Resolve conflicts and remove obsolete files.
Sponsored by: registrar.no
This commit is contained in:
parent
fb7dd0a77c
commit
cf2b5f3b6d
@ -76,14 +76,6 @@ OpenSSH contains no GPL code.
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
2)
|
||||
The 32-bit CRC implementation in crc32.c is due to Gary S. Brown.
|
||||
Comments in the file indicate it may be used for any purpose without
|
||||
restrictions:
|
||||
|
||||
* COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or
|
||||
* code or tables extracted from it, as desired without restriction.
|
||||
|
||||
3)
|
||||
The 32-bit CRC compensation attack detector in deattack.c was
|
||||
contributed by CORE SDI S.A. under a BSD-style license.
|
||||
|
||||
@ -104,7 +96,7 @@ OpenSSH contains no GPL code.
|
||||
* Ariel Futoransky <futo@core-sdi.com>
|
||||
* <http://www.core-sdi.com>
|
||||
|
||||
4)
|
||||
3)
|
||||
ssh-keygen was contributed by David Mazieres under a BSD-style
|
||||
license.
|
||||
|
||||
@ -114,7 +106,7 @@ OpenSSH contains no GPL code.
|
||||
* permitted provided that due credit is given to the author and the
|
||||
* OpenBSD project by leaving this copyright notice intact.
|
||||
|
||||
5)
|
||||
4)
|
||||
The Rijndael implementation by Vincent Rijmen, Antoon Bosselaers
|
||||
and Paulo Barreto is in the public domain and distributed
|
||||
with the following license:
|
||||
@ -141,12 +133,10 @@ OpenSSH contains no GPL code.
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
6)
|
||||
One component of the ssh source code is under a 4-clause BSD license,
|
||||
5)
|
||||
One component of the ssh source code is under a 3-clause BSD license,
|
||||
held by the University of California, since we pulled these parts from
|
||||
original Berkeley code. The Regents of the University of California
|
||||
have declared that term 3 is no longer enforceable on their source code,
|
||||
but we retain that license as is.
|
||||
original Berkeley code.
|
||||
|
||||
* Copyright (c) 1983, 1990, 1992, 1993, 1995
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
@ -159,11 +149,7 @@ OpenSSH contains no GPL code.
|
||||
* 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.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
@ -179,7 +165,7 @@ OpenSSH contains no GPL code.
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
|
||||
7)
|
||||
6)
|
||||
Remaining components of the software are provided under a standard
|
||||
2-term BSD licence with the following names as copyright holders:
|
||||
|
||||
@ -192,6 +178,31 @@ OpenSSH contains no GPL code.
|
||||
Kevin Steves
|
||||
Daniel Kouril
|
||||
Per Allansson
|
||||
Wesley Griffin
|
||||
Per Allansson
|
||||
Nils Nordman
|
||||
Simon Wilkinson
|
||||
|
||||
Portable OpenSSH additionally includes code from the following copyright
|
||||
holders, also under the 2-term BSD license:
|
||||
|
||||
Ben Lindstrom
|
||||
Tim Rice
|
||||
Andre Lucas
|
||||
Chris Adams
|
||||
Corinna Vinschen
|
||||
Cray Inc.
|
||||
Denis Parker
|
||||
Gert Doering
|
||||
Jakob Schlyter
|
||||
Jason Downs
|
||||
Juha Yrjölä
|
||||
Michael Stone
|
||||
Networks Associates Technology, Inc.
|
||||
Solar Designer
|
||||
Todd C. Miller
|
||||
Wayne Schroeder
|
||||
William Jones
|
||||
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -212,3 +223,110 @@ OpenSSH contains no GPL code.
|
||||
* 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.
|
||||
|
||||
8) Portable OpenSSH contains the following additional licenses:
|
||||
|
||||
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
|
||||
* 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
|
||||
* notice remains intact on all source code distributions
|
||||
|
||||
c) Compatibility code (openbsd-compat)
|
||||
|
||||
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
|
||||
copyright holders:
|
||||
|
||||
Todd C. Miller
|
||||
Theo de Raadt
|
||||
Damien Miller
|
||||
Eric P. Allman
|
||||
The Regents of the University of California
|
||||
|
||||
* 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.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
|
||||
|
||||
Some code is licensed under an ISC-style license, to the following
|
||||
copyright holders:
|
||||
|
||||
Internet Software Consortium.
|
||||
Todd C. Miller
|
||||
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND TODD C. MILLER DISCLAIMS ALL
|
||||
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL TODD C. MILLER BE LIABLE
|
||||
* FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* 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
|
||||
copyright holders:
|
||||
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a *
|
||||
* copy of this software and associated documentation files (the *
|
||||
* "Software"), to deal in the Software without restriction, including *
|
||||
* without limitation the rights to use, copy, modify, merge, publish, *
|
||||
* distribute, distribute with modifications, sublicense, and/or sell *
|
||||
* copies of the Software, and to permit persons to whom the Software is *
|
||||
* furnished to do so, subject to the following conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included *
|
||||
* in all copies or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS *
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF *
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. *
|
||||
* IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
|
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
|
||||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR *
|
||||
* THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
* *
|
||||
* Except as contained in this notice, the name(s) of the above copyright *
|
||||
* holders shall not be used in advertising or otherwise to promote the *
|
||||
* sale, use or other dealings in this Software without prior written *
|
||||
* authorization. *
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
------
|
||||
$OpenBSD: LICENCE,v 1.17 2003/08/22 20:55:06 markus Exp $
|
||||
|
@ -1,6 +1,30 @@
|
||||
/* $Id: acconfig.h,v 1.149 2003/03/10 00:38:10 djm Exp $ */
|
||||
/* $Id: acconfig.h,v 1.166 2003/09/16 01:52:19 dtucker Exp $ */
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1999-2003 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.
|
||||
*/
|
||||
|
||||
#ifndef _CONFIG_H
|
||||
#define _CONFIG_H
|
||||
|
||||
@ -9,9 +33,19 @@
|
||||
|
||||
@TOP@
|
||||
|
||||
/* Define if your platform breaks doing a seteuid before a setuid */
|
||||
#undef SETEUID_BREAKS_SETUID
|
||||
|
||||
/* Define if your setreuid() is broken */
|
||||
#undef BROKEN_SETREUID
|
||||
|
||||
/* Define if your setregid() is broken */
|
||||
#undef BROKEN_SETREGID
|
||||
|
||||
/* Define to a Set Process Title type if your system is */
|
||||
/* supported by bsd-setproctitle.c */
|
||||
#undef SPT_TYPE
|
||||
#undef SPT_PADCHAR
|
||||
|
||||
/* setgroups() NOOP allowed */
|
||||
#undef SETGROUPS_NOOP
|
||||
@ -83,6 +117,9 @@
|
||||
/* Define if you want to enable AIX4's authenticate function */
|
||||
#undef WITH_AIXAUTHENTICATE
|
||||
|
||||
/* Define if your AIX loginfailed() function takes 4 arguments (AIX >= 5.2) */
|
||||
#undef AIX_LOGINFAILED_4ARG
|
||||
|
||||
/* Define if you have/want arrays (cluster-wide session managment, not C arrays) */
|
||||
#undef WITH_IRIX_ARRAY
|
||||
|
||||
@ -202,18 +239,15 @@
|
||||
/* Define if compiler implements __func__ */
|
||||
#undef HAVE___func__
|
||||
|
||||
/* Define this is you want GSSAPI support in the version 2 protocol */
|
||||
#undef GSSAPI
|
||||
|
||||
/* Define if you want Kerberos 5 support */
|
||||
#undef KRB5
|
||||
|
||||
/* Define this if you are using the Heimdal version of Kerberos V5 */
|
||||
#undef HEIMDAL
|
||||
|
||||
/* Define if you want Kerberos 4 support */
|
||||
#undef KRB4
|
||||
|
||||
/* Define if you want AFS support */
|
||||
#undef AFS
|
||||
|
||||
/* Define if you want S/Key support */
|
||||
#undef SKEY
|
||||
|
||||
@ -299,9 +333,6 @@
|
||||
/* Specify location of ssh.pid */
|
||||
#undef _PATH_SSH_PIDDIR
|
||||
|
||||
/* Use IPv4 for connection by default, IPv6 can still if explicity asked */
|
||||
#undef IPV4_DEFAULT
|
||||
|
||||
/* getaddrinfo is broken (if present) */
|
||||
#undef BROKEN_GETADDRINFO
|
||||
|
||||
@ -332,6 +363,9 @@
|
||||
/* Define in your struct dirent expects you to allocate extra space for d_name */
|
||||
#undef BROKEN_ONE_BYTE_DIRENT_D_NAME
|
||||
|
||||
/* Define if your system has /etc/default/login */
|
||||
#undef HAVE_ETC_DEFAULT_LOGIN
|
||||
|
||||
/* Define if your getopt(3) defines and uses optreset */
|
||||
#undef HAVE_GETOPT_OPTRESET
|
||||
|
||||
@ -371,15 +405,28 @@
|
||||
/* Silly mkstemp() */
|
||||
#undef HAVE_STRICT_MKSTEMP
|
||||
|
||||
/* Setproctitle emulation */
|
||||
#undef SETPROCTITLE_STRATEGY
|
||||
#undef SETPROCTITLE_PS_PADDING
|
||||
|
||||
/* Some systems put this outside of libc */
|
||||
#undef HAVE_NANOSLEEP
|
||||
|
||||
/* Pushing STREAMS modules incorrectly acquires a controlling TTY */
|
||||
#undef STREAMS_PUSH_ACQUIRES_CTTY
|
||||
/* Define if sshd somehow reacquires a controlling TTY after setsid() */
|
||||
#undef SSHD_ACQUIRES_CTTY
|
||||
|
||||
/* Define if cmsg_type is not passed correctly */
|
||||
#undef BROKEN_CMSG_TYPE
|
||||
|
||||
/* Strings used in /etc/passwd to denote locked account */
|
||||
#undef LOCKED_PASSWD_STRING
|
||||
#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
|
||||
|
||||
@BOTTOM@
|
||||
|
||||
|
@ -1,368 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1999 Dug Song. 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.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: auth-krb4.c,v 1.29 2003/02/21 10:34:48 mpech Exp $");
|
||||
|
||||
#include "ssh.h"
|
||||
#include "ssh1.h"
|
||||
#include "packet.h"
|
||||
#include "xmalloc.h"
|
||||
#include "log.h"
|
||||
#include "servconf.h"
|
||||
#include "uidswap.h"
|
||||
#include "auth.h"
|
||||
|
||||
#ifdef AFS
|
||||
#include "radix.h"
|
||||
#endif
|
||||
|
||||
#ifdef KRB4
|
||||
extern ServerOptions options;
|
||||
|
||||
static int
|
||||
krb4_init(void *context)
|
||||
{
|
||||
static int cleanup_registered = 0;
|
||||
Authctxt *authctxt = (Authctxt *)context;
|
||||
const char *tkt_root = TKT_ROOT;
|
||||
struct stat st;
|
||||
int fd;
|
||||
|
||||
if (!authctxt->krb4_ticket_file) {
|
||||
/* Set unique ticket string manually since we're still root. */
|
||||
authctxt->krb4_ticket_file = xmalloc(MAXPATHLEN);
|
||||
#ifdef AFS
|
||||
if (lstat("/ticket", &st) != -1)
|
||||
tkt_root = "/ticket/";
|
||||
#endif /* AFS */
|
||||
snprintf(authctxt->krb4_ticket_file, MAXPATHLEN, "%s%u_%ld",
|
||||
tkt_root, authctxt->pw->pw_uid, (long)getpid());
|
||||
krb_set_tkt_string(authctxt->krb4_ticket_file);
|
||||
}
|
||||
/* Register ticket cleanup in case of fatal error. */
|
||||
if (!cleanup_registered) {
|
||||
fatal_add_cleanup(krb4_cleanup_proc, authctxt);
|
||||
cleanup_registered = 1;
|
||||
}
|
||||
/* Try to create our ticket file. */
|
||||
if ((fd = mkstemp(authctxt->krb4_ticket_file)) != -1) {
|
||||
close(fd);
|
||||
return (1);
|
||||
}
|
||||
/* Ticket file exists - make sure user owns it (just passed ticket). */
|
||||
if (lstat(authctxt->krb4_ticket_file, &st) != -1) {
|
||||
if (st.st_mode == (S_IFREG | S_IRUSR | S_IWUSR) &&
|
||||
st.st_uid == authctxt->pw->pw_uid)
|
||||
return (1);
|
||||
}
|
||||
/* Failure - cancel cleanup function, leaving ticket for inspection. */
|
||||
log("WARNING: bad ticket file %s", authctxt->krb4_ticket_file);
|
||||
|
||||
fatal_remove_cleanup(krb4_cleanup_proc, authctxt);
|
||||
cleanup_registered = 0;
|
||||
|
||||
xfree(authctxt->krb4_ticket_file);
|
||||
authctxt->krb4_ticket_file = NULL;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* try krb4 authentication,
|
||||
* return 1 on success, 0 on failure, -1 if krb4 is not available
|
||||
*/
|
||||
int
|
||||
auth_krb4_password(Authctxt *authctxt, const char *password)
|
||||
{
|
||||
AUTH_DAT adata;
|
||||
KTEXT_ST tkt;
|
||||
struct hostent *hp;
|
||||
struct passwd *pw;
|
||||
char localhost[MAXHOSTNAMELEN], phost[INST_SZ], realm[REALM_SZ];
|
||||
u_int32_t faddr;
|
||||
int r;
|
||||
|
||||
if ((pw = authctxt->pw) == NULL)
|
||||
return (0);
|
||||
|
||||
/*
|
||||
* Try Kerberos password authentication only for non-root
|
||||
* users and only if Kerberos is installed.
|
||||
*/
|
||||
if (pw->pw_uid != 0 && krb_get_lrealm(realm, 1) == KSUCCESS) {
|
||||
/* Set up our ticket file. */
|
||||
if (!krb4_init(authctxt)) {
|
||||
log("Couldn't initialize Kerberos ticket file for %s!",
|
||||
pw->pw_name);
|
||||
goto failure;
|
||||
}
|
||||
/* Try to get TGT using our password. */
|
||||
r = krb_get_pw_in_tkt((char *) pw->pw_name, "", realm,
|
||||
"krbtgt", realm, DEFAULT_TKT_LIFE, (char *)password);
|
||||
if (r != INTK_OK) {
|
||||
debug("Kerberos v4 password authentication for %s "
|
||||
"failed: %s", pw->pw_name, krb_err_txt[r]);
|
||||
goto failure;
|
||||
}
|
||||
/* Successful authentication. */
|
||||
chown(tkt_string(), pw->pw_uid, pw->pw_gid);
|
||||
|
||||
/*
|
||||
* Now that we have a TGT, try to get a local
|
||||
* "rcmd" ticket to ensure that we are not talking
|
||||
* to a bogus Kerberos server.
|
||||
*/
|
||||
gethostname(localhost, sizeof(localhost));
|
||||
strlcpy(phost, (char *)krb_get_phost(localhost),
|
||||
sizeof(phost));
|
||||
r = krb_mk_req(&tkt, KRB4_SERVICE_NAME, phost, realm, 33);
|
||||
|
||||
if (r == KSUCCESS) {
|
||||
if ((hp = gethostbyname(localhost)) == NULL) {
|
||||
log("Couldn't get local host address!");
|
||||
goto failure;
|
||||
}
|
||||
memmove((void *)&faddr, (void *)hp->h_addr,
|
||||
sizeof(faddr));
|
||||
|
||||
/* Verify our "rcmd" ticket. */
|
||||
r = krb_rd_req(&tkt, KRB4_SERVICE_NAME, phost,
|
||||
faddr, &adata, "");
|
||||
if (r == RD_AP_UNDEC) {
|
||||
/*
|
||||
* Probably didn't have a srvtab on
|
||||
* localhost. Disallow login.
|
||||
*/
|
||||
log("Kerberos v4 TGT for %s unverifiable, "
|
||||
"no srvtab installed? krb_rd_req: %s",
|
||||
pw->pw_name, krb_err_txt[r]);
|
||||
goto failure;
|
||||
} else if (r != KSUCCESS) {
|
||||
log("Kerberos v4 %s ticket unverifiable: %s",
|
||||
KRB4_SERVICE_NAME, krb_err_txt[r]);
|
||||
goto failure;
|
||||
}
|
||||
} else if (r == KDC_PR_UNKNOWN) {
|
||||
/*
|
||||
* Disallow login if no rcmd service exists, and
|
||||
* log the error.
|
||||
*/
|
||||
log("Kerberos v4 TGT for %s unverifiable: %s; %s.%s "
|
||||
"not registered, or srvtab is wrong?", pw->pw_name,
|
||||
krb_err_txt[r], KRB4_SERVICE_NAME, phost);
|
||||
goto failure;
|
||||
} else {
|
||||
/*
|
||||
* TGT is bad, forget it. Possibly spoofed!
|
||||
*/
|
||||
debug("WARNING: Kerberos v4 TGT possibly spoofed "
|
||||
"for %s: %s", pw->pw_name, krb_err_txt[r]);
|
||||
goto failure;
|
||||
}
|
||||
/* Authentication succeeded. */
|
||||
return (1);
|
||||
} else
|
||||
/* Logging in as root or no local Kerberos realm. */
|
||||
debug("Unable to authenticate to Kerberos.");
|
||||
|
||||
failure:
|
||||
krb4_cleanup_proc(authctxt);
|
||||
|
||||
if (!options.kerberos_or_local_passwd)
|
||||
return (0);
|
||||
|
||||
/* Fall back to ordinary passwd authentication. */
|
||||
return (-1);
|
||||
}
|
||||
|
||||
void
|
||||
krb4_cleanup_proc(void *context)
|
||||
{
|
||||
Authctxt *authctxt = (Authctxt *)context;
|
||||
debug("krb4_cleanup_proc called");
|
||||
if (authctxt->krb4_ticket_file) {
|
||||
(void) dest_tkt();
|
||||
xfree(authctxt->krb4_ticket_file);
|
||||
authctxt->krb4_ticket_file = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
auth_krb4(Authctxt *authctxt, KTEXT auth, char **client, KTEXT reply)
|
||||
{
|
||||
AUTH_DAT adat = {0};
|
||||
Key_schedule schedule;
|
||||
struct sockaddr_in local, foreign;
|
||||
char instance[INST_SZ];
|
||||
socklen_t slen;
|
||||
u_int cksum;
|
||||
int r, s;
|
||||
|
||||
s = packet_get_connection_in();
|
||||
|
||||
slen = sizeof(local);
|
||||
memset(&local, 0, sizeof(local));
|
||||
if (getsockname(s, (struct sockaddr *) & local, &slen) < 0)
|
||||
debug("getsockname failed: %.100s", strerror(errno));
|
||||
slen = sizeof(foreign);
|
||||
memset(&foreign, 0, sizeof(foreign));
|
||||
if (getpeername(s, (struct sockaddr *) & foreign, &slen) < 0) {
|
||||
debug("getpeername failed: %.100s", strerror(errno));
|
||||
fatal_cleanup();
|
||||
}
|
||||
instance[0] = '*';
|
||||
instance[1] = 0;
|
||||
|
||||
/* Get the encrypted request, challenge, and session key. */
|
||||
if ((r = krb_rd_req(auth, KRB4_SERVICE_NAME, instance,
|
||||
0, &adat, ""))) {
|
||||
debug("Kerberos v4 krb_rd_req: %.100s", krb_err_txt[r]);
|
||||
return (0);
|
||||
}
|
||||
des_key_sched((des_cblock *) adat.session, schedule);
|
||||
|
||||
*client = xmalloc(MAX_K_NAME_SZ);
|
||||
(void) snprintf(*client, MAX_K_NAME_SZ, "%s%s%s@%s", adat.pname,
|
||||
*adat.pinst ? "." : "", adat.pinst, adat.prealm);
|
||||
|
||||
/* Check ~/.klogin authorization now. */
|
||||
if (kuserok(&adat, authctxt->user) != KSUCCESS) {
|
||||
log("Kerberos v4 .klogin authorization failed for %s to "
|
||||
"account %s", *client, authctxt->user);
|
||||
xfree(*client);
|
||||
*client = NULL;
|
||||
return (0);
|
||||
}
|
||||
/* Increment the checksum, and return it encrypted with the
|
||||
session key. */
|
||||
cksum = adat.checksum + 1;
|
||||
cksum = htonl(cksum);
|
||||
|
||||
/* If we can't successfully encrypt the checksum, we send back an
|
||||
empty message, admitting our failure. */
|
||||
if ((r = krb_mk_priv((u_char *) & cksum, reply->dat, sizeof(cksum) + 1,
|
||||
schedule, &adat.session, &local, &foreign)) < 0) {
|
||||
debug("Kerberos v4 mk_priv: (%d) %s", r, krb_err_txt[r]);
|
||||
reply->dat[0] = 0;
|
||||
reply->length = 0;
|
||||
} else
|
||||
reply->length = r;
|
||||
|
||||
/* Clear session key. */
|
||||
memset(&adat.session, 0, sizeof(adat.session));
|
||||
return (1);
|
||||
}
|
||||
#endif /* KRB4 */
|
||||
|
||||
#ifdef AFS
|
||||
int
|
||||
auth_krb4_tgt(Authctxt *authctxt, const char *string)
|
||||
{
|
||||
CREDENTIALS creds;
|
||||
struct passwd *pw;
|
||||
|
||||
if ((pw = authctxt->pw) == NULL)
|
||||
goto failure;
|
||||
|
||||
temporarily_use_uid(pw);
|
||||
|
||||
if (!radix_to_creds(string, &creds)) {
|
||||
log("Protocol error decoding Kerberos v4 TGT");
|
||||
goto failure;
|
||||
}
|
||||
if (strncmp(creds.service, "", 1) == 0) /* backward compatibility */
|
||||
strlcpy(creds.service, "krbtgt", sizeof creds.service);
|
||||
|
||||
if (strcmp(creds.service, "krbtgt")) {
|
||||
log("Kerberos v4 TGT (%s%s%s@%s) rejected for %s",
|
||||
creds.pname, creds.pinst[0] ? "." : "", creds.pinst,
|
||||
creds.realm, pw->pw_name);
|
||||
goto failure;
|
||||
}
|
||||
if (!krb4_init(authctxt))
|
||||
goto failure;
|
||||
|
||||
if (in_tkt(creds.pname, creds.pinst) != KSUCCESS)
|
||||
goto failure;
|
||||
|
||||
if (save_credentials(creds.service, creds.instance, creds.realm,
|
||||
creds.session, creds.lifetime, creds.kvno, &creds.ticket_st,
|
||||
creds.issue_date) != KSUCCESS) {
|
||||
debug("Kerberos v4 TGT refused: couldn't save credentials");
|
||||
goto failure;
|
||||
}
|
||||
/* Successful authentication, passed all checks. */
|
||||
chown(tkt_string(), pw->pw_uid, pw->pw_gid);
|
||||
|
||||
debug("Kerberos v4 TGT accepted (%s%s%s@%s)",
|
||||
creds.pname, creds.pinst[0] ? "." : "", creds.pinst, creds.realm);
|
||||
memset(&creds, 0, sizeof(creds));
|
||||
|
||||
restore_uid();
|
||||
|
||||
return (1);
|
||||
|
||||
failure:
|
||||
krb4_cleanup_proc(authctxt);
|
||||
memset(&creds, 0, sizeof(creds));
|
||||
restore_uid();
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
auth_afs_token(Authctxt *authctxt, const char *token_string)
|
||||
{
|
||||
CREDENTIALS creds;
|
||||
struct passwd *pw;
|
||||
uid_t uid;
|
||||
|
||||
if ((pw = authctxt->pw) == NULL)
|
||||
return (0);
|
||||
|
||||
if (!radix_to_creds(token_string, &creds)) {
|
||||
log("Protocol error decoding AFS token");
|
||||
return (0);
|
||||
}
|
||||
if (strncmp(creds.service, "", 1) == 0) /* backward compatibility */
|
||||
strlcpy(creds.service, "afs", sizeof creds.service);
|
||||
|
||||
if (strncmp(creds.pname, "AFS ID ", 7) == 0)
|
||||
uid = atoi(creds.pname + 7);
|
||||
else
|
||||
uid = pw->pw_uid;
|
||||
|
||||
if (kafs_settoken(creds.realm, uid, &creds)) {
|
||||
log("AFS token (%s@%s) rejected for %s",
|
||||
creds.pname, creds.realm, pw->pw_name);
|
||||
memset(&creds, 0, sizeof(creds));
|
||||
return (0);
|
||||
}
|
||||
debug("AFS token accepted (%s@%s)", creds.pname, creds.realm);
|
||||
memset(&creds, 0, sizeof(creds));
|
||||
|
||||
return (1);
|
||||
}
|
||||
#endif /* AFS */
|
@ -28,7 +28,7 @@
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: auth-krb5.c,v 1.10 2002/11/21 23:03:51 deraadt Exp $");
|
||||
RCSID("$OpenBSD: auth-krb5.c,v 1.12 2003/08/28 12:54:34 markus Exp $");
|
||||
RCSID("$FreeBSD$");
|
||||
|
||||
#include "ssh.h"
|
||||
@ -41,10 +41,8 @@ RCSID("$FreeBSD$");
|
||||
#include "auth.h"
|
||||
|
||||
#ifdef KRB5
|
||||
|
||||
#include <krb5.h>
|
||||
#ifndef HEIMDAL
|
||||
#define krb5_get_err_text(context,code) error_message(code)
|
||||
#endif /* !HEIMDAL */
|
||||
|
||||
extern ServerOptions options;
|
||||
|
||||
@ -68,193 +66,6 @@ krb5_init(void *context)
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Try krb5 authentication. server_user is passed for logging purposes
|
||||
* only, in auth is received ticket, in client is returned principal
|
||||
* from the ticket
|
||||
*/
|
||||
int
|
||||
auth_krb5(Authctxt *authctxt, krb5_data *auth, char **client, krb5_data *reply)
|
||||
{
|
||||
krb5_error_code problem;
|
||||
krb5_principal server;
|
||||
krb5_ticket *ticket;
|
||||
int fd, ret;
|
||||
|
||||
ret = 0;
|
||||
server = NULL;
|
||||
ticket = NULL;
|
||||
reply->length = 0;
|
||||
|
||||
problem = krb5_init(authctxt);
|
||||
if (problem)
|
||||
goto err;
|
||||
|
||||
problem = krb5_auth_con_init(authctxt->krb5_ctx,
|
||||
&authctxt->krb5_auth_ctx);
|
||||
if (problem)
|
||||
goto err;
|
||||
|
||||
fd = packet_get_connection_in();
|
||||
#ifdef HEIMDAL
|
||||
problem = krb5_auth_con_setaddrs_from_fd(authctxt->krb5_ctx,
|
||||
authctxt->krb5_auth_ctx, &fd);
|
||||
#else
|
||||
problem = krb5_auth_con_genaddrs(authctxt->krb5_ctx,
|
||||
authctxt->krb5_auth_ctx,fd,
|
||||
KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR |
|
||||
KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR);
|
||||
#endif
|
||||
if (problem)
|
||||
goto err;
|
||||
|
||||
problem = krb5_sname_to_principal(authctxt->krb5_ctx, NULL, NULL,
|
||||
KRB5_NT_SRV_HST, &server);
|
||||
if (problem)
|
||||
goto err;
|
||||
|
||||
problem = krb5_rd_req(authctxt->krb5_ctx, &authctxt->krb5_auth_ctx,
|
||||
auth, server, NULL, NULL, &ticket);
|
||||
if (problem)
|
||||
goto err;
|
||||
|
||||
#ifdef HEIMDAL
|
||||
problem = krb5_copy_principal(authctxt->krb5_ctx, ticket->client,
|
||||
&authctxt->krb5_user);
|
||||
#else
|
||||
problem = krb5_copy_principal(authctxt->krb5_ctx,
|
||||
ticket->enc_part2->client,
|
||||
&authctxt->krb5_user);
|
||||
#endif
|
||||
if (problem)
|
||||
goto err;
|
||||
|
||||
/* if client wants mutual auth */
|
||||
problem = krb5_mk_rep(authctxt->krb5_ctx, authctxt->krb5_auth_ctx,
|
||||
reply);
|
||||
if (problem)
|
||||
goto err;
|
||||
|
||||
/* Check .k5login authorization now. */
|
||||
if (!krb5_kuserok(authctxt->krb5_ctx, authctxt->krb5_user,
|
||||
authctxt->pw->pw_name))
|
||||
goto err;
|
||||
|
||||
if (client)
|
||||
krb5_unparse_name(authctxt->krb5_ctx, authctxt->krb5_user,
|
||||
client);
|
||||
|
||||
ret = 1;
|
||||
err:
|
||||
if (server)
|
||||
krb5_free_principal(authctxt->krb5_ctx, server);
|
||||
if (ticket)
|
||||
krb5_free_ticket(authctxt->krb5_ctx, ticket);
|
||||
if (!ret && reply->length) {
|
||||
xfree(reply->data);
|
||||
memset(reply, 0, sizeof(*reply));
|
||||
}
|
||||
|
||||
if (problem) {
|
||||
if (authctxt->krb5_ctx != NULL)
|
||||
debug("Kerberos v5 authentication failed: %s",
|
||||
krb5_get_err_text(authctxt->krb5_ctx, problem));
|
||||
else
|
||||
debug("Kerberos v5 authentication failed: %d",
|
||||
problem);
|
||||
}
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int
|
||||
auth_krb5_tgt(Authctxt *authctxt, krb5_data *tgt)
|
||||
{
|
||||
krb5_error_code problem;
|
||||
krb5_ccache ccache = NULL;
|
||||
char *pname;
|
||||
krb5_creds **creds;
|
||||
|
||||
if (authctxt->pw == NULL || authctxt->krb5_user == NULL)
|
||||
return (0);
|
||||
|
||||
temporarily_use_uid(authctxt->pw);
|
||||
|
||||
#ifdef HEIMDAL
|
||||
problem = krb5_cc_gen_new(authctxt->krb5_ctx, &krb5_fcc_ops, &ccache);
|
||||
#else
|
||||
{
|
||||
char ccname[40];
|
||||
int tmpfd;
|
||||
|
||||
snprintf(ccname,sizeof(ccname),"FILE:/tmp/krb5cc_%d_XXXXXX",geteuid());
|
||||
|
||||
if ((tmpfd = mkstemp(ccname+strlen("FILE:")))==-1) {
|
||||
log("mkstemp(): %.100s", strerror(errno));
|
||||
problem = errno;
|
||||
goto fail;
|
||||
}
|
||||
if (fchmod(tmpfd,S_IRUSR | S_IWUSR) == -1) {
|
||||
log("fchmod(): %.100s", strerror(errno));
|
||||
close(tmpfd);
|
||||
problem = errno;
|
||||
goto fail;
|
||||
}
|
||||
close(tmpfd);
|
||||
problem = krb5_cc_resolve(authctxt->krb5_ctx, ccname, &ccache);
|
||||
}
|
||||
#endif
|
||||
if (problem)
|
||||
goto fail;
|
||||
|
||||
problem = krb5_cc_initialize(authctxt->krb5_ctx, ccache,
|
||||
authctxt->krb5_user);
|
||||
if (problem)
|
||||
goto fail;
|
||||
|
||||
#ifdef HEIMDAL
|
||||
problem = krb5_rd_cred2(authctxt->krb5_ctx, authctxt->krb5_auth_ctx,
|
||||
ccache, tgt);
|
||||
if (problem)
|
||||
goto fail;
|
||||
#else
|
||||
problem = krb5_rd_cred(authctxt->krb5_ctx, authctxt->krb5_auth_ctx,
|
||||
tgt, &creds, NULL);
|
||||
if (problem)
|
||||
goto fail;
|
||||
problem = krb5_cc_store_cred(authctxt->krb5_ctx, ccache, *creds);
|
||||
if (problem)
|
||||
goto fail;
|
||||
#endif
|
||||
|
||||
authctxt->krb5_fwd_ccache = ccache;
|
||||
ccache = NULL;
|
||||
|
||||
authctxt->krb5_ticket_file = (char *)krb5_cc_get_name(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache);
|
||||
|
||||
problem = krb5_unparse_name(authctxt->krb5_ctx, authctxt->krb5_user,
|
||||
&pname);
|
||||
if (problem)
|
||||
goto fail;
|
||||
|
||||
debug("Kerberos v5 TGT accepted (%s)", pname);
|
||||
|
||||
restore_uid();
|
||||
|
||||
return (1);
|
||||
|
||||
fail:
|
||||
if (problem)
|
||||
debug("Kerberos v5 TGT passing failed: %s",
|
||||
krb5_get_err_text(authctxt->krb5_ctx, problem));
|
||||
if (ccache)
|
||||
krb5_cc_destroy(authctxt->krb5_ctx, ccache);
|
||||
|
||||
restore_uid();
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
auth_krb5_password(Authctxt *authctxt, const char *password)
|
||||
{
|
||||
@ -265,6 +76,7 @@ auth_krb5_password(Authctxt *authctxt, const char *password)
|
||||
int tmpfd;
|
||||
#endif
|
||||
krb5_error_code problem;
|
||||
krb5_ccache ccache = NULL;
|
||||
|
||||
if (authctxt->pw == NULL)
|
||||
return (0);
|
||||
@ -281,23 +93,35 @@ auth_krb5_password(Authctxt *authctxt, const char *password)
|
||||
goto out;
|
||||
|
||||
#ifdef HEIMDAL
|
||||
problem = krb5_cc_gen_new(authctxt->krb5_ctx, &krb5_mcc_ops,
|
||||
&authctxt->krb5_fwd_ccache);
|
||||
problem = krb5_cc_gen_new(authctxt->krb5_ctx, &krb5_mcc_ops, &ccache);
|
||||
if (problem)
|
||||
goto out;
|
||||
|
||||
problem = krb5_cc_initialize(authctxt->krb5_ctx,
|
||||
authctxt->krb5_fwd_ccache, authctxt->krb5_user);
|
||||
problem = krb5_cc_initialize(authctxt->krb5_ctx, ccache,
|
||||
authctxt->krb5_user);
|
||||
if (problem)
|
||||
goto out;
|
||||
|
||||
restore_uid();
|
||||
|
||||
problem = krb5_verify_user(authctxt->krb5_ctx, authctxt->krb5_user,
|
||||
authctxt->krb5_fwd_ccache, password, 1, NULL);
|
||||
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)
|
||||
goto out;
|
||||
|
||||
problem = krb5_cc_copy_cache(authctxt->krb5_ctx, ccache,
|
||||
authctxt->krb5_fwd_ccache);
|
||||
krb5_cc_destroy(authctxt->krb5_ctx, ccache);
|
||||
ccache = NULL;
|
||||
if (problem)
|
||||
goto out;
|
||||
|
||||
#else
|
||||
problem = krb5_get_init_creds_password(authctxt->krb5_ctx, &creds,
|
||||
@ -327,13 +151,13 @@ auth_krb5_password(Authctxt *authctxt, const char *password)
|
||||
snprintf(ccname,sizeof(ccname),"FILE:/tmp/krb5cc_%d_XXXXXX",geteuid());
|
||||
|
||||
if ((tmpfd = mkstemp(ccname+strlen("FILE:")))==-1) {
|
||||
log("mkstemp(): %.100s", strerror(errno));
|
||||
logit("mkstemp(): %.100s", strerror(errno));
|
||||
problem = errno;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (fchmod(tmpfd,S_IRUSR | S_IWUSR) == -1) {
|
||||
log("fchmod(): %.100s", strerror(errno));
|
||||
logit("fchmod(): %.100s", strerror(errno));
|
||||
close(tmpfd);
|
||||
problem = errno;
|
||||
goto out;
|
||||
@ -361,6 +185,9 @@ auth_krb5_password(Authctxt *authctxt, const char *password)
|
||||
restore_uid();
|
||||
|
||||
if (problem) {
|
||||
if (ccache)
|
||||
krb5_cc_destroy(authctxt->krb5_ctx, ccache);
|
||||
|
||||
if (authctxt->krb5_ctx != NULL && problem!=-1)
|
||||
debug("Kerberos password authentication failed: %s",
|
||||
krb5_get_err_text(authctxt->krb5_ctx, problem));
|
||||
@ -392,11 +219,6 @@ krb5_cleanup_proc(void *context)
|
||||
krb5_free_principal(authctxt->krb5_ctx, authctxt->krb5_user);
|
||||
authctxt->krb5_user = NULL;
|
||||
}
|
||||
if (authctxt->krb5_auth_ctx) {
|
||||
krb5_auth_con_free(authctxt->krb5_ctx,
|
||||
authctxt->krb5_auth_ctx);
|
||||
authctxt->krb5_auth_ctx = NULL;
|
||||
}
|
||||
if (authctxt->krb5_ctx) {
|
||||
krb5_free_context(authctxt->krb5_ctx);
|
||||
authctxt->krb5_ctx = NULL;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,4 @@
|
||||
/* $Id: auth-pam.h,v 1.16 2002/07/23 00:44:07 stevesk Exp $ */
|
||||
/* $Id: auth-pam.h,v 1.21 2003/09/02 13:18:53 djm Exp $ */
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/*
|
||||
@ -32,19 +32,17 @@
|
||||
# define SSHD_PAM_SERVICE __progname
|
||||
#endif
|
||||
|
||||
void start_pam(const char *user);
|
||||
void start_pam(const char *);
|
||||
void finish_pam(void);
|
||||
int auth_pam_password(Authctxt *authctxt, const char *password);
|
||||
char **fetch_pam_environment(void);
|
||||
void free_pam_environment(char **env);
|
||||
int do_pam_authenticate(int flags);
|
||||
int do_pam_account(const char *username, const char *remote_user);
|
||||
void do_pam_session(const char *username, const char *ttyname);
|
||||
void do_pam_setcred(int init);
|
||||
void print_pam_messages(void);
|
||||
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);
|
||||
void do_pam_set_conv(struct pam_conv *);
|
||||
void message_cat(char **p, const char *a);
|
||||
int do_pam_putenv(char *, char *);
|
||||
void print_pam_messages(void);
|
||||
char ** fetch_pam_environment(void);
|
||||
void free_pam_environment(char **);
|
||||
|
||||
#endif /* USE_PAM */
|
||||
|
@ -36,62 +36,20 @@
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: auth-passwd.c,v 1.27 2002/05/24 16:45:16 stevesk Exp $");
|
||||
RCSID("$OpenBSD: auth-passwd.c,v 1.29 2003/08/26 09:58:43 markus Exp $");
|
||||
RCSID("$FreeBSD$");
|
||||
|
||||
#include "packet.h"
|
||||
#include "log.h"
|
||||
#include "servconf.h"
|
||||
#include "auth.h"
|
||||
|
||||
/*
|
||||
* Do not try to use PAM for password authentication, as it is
|
||||
* already (and far better) supported by the challenge/response
|
||||
* authentication mechanism.
|
||||
*/
|
||||
#undef USE_PAM
|
||||
|
||||
#if !defined(USE_PAM) && !defined(HAVE_OSF_SIA)
|
||||
/* Don't need any of these headers for the PAM or SIA cases */
|
||||
# ifdef HAVE_CRYPT_H
|
||||
# include <crypt.h>
|
||||
# endif
|
||||
# ifdef WITH_AIXAUTHENTICATE
|
||||
# include <login.h>
|
||||
# endif
|
||||
# ifdef __hpux
|
||||
# include <hpsecurity.h>
|
||||
# include <prot.h>
|
||||
# endif
|
||||
# ifdef HAVE_SECUREWARE
|
||||
# include <sys/security.h>
|
||||
# include <sys/audit.h>
|
||||
# include <prot.h>
|
||||
# endif /* HAVE_SECUREWARE */
|
||||
# if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW)
|
||||
# include <shadow.h>
|
||||
# endif
|
||||
# if defined(HAVE_GETPWANAM) && !defined(DISABLE_SHADOW)
|
||||
# include <sys/label.h>
|
||||
# include <sys/audit.h>
|
||||
# include <pwdadj.h>
|
||||
# endif
|
||||
# if defined(HAVE_MD5_PASSWORDS) && !defined(HAVE_MD5_CRYPT)
|
||||
# include "md5crypt.h"
|
||||
# endif /* defined(HAVE_MD5_PASSWORDS) && !defined(HAVE_MD5_CRYPT) */
|
||||
|
||||
# ifdef HAVE_CYGWIN
|
||||
# undef ERROR
|
||||
# include <windows.h>
|
||||
# include <sys/cygwin.h>
|
||||
# define is_winnt (GetVersion() < 0x80000000)
|
||||
# endif
|
||||
#endif /* !USE_PAM && !HAVE_OSF_SIA */
|
||||
#ifdef WITH_AIXAUTHENTICATE
|
||||
# include "buffer.h"
|
||||
# include "canohost.h"
|
||||
extern Buffer loginmsg;
|
||||
#endif
|
||||
|
||||
extern ServerOptions options;
|
||||
#ifdef WITH_AIXAUTHENTICATE
|
||||
extern char *aixloginmsg;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Tries to authenticate the user using password. Returns true if
|
||||
@ -101,46 +59,26 @@ int
|
||||
auth_password(Authctxt *authctxt, const char *password)
|
||||
{
|
||||
struct passwd * pw = authctxt->pw;
|
||||
#if !defined(USE_PAM) && !defined(HAVE_OSF_SIA)
|
||||
char *encrypted_password;
|
||||
char *pw_password;
|
||||
char *salt;
|
||||
# if defined(__hpux) || defined(HAVE_SECUREWARE)
|
||||
struct pr_passwd *spw;
|
||||
# endif /* __hpux || HAVE_SECUREWARE */
|
||||
# if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW)
|
||||
struct spwd *spw;
|
||||
# endif
|
||||
# if defined(HAVE_GETPWANAM) && !defined(DISABLE_SHADOW)
|
||||
struct passwd_adjunct *spw;
|
||||
# endif
|
||||
# ifdef WITH_AIXAUTHENTICATE
|
||||
char *authmsg;
|
||||
int authsuccess;
|
||||
int reenter = 1;
|
||||
# endif
|
||||
#endif /* !defined(USE_PAM) && !defined(HAVE_OSF_SIA) */
|
||||
int ok = authctxt->valid;
|
||||
|
||||
/* deny if no user. */
|
||||
if (pw == NULL)
|
||||
return 0;
|
||||
#ifndef HAVE_CYGWIN
|
||||
if (pw->pw_uid == 0 && options.permit_root_login != PERMIT_YES)
|
||||
return 0;
|
||||
if (pw && 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(USE_PAM)
|
||||
return auth_pam_password(authctxt, password);
|
||||
#elif defined(HAVE_OSF_SIA)
|
||||
return auth_sia_password(authctxt, password);
|
||||
#if defined(HAVE_OSF_SIA)
|
||||
return auth_sia_password(authctxt, password) && ok;
|
||||
#else
|
||||
# ifdef KRB5
|
||||
if (options.kerberos_authentication == 1) {
|
||||
int ret = auth_krb5_password(authctxt, password);
|
||||
if (ret == 1 || ret == 0)
|
||||
return ret;
|
||||
return ret && ok;
|
||||
/* Fall back to ordinary passwd authentication. */
|
||||
}
|
||||
# endif
|
||||
@ -151,27 +89,47 @@ auth_password(Authctxt *authctxt, const char *password)
|
||||
if (hToken == INVALID_HANDLE_VALUE)
|
||||
return 0;
|
||||
cygwin_set_impersonation_token(hToken);
|
||||
return 1;
|
||||
return ok;
|
||||
}
|
||||
# endif
|
||||
# ifdef WITH_AIXAUTHENTICATE
|
||||
authsuccess = (authenticate(pw->pw_name,password,&reenter,&authmsg) == 0);
|
||||
{
|
||||
char *authmsg = NULL;
|
||||
int reenter = 1;
|
||||
int authsuccess = 0;
|
||||
|
||||
if (authsuccess)
|
||||
/* We don't have a pty yet, so just label the line as "ssh" */
|
||||
if (loginsuccess(authctxt->user,
|
||||
get_canonical_hostname(options.verify_reverse_mapping),
|
||||
"ssh", &aixloginmsg) < 0)
|
||||
aixloginmsg = NULL;
|
||||
if (authenticate(pw->pw_name, password, &reenter,
|
||||
&authmsg) == 0 && ok) {
|
||||
char *msg;
|
||||
char *host =
|
||||
(char *)get_canonical_hostname(options.use_dns);
|
||||
|
||||
return(authsuccess);
|
||||
# endif
|
||||
# ifdef KRB4
|
||||
if (options.kerberos_authentication == 1) {
|
||||
int ret = auth_krb4_password(authctxt, password);
|
||||
if (ret == 1 || ret == 0)
|
||||
return ret;
|
||||
/* Fall back to ordinary passwd authentication. */
|
||||
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);
|
||||
}
|
||||
|
||||
if (authmsg != NULL)
|
||||
xfree(authmsg);
|
||||
|
||||
return authsuccess;
|
||||
}
|
||||
# endif
|
||||
# ifdef BSD_AUTH
|
||||
@ -179,64 +137,28 @@ auth_password(Authctxt *authctxt, const char *password)
|
||||
(char *)password) == 0)
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
# endif
|
||||
pw_password = pw->pw_passwd;
|
||||
|
||||
/*
|
||||
* Various interfaces to shadow or protected password data
|
||||
*/
|
||||
# if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW)
|
||||
spw = getspnam(pw->pw_name);
|
||||
if (spw != NULL)
|
||||
pw_password = spw->sp_pwdp;
|
||||
# endif /* defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) */
|
||||
|
||||
# if defined(HAVE_GETPWANAM) && !defined(DISABLE_SHADOW)
|
||||
if (issecure() && (spw = getpwanam(pw->pw_name)) != NULL)
|
||||
pw_password = spw->pwa_passwd;
|
||||
# endif /* defined(HAVE_GETPWANAM) && !defined(DISABLE_SHADOW) */
|
||||
|
||||
# ifdef HAVE_SECUREWARE
|
||||
if ((spw = getprpwnam(pw->pw_name)) != NULL)
|
||||
pw_password = spw->ufld.fd_encrypt;
|
||||
# endif /* HAVE_SECUREWARE */
|
||||
|
||||
# if defined(__hpux) && !defined(HAVE_SECUREWARE)
|
||||
if (iscomsec() && (spw = getprpwnam(pw->pw_name)) != NULL)
|
||||
pw_password = spw->ufld.fd_encrypt;
|
||||
# endif /* defined(__hpux) && !defined(HAVE_SECUREWARE) */
|
||||
return ok;
|
||||
# else
|
||||
{
|
||||
/* 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 ((password[0] == '\0') && (pw_password[0] == '\0'))
|
||||
return 1;
|
||||
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");
|
||||
|
||||
if (pw_password[0] != '\0')
|
||||
salt = pw_password;
|
||||
else
|
||||
salt = "xx";
|
||||
/*
|
||||
* Authentication is accepted if the encrypted passwords
|
||||
* are identical.
|
||||
*/
|
||||
return (strcmp(encrypted_password, pw_password) == 0) && ok;
|
||||
}
|
||||
|
||||
# ifdef HAVE_MD5_PASSWORDS
|
||||
if (is_md5_salt(salt))
|
||||
encrypted_password = md5_crypt(password, salt);
|
||||
else
|
||||
encrypted_password = crypt(password, salt);
|
||||
# else /* HAVE_MD5_PASSWORDS */
|
||||
# if defined(__hpux) && !defined(HAVE_SECUREWARE)
|
||||
if (iscomsec())
|
||||
encrypted_password = bigcrypt(password, salt);
|
||||
else
|
||||
encrypted_password = crypt(password, salt);
|
||||
# else
|
||||
# ifdef HAVE_SECUREWARE
|
||||
encrypted_password = bigcrypt(password, salt);
|
||||
# else
|
||||
encrypted_password = crypt(password, salt);
|
||||
# endif /* HAVE_SECUREWARE */
|
||||
# endif /* __hpux && !defined(HAVE_SECUREWARE) */
|
||||
# endif /* HAVE_MD5_PASSWORDS */
|
||||
|
||||
/* Authentication is accepted if the encrypted passwords are identical. */
|
||||
return (strcmp(encrypted_password, pw_password) == 0);
|
||||
#endif /* !USE_PAM && !HAVE_OSF_SIA */
|
||||
}
|
||||
# endif
|
||||
#endif /* !HAVE_OSF_SIA */
|
||||
}
|
||||
|
@ -13,7 +13,7 @@
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: auth-rh-rsa.c,v 1.34 2002/03/25 09:25:06 markus Exp $");
|
||||
RCSID("$OpenBSD: auth-rh-rsa.c,v 1.36 2003/06/02 09:17:34 markus Exp $");
|
||||
|
||||
#include "packet.h"
|
||||
#include "uidswap.h"
|
||||
@ -63,7 +63,7 @@ auth_rhosts_rsa(struct passwd *pw, char *cuser, Key *client_host_key)
|
||||
client_host_key->rsa == NULL)
|
||||
return 0;
|
||||
|
||||
chost = (char *)get_canonical_hostname(options.verify_reverse_mapping);
|
||||
chost = (char *)get_canonical_hostname(options.use_dns);
|
||||
debug("Rhosts RSA authentication: canonical host %.900s", chost);
|
||||
|
||||
if (!PRIVSEP(auth_rhosts_rsa_key_allowed(pw, cuser, chost, client_host_key))) {
|
||||
@ -75,7 +75,7 @@ auth_rhosts_rsa(struct passwd *pw, char *cuser, Key *client_host_key)
|
||||
|
||||
/* Perform the challenge-response dialog with the client for the host key. */
|
||||
if (!auth_rsa_challenge_dialog(client_host_key)) {
|
||||
log("Client on %.800s failed to respond correctly to host authentication.",
|
||||
logit("Client on %.800s failed to respond correctly to host authentication.",
|
||||
chost);
|
||||
return 0;
|
||||
}
|
||||
|
@ -14,7 +14,7 @@
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: auth-rsa.c,v 1.56 2002/06/10 16:53:06 stevesk Exp $");
|
||||
RCSID("$OpenBSD: auth-rsa.c,v 1.57 2003/04/08 20:21:28 itojun Exp $");
|
||||
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/md5.h>
|
||||
@ -187,7 +187,7 @@ auth_rsa_key_allowed(struct passwd *pw, BIGNUM *client_n, Key **rkey)
|
||||
secure_filename(f, file, pw, line, sizeof(line)) != 0) {
|
||||
xfree(file);
|
||||
fclose(f);
|
||||
log("Authentication refused: %s", line);
|
||||
logit("Authentication refused: %s", line);
|
||||
restore_uid();
|
||||
return (0);
|
||||
}
|
||||
@ -246,7 +246,7 @@ auth_rsa_key_allowed(struct passwd *pw, BIGNUM *client_n, Key **rkey)
|
||||
|
||||
/* check the real bits */
|
||||
if (bits != BN_num_bits(key->rsa->n))
|
||||
log("Warning: %s, line %lu: keysize mismatch: "
|
||||
logit("Warning: %s, line %lu: keysize mismatch: "
|
||||
"actual %d vs. announced %d.",
|
||||
file, linenum, BN_num_bits(key->rsa->n), bits);
|
||||
|
||||
|
@ -23,7 +23,7 @@
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: auth.c,v 1.46 2002/11/04 10:07:53 markus Exp $");
|
||||
RCSID("$OpenBSD: auth.c,v 1.49 2003/08/26 09:58:43 markus Exp $");
|
||||
RCSID("$FreeBSD$");
|
||||
|
||||
#ifdef HAVE_LOGIN_H
|
||||
@ -55,6 +55,7 @@ RCSID("$FreeBSD$");
|
||||
|
||||
/* import */
|
||||
extern ServerOptions options;
|
||||
extern Buffer loginmsg;
|
||||
|
||||
/* Debugging messages */
|
||||
Buffer auth_debug;
|
||||
@ -73,26 +74,25 @@ int
|
||||
allowed_user(struct passwd * pw)
|
||||
{
|
||||
struct stat st;
|
||||
const char *hostname = NULL, *ipaddr = NULL;
|
||||
const char *hostname = NULL, *ipaddr = NULL, *passwd = NULL;
|
||||
char *shell;
|
||||
int i;
|
||||
#ifdef WITH_AIXAUTHENTICATE
|
||||
char *loginmsg;
|
||||
#endif /* WITH_AIXAUTHENTICATE */
|
||||
#if !defined(USE_PAM) && defined(HAVE_SHADOW_H) && \
|
||||
!defined(DISABLE_SHADOW) && defined(HAS_SHADOW_EXPIRE)
|
||||
struct spwd *spw;
|
||||
time_t today;
|
||||
#if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW)
|
||||
struct spwd *spw = NULL;
|
||||
#endif
|
||||
|
||||
/* Shouldn't be called if pw is NULL, but better safe than sorry... */
|
||||
if (!pw || !pw->pw_name)
|
||||
return 0;
|
||||
|
||||
#if !defined(USE_PAM) && defined(HAVE_SHADOW_H) && \
|
||||
!defined(DISABLE_SHADOW) && defined(HAS_SHADOW_EXPIRE)
|
||||
#if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW)
|
||||
if (!options.use_pam)
|
||||
spw = getspnam(pw->pw_name);
|
||||
#ifdef HAS_SHADOW_EXPIRE
|
||||
#define DAY (24L * 60 * 60) /* 1 day in seconds */
|
||||
if ((spw = getspnam(pw->pw_name)) != NULL) {
|
||||
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,
|
||||
@ -103,25 +103,58 @@ allowed_user(struct passwd * pw)
|
||||
* day after the day specified.
|
||||
*/
|
||||
if (spw->sp_expire != -1 && today > spw->sp_expire) {
|
||||
log("Account %.100s has expired", pw->pw_name);
|
||||
logit("Account %.100s has expired", pw->pw_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (spw->sp_lstchg == 0) {
|
||||
log("User %.100s password has expired (root forced)",
|
||||
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) {
|
||||
log("User %.100s password has expired (password aged)",
|
||||
logit("User %.100s password has expired (password aged)",
|
||||
pw->pw_name);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif /* HAS_SHADOW_EXPIRE */
|
||||
#endif /* defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) */
|
||||
|
||||
/* grab passwd field for locked account check */
|
||||
#if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW)
|
||||
if (spw != NULL)
|
||||
passwd = spw->sp_pwdp;
|
||||
#else
|
||||
passwd = pw->pw_passwd;
|
||||
#endif
|
||||
|
||||
/* check for locked account */
|
||||
if (!options.use_pam && passwd && *passwd) {
|
||||
int locked = 0;
|
||||
|
||||
#ifdef LOCKED_PASSWD_STRING
|
||||
if (strcmp(passwd, LOCKED_PASSWD_STRING) == 0)
|
||||
locked = 1;
|
||||
#endif
|
||||
#ifdef LOCKED_PASSWD_PREFIX
|
||||
if (strncmp(passwd, LOCKED_PASSWD_PREFIX,
|
||||
strlen(LOCKED_PASSWD_PREFIX)) == 0)
|
||||
locked = 1;
|
||||
#endif
|
||||
#ifdef LOCKED_PASSWD_SUBSTR
|
||||
if (strstr(passwd, LOCKED_PASSWD_SUBSTR))
|
||||
locked = 1;
|
||||
#endif
|
||||
if (locked) {
|
||||
logit("User %.100s not allowed because account is locked",
|
||||
pw->pw_name);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the shell from the password data. An empty shell field is
|
||||
* legal, and means /bin/sh.
|
||||
@ -130,19 +163,19 @@ allowed_user(struct passwd * pw)
|
||||
|
||||
/* deny if shell does not exists or is not executable */
|
||||
if (stat(shell, &st) != 0) {
|
||||
log("User %.100s not allowed because shell %.100s does not exist",
|
||||
logit("User %.100s not allowed because shell %.100s does not exist",
|
||||
pw->pw_name, shell);
|
||||
return 0;
|
||||
}
|
||||
if (S_ISREG(st.st_mode) == 0 ||
|
||||
(st.st_mode & (S_IXOTH|S_IXUSR|S_IXGRP)) == 0) {
|
||||
log("User %.100s not allowed because shell %.100s is not executable",
|
||||
logit("User %.100s not allowed because shell %.100s is not executable",
|
||||
pw->pw_name, shell);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (options.num_deny_users > 0 || options.num_allow_users > 0) {
|
||||
hostname = get_canonical_hostname(options.verify_reverse_mapping);
|
||||
hostname = get_canonical_hostname(options.use_dns);
|
||||
ipaddr = get_remote_ipaddr();
|
||||
}
|
||||
|
||||
@ -151,7 +184,7 @@ allowed_user(struct passwd * pw)
|
||||
for (i = 0; i < options.num_deny_users; i++)
|
||||
if (match_user(pw->pw_name, hostname, ipaddr,
|
||||
options.deny_users[i])) {
|
||||
log("User %.100s not allowed because listed in DenyUsers",
|
||||
logit("User %.100s not allowed because listed in DenyUsers",
|
||||
pw->pw_name);
|
||||
return 0;
|
||||
}
|
||||
@ -164,7 +197,7 @@ allowed_user(struct passwd * pw)
|
||||
break;
|
||||
/* i < options.num_allow_users iff we break for loop */
|
||||
if (i >= options.num_allow_users) {
|
||||
log("User %.100s not allowed because not listed in AllowUsers",
|
||||
logit("User %.100s not allowed because not listed in AllowUsers",
|
||||
pw->pw_name);
|
||||
return 0;
|
||||
}
|
||||
@ -172,7 +205,7 @@ allowed_user(struct passwd * pw)
|
||||
if (options.num_deny_groups > 0 || options.num_allow_groups > 0) {
|
||||
/* Get the user's group access list (primary and supplementary) */
|
||||
if (ga_init(pw->pw_name, pw->pw_gid) == 0) {
|
||||
log("User %.100s not allowed because not in any group",
|
||||
logit("User %.100s not allowed because not in any group",
|
||||
pw->pw_name);
|
||||
return 0;
|
||||
}
|
||||
@ -182,7 +215,7 @@ allowed_user(struct passwd * pw)
|
||||
if (ga_match(options.deny_groups,
|
||||
options.num_deny_groups)) {
|
||||
ga_free();
|
||||
log("User %.100s not allowed because a group is listed in DenyGroups",
|
||||
logit("User %.100s not allowed because a group is listed in DenyGroups",
|
||||
pw->pw_name);
|
||||
return 0;
|
||||
}
|
||||
@ -194,7 +227,7 @@ allowed_user(struct passwd * pw)
|
||||
if (!ga_match(options.allow_groups,
|
||||
options.num_allow_groups)) {
|
||||
ga_free();
|
||||
log("User %.100s not allowed because none of user's groups are listed in AllowGroups",
|
||||
logit("User %.100s not allowed because none of user's groups are listed in AllowGroups",
|
||||
pw->pw_name);
|
||||
return 0;
|
||||
}
|
||||
@ -207,26 +240,23 @@ allowed_user(struct passwd * pw)
|
||||
* PermitRootLogin to control logins via ssh), or if running as
|
||||
* non-root user (since loginrestrictions will always fail).
|
||||
*/
|
||||
if ((pw->pw_uid != 0) && (geteuid() == 0) &&
|
||||
loginrestrictions(pw->pw_name, S_RLOGIN, NULL, &loginmsg) != 0) {
|
||||
int loginrestrict_errno = errno;
|
||||
if ((pw->pw_uid != 0) && (geteuid() == 0)) {
|
||||
char *msg;
|
||||
|
||||
if (loginmsg && *loginmsg) {
|
||||
/* Remove embedded newlines (if any) */
|
||||
char *p;
|
||||
for (p = loginmsg; *p; p++) {
|
||||
if (*p == '\n')
|
||||
*p = ' ';
|
||||
if (loginrestrictions(pw->pw_name, S_RLOGIN, NULL, &msg) != 0) {
|
||||
int loginrestrict_errno = errno;
|
||||
|
||||
if (msg && *msg) {
|
||||
buffer_append(&loginmsg, msg, strlen(msg));
|
||||
aix_remove_embedded_newlines(msg);
|
||||
logit("Login restricted for %s: %.100s",
|
||||
pw->pw_name, msg);
|
||||
}
|
||||
/* Remove trailing newline */
|
||||
*--p = '\0';
|
||||
log("Login restricted for %s: %.100s", pw->pw_name,
|
||||
loginmsg);
|
||||
/* Don't fail if /etc/nologin set */
|
||||
if (!(loginrestrict_errno == EPERM &&
|
||||
stat(_PATH_NOLOGIN, &st) == 0))
|
||||
return 0;
|
||||
}
|
||||
/* Don't fail if /etc/nologin set */
|
||||
if (!(loginrestrict_errno == EPERM &&
|
||||
stat(_PATH_NOLOGIN, &st) == 0))
|
||||
return 0;
|
||||
}
|
||||
#endif /* WITH_AIXAUTHENTICATE */
|
||||
|
||||
@ -253,7 +283,7 @@ auth_log(Authctxt *authctxt, int authenticated, char *method, char *info)
|
||||
!authctxt->valid ||
|
||||
authctxt->failures >= AUTH_FAIL_LOG ||
|
||||
strcmp(method, "password") == 0)
|
||||
authlog = log;
|
||||
authlog = logit;
|
||||
|
||||
if (authctxt->postponed)
|
||||
authmsg = "Postponed";
|
||||
@ -269,13 +299,10 @@ auth_log(Authctxt *authctxt, int authenticated, char *method, char *info)
|
||||
get_remote_port(),
|
||||
info);
|
||||
|
||||
#ifdef WITH_AIXAUTHENTICATE
|
||||
#ifdef CUSTOM_FAILED_LOGIN
|
||||
if (authenticated == 0 && strcmp(method, "password") == 0)
|
||||
loginfailed(authctxt->user,
|
||||
get_canonical_hostname(options.verify_reverse_mapping),
|
||||
"ssh");
|
||||
#endif /* WITH_AIXAUTHENTICATE */
|
||||
|
||||
record_failed_login(authctxt->user, "ssh");
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@ -294,12 +321,12 @@ auth_root_allowed(char *method)
|
||||
break;
|
||||
case PERMIT_FORCED_ONLY:
|
||||
if (forced_command) {
|
||||
log("Root login accepted for forced command.");
|
||||
logit("Root login accepted for forced command.");
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
log("ROOT LOGIN REFUSED FROM %.200s", get_remote_ipaddr());
|
||||
logit("ROOT LOGIN REFUSED FROM %.200s", get_remote_ipaddr());
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -391,7 +418,7 @@ check_key_in_hostfiles(struct passwd *pw, Key *key, const char *host,
|
||||
(stat(user_hostfile, &st) == 0) &&
|
||||
((st.st_uid != 0 && st.st_uid != pw->pw_uid) ||
|
||||
(st.st_mode & 022) != 0)) {
|
||||
log("Authentication refused for %.100s: "
|
||||
logit("Authentication refused for %.100s: "
|
||||
"bad owner or modes for %.200s",
|
||||
pw->pw_name, user_hostfile);
|
||||
} else {
|
||||
@ -495,12 +522,10 @@ getpwnamallow(const char *user)
|
||||
|
||||
pw = getpwnam(user);
|
||||
if (pw == NULL) {
|
||||
log("Illegal user %.100s from %.100s",
|
||||
logit("Illegal user %.100s from %.100s",
|
||||
user, get_remote_ipaddr());
|
||||
#ifdef WITH_AIXAUTHENTICATE
|
||||
loginfailed(user,
|
||||
get_canonical_hostname(options.verify_reverse_mapping),
|
||||
"ssh");
|
||||
#ifdef CUSTOM_FAILED_LOGIN
|
||||
record_failed_login(user, "ssh");
|
||||
#endif
|
||||
return (NULL);
|
||||
}
|
||||
@ -565,3 +590,24 @@ auth_debug_reset(void)
|
||||
auth_debug_init = 1;
|
||||
}
|
||||
}
|
||||
|
||||
struct passwd *
|
||||
fakepw(void)
|
||||
{
|
||||
static struct passwd fake;
|
||||
|
||||
memset(&fake, 0, sizeof(fake));
|
||||
fake.pw_name = "NOUSER";
|
||||
fake.pw_passwd =
|
||||
"$2a$06$r3.juUaHZDlIbQaO2dS9FuYxL1W9M81R1Tc92PoSNmzvpEqLkLGrK";
|
||||
fake.pw_gecos = "NOUSER";
|
||||
fake.pw_uid = -1;
|
||||
fake.pw_gid = -1;
|
||||
#ifdef HAVE_PW_CLASS_IN_PASSWD
|
||||
fake.pw_class = "";
|
||||
#endif
|
||||
fake.pw_dir = "/nonexist";
|
||||
fake.pw_shell = "/nonexist";
|
||||
|
||||
return (&fake);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: auth.h,v 1.41 2002/09/26 11:38:43 markus Exp $ */
|
||||
/* $OpenBSD: auth.h,v 1.46 2003/08/28 12:54:34 markus Exp $ */
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/*
|
||||
@ -49,29 +49,32 @@ typedef struct KbdintDevice KbdintDevice;
|
||||
|
||||
struct Authctxt {
|
||||
int success;
|
||||
int postponed;
|
||||
int valid;
|
||||
int postponed; /* authentication needs another step */
|
||||
int valid; /* user exists and is allowed to login */
|
||||
int attempt;
|
||||
int failures;
|
||||
char *user;
|
||||
char *user; /* username sent by the client */
|
||||
char *service;
|
||||
struct passwd *pw;
|
||||
struct passwd *pw; /* set if 'valid' */
|
||||
char *style;
|
||||
void *kbdintctxt;
|
||||
#ifdef BSD_AUTH
|
||||
auth_session_t *as;
|
||||
#endif
|
||||
#ifdef KRB4
|
||||
char *krb4_ticket_file;
|
||||
#endif
|
||||
#ifdef KRB5
|
||||
krb5_context krb5_ctx;
|
||||
krb5_auth_context krb5_auth_ctx;
|
||||
krb5_ccache krb5_fwd_ccache;
|
||||
krb5_principal krb5_user;
|
||||
char *krb5_ticket_file;
|
||||
#endif
|
||||
void *methoddata;
|
||||
};
|
||||
/*
|
||||
* Every authentication method has to handle authentication requests for
|
||||
* non-existing users, or for users that are not allowed to login. In this
|
||||
* case 'valid' is set to 0, but 'user' points to the username requested by
|
||||
* the client.
|
||||
*/
|
||||
|
||||
struct Authmethod {
|
||||
char *name;
|
||||
@ -112,20 +115,6 @@ int auth_rhosts_rsa_key_allowed(struct passwd *, char *, char *, Key *);
|
||||
int hostbased_key_allowed(struct passwd *, const char *, char *, Key *);
|
||||
int user_key_allowed(struct passwd *, Key *);
|
||||
|
||||
#ifdef KRB4
|
||||
#include <krb.h>
|
||||
int auth_krb4(Authctxt *, KTEXT, char **, KTEXT);
|
||||
int auth_krb4_password(Authctxt *, const char *);
|
||||
void krb4_cleanup_proc(void *);
|
||||
|
||||
#ifdef AFS
|
||||
#include <kafs.h>
|
||||
int auth_krb4_tgt(Authctxt *, const char *);
|
||||
int auth_afs_token(Authctxt *, const char *);
|
||||
#endif /* AFS */
|
||||
|
||||
#endif /* KRB4 */
|
||||
|
||||
#ifdef KRB5
|
||||
int auth_krb5(Authctxt *authctxt, krb5_data *auth, char **client, krb5_data *);
|
||||
int auth_krb5_tgt(Authctxt *authctxt, krb5_data *tgt);
|
||||
@ -134,7 +123,6 @@ void krb5_cleanup_proc(void *authctxt);
|
||||
#endif /* KRB5 */
|
||||
|
||||
#include "auth-pam.h"
|
||||
#include "auth2-pam.h"
|
||||
|
||||
Authctxt *do_authentication(void);
|
||||
Authctxt *do_authentication2(void);
|
||||
@ -186,6 +174,8 @@ void auth_debug_add(const char *fmt,...) __attribute__((format(printf, 1, 2)));
|
||||
void auth_debug_send(void);
|
||||
void auth_debug_reset(void);
|
||||
|
||||
struct passwd *fakepw(void);
|
||||
|
||||
#define AUTH_FAIL_MAX 6
|
||||
#define AUTH_FAIL_LOG (AUTH_FAIL_MAX/2)
|
||||
#define AUTH_FAIL_MSG "Too many authentication failures for %.100s"
|
||||
|
@ -10,7 +10,7 @@
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: auth1.c,v 1.47 2003/02/06 21:22:42 markus Exp $");
|
||||
RCSID("$OpenBSD: auth1.c,v 1.52 2003/08/28 12:54:34 markus Exp $");
|
||||
RCSID("$FreeBSD$");
|
||||
|
||||
#include "xmalloc.h"
|
||||
@ -50,10 +50,6 @@ get_authname(int type)
|
||||
case SSH_CMSG_AUTH_TIS:
|
||||
case SSH_CMSG_AUTH_TIS_RESPONSE:
|
||||
return "challenge-response";
|
||||
#if defined(KRB4) || defined(KRB5)
|
||||
case SSH_CMSG_AUTH_KERBEROS:
|
||||
return "kerberos";
|
||||
#endif
|
||||
}
|
||||
snprintf(buf, sizeof buf, "bad-auth-msg-%d", type);
|
||||
return buf;
|
||||
@ -82,7 +78,7 @@ do_authloop(Authctxt *authctxt)
|
||||
|
||||
/* If the user has no password, accept authentication immediately. */
|
||||
if (options.password_authentication &&
|
||||
#if defined(KRB4) || defined(KRB5)
|
||||
#ifdef KRB5
|
||||
(!options.kerberos_authentication || options.kerberos_or_local_passwd) &&
|
||||
#endif
|
||||
PRIVSEP(auth_password(authctxt, ""))) {
|
||||
@ -120,100 +116,6 @@ do_authloop(Authctxt *authctxt)
|
||||
|
||||
/* Process the packet. */
|
||||
switch (type) {
|
||||
|
||||
#if defined(KRB4) || defined(KRB5)
|
||||
case SSH_CMSG_AUTH_KERBEROS:
|
||||
if (!options.kerberos_authentication) {
|
||||
verbose("Kerberos authentication disabled.");
|
||||
} else {
|
||||
char *kdata = packet_get_string(&dlen);
|
||||
packet_check_eom();
|
||||
|
||||
if (kdata[0] == 4) { /* KRB_PROT_VERSION */
|
||||
#ifdef KRB4
|
||||
KTEXT_ST tkt, reply;
|
||||
tkt.length = dlen;
|
||||
if (tkt.length < MAX_KTXT_LEN)
|
||||
memcpy(tkt.dat, kdata, tkt.length);
|
||||
|
||||
if (PRIVSEP(auth_krb4(authctxt, &tkt,
|
||||
&client_user, &reply))) {
|
||||
authenticated = 1;
|
||||
snprintf(info, sizeof(info),
|
||||
" tktuser %.100s",
|
||||
client_user);
|
||||
|
||||
packet_start(
|
||||
SSH_SMSG_AUTH_KERBEROS_RESPONSE);
|
||||
packet_put_string((char *)
|
||||
reply.dat, reply.length);
|
||||
packet_send();
|
||||
packet_write_wait();
|
||||
}
|
||||
#endif /* KRB4 */
|
||||
} else {
|
||||
#ifdef KRB5
|
||||
krb5_data tkt, reply;
|
||||
tkt.length = dlen;
|
||||
tkt.data = kdata;
|
||||
|
||||
if (PRIVSEP(auth_krb5(authctxt, &tkt,
|
||||
&client_user, &reply))) {
|
||||
authenticated = 1;
|
||||
snprintf(info, sizeof(info),
|
||||
" tktuser %.100s",
|
||||
client_user);
|
||||
|
||||
/* Send response to client */
|
||||
packet_start(
|
||||
SSH_SMSG_AUTH_KERBEROS_RESPONSE);
|
||||
packet_put_string((char *)
|
||||
reply.data, reply.length);
|
||||
packet_send();
|
||||
packet_write_wait();
|
||||
|
||||
if (reply.length)
|
||||
xfree(reply.data);
|
||||
}
|
||||
#endif /* KRB5 */
|
||||
}
|
||||
xfree(kdata);
|
||||
}
|
||||
break;
|
||||
#endif /* KRB4 || KRB5 */
|
||||
|
||||
#if defined(AFS) || defined(KRB5)
|
||||
/* XXX - punt on backward compatibility here. */
|
||||
case SSH_CMSG_HAVE_KERBEROS_TGT:
|
||||
packet_send_debug("Kerberos TGT passing disabled before authentication.");
|
||||
break;
|
||||
#ifdef AFS
|
||||
case SSH_CMSG_HAVE_AFS_TOKEN:
|
||||
packet_send_debug("AFS token passing disabled before authentication.");
|
||||
break;
|
||||
#endif /* AFS */
|
||||
#endif /* AFS || KRB5 */
|
||||
|
||||
case SSH_CMSG_AUTH_RHOSTS:
|
||||
if (!options.rhosts_authentication) {
|
||||
verbose("Rhosts authentication disabled.");
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* Get client user name. Note that we just have to
|
||||
* trust the client; this is one reason why rhosts
|
||||
* authentication is insecure. (Another is
|
||||
* IP-spoofing on a local network.)
|
||||
*/
|
||||
client_user = packet_get_string(&ulen);
|
||||
packet_check_eom();
|
||||
|
||||
/* Try to authenticate using /etc/hosts.equiv and .rhosts. */
|
||||
authenticated = auth_rhosts(pw, client_user);
|
||||
|
||||
snprintf(info, sizeof info, " ruser %.100s", client_user);
|
||||
break;
|
||||
|
||||
case SSH_CMSG_AUTH_RHOSTS_RSA:
|
||||
if (!options.rhosts_rsa_authentication) {
|
||||
verbose("Rhosts with RSA authentication disabled.");
|
||||
@ -310,7 +212,7 @@ do_authloop(Authctxt *authctxt)
|
||||
* Any unknown messages will be ignored (and failure
|
||||
* returned) during authentication.
|
||||
*/
|
||||
log("Unknown message during authentication: type %d", type);
|
||||
logit("Unknown message during authentication: type %d", type);
|
||||
break;
|
||||
}
|
||||
#ifdef BSD_AUTH
|
||||
@ -324,8 +226,6 @@ do_authloop(Authctxt *authctxt)
|
||||
authctxt->user);
|
||||
|
||||
#ifdef _UNICOS
|
||||
if (type == SSH_CMSG_AUTH_PASSWORD && !authenticated)
|
||||
cray_login_failure(authctxt->user, IA_UDBERR);
|
||||
if (authenticated && cray_access_denied(authctxt->user)) {
|
||||
authenticated = 0;
|
||||
fatal("Access denied for user %s.",authctxt->user);
|
||||
@ -345,9 +245,10 @@ do_authloop(Authctxt *authctxt)
|
||||
!auth_root_allowed(get_authname(type)))
|
||||
authenticated = 0;
|
||||
#endif
|
||||
|
||||
#ifdef USE_PAM
|
||||
if (!use_privsep && authenticated &&
|
||||
!do_pam_account(pw->pw_name, client_user))
|
||||
if (options.use_pam && authenticated &&
|
||||
!PRIVSEP(do_pam_account()))
|
||||
authenticated = 0;
|
||||
#endif
|
||||
|
||||
@ -362,9 +263,8 @@ do_authloop(Authctxt *authctxt)
|
||||
if (authenticated)
|
||||
return;
|
||||
|
||||
if (authctxt->failures++ > AUTH_FAIL_MAX) {
|
||||
if (authctxt->failures++ > AUTH_FAIL_MAX)
|
||||
packet_disconnect(AUTH_FAIL_MSG, authctxt->user);
|
||||
}
|
||||
|
||||
packet_start(SSH_SMSG_FAILURE);
|
||||
packet_send();
|
||||
@ -393,16 +293,6 @@ do_authentication(void)
|
||||
if ((style = strchr(user, ':')) != NULL)
|
||||
*style++ = '\0';
|
||||
|
||||
#ifdef KRB5
|
||||
/* XXX - SSH.com Kerberos v5 braindeath. */
|
||||
if ((datafellows & SSH_BUG_K5USER) &&
|
||||
options.kerberos_authentication) {
|
||||
char *p;
|
||||
if ((p = strchr(user, '@')) != NULL)
|
||||
*p = '\0';
|
||||
}
|
||||
#endif
|
||||
|
||||
authctxt = authctxt_new();
|
||||
authctxt->user = user;
|
||||
authctxt->style = style;
|
||||
@ -410,14 +300,17 @@ do_authentication(void)
|
||||
/* Verify that the user is a valid user. */
|
||||
if ((authctxt->pw = PRIVSEP(getpwnamallow(user))) != NULL)
|
||||
authctxt->valid = 1;
|
||||
else
|
||||
else {
|
||||
debug("do_authentication: illegal user %s", user);
|
||||
authctxt->pw = fakepw();
|
||||
}
|
||||
|
||||
setproctitle("%s%s", authctxt->pw ? user : "unknown",
|
||||
use_privsep ? " [net]" : "");
|
||||
|
||||
#ifdef USE_PAM
|
||||
PRIVSEP(start_pam(authctxt->pw == NULL ? "NOUSER" : user));
|
||||
if (options.use_pam)
|
||||
PRIVSEP(start_pam(user));
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -43,7 +43,7 @@ static void input_userauth_info_response(int, u_int32_t, void *);
|
||||
extern KbdintDevice bsdauth_device;
|
||||
#else
|
||||
#ifdef USE_PAM
|
||||
extern KbdintDevice pam_device;
|
||||
extern KbdintDevice sshpam_device;
|
||||
#endif
|
||||
#ifdef SKEY
|
||||
extern KbdintDevice skey_device;
|
||||
@ -55,7 +55,7 @@ KbdintDevice *devices[] = {
|
||||
&bsdauth_device,
|
||||
#else
|
||||
#ifdef USE_PAM
|
||||
&pam_device,
|
||||
&sshpam_device,
|
||||
#endif
|
||||
#ifdef SKEY
|
||||
&skey_device,
|
||||
@ -327,22 +327,24 @@ input_userauth_info_response(int type, u_int32_t seq, void *ctxt)
|
||||
void
|
||||
privsep_challenge_enable(void)
|
||||
{
|
||||
#if defined(BSD_AUTH) || defined(USE_PAM) || defined(SKEY)
|
||||
int n = 0;
|
||||
#endif
|
||||
#ifdef BSD_AUTH
|
||||
extern KbdintDevice mm_bsdauth_device;
|
||||
#endif
|
||||
#ifdef USE_PAM
|
||||
extern KbdintDevice mm_pam_device;
|
||||
extern KbdintDevice mm_sshpam_device;
|
||||
#endif
|
||||
#ifdef SKEY
|
||||
extern KbdintDevice mm_skey_device;
|
||||
#endif
|
||||
int n = 0;
|
||||
|
||||
#ifdef BSD_AUTH
|
||||
devices[n++] = &mm_bsdauth_device;
|
||||
#else
|
||||
#ifdef USE_PAM
|
||||
devices[n++] = &mm_pam_device;
|
||||
devices[n++] = &mm_sshpam_device;
|
||||
#endif
|
||||
#ifdef SKEY
|
||||
devices[n++] = &mm_skey_device;
|
||||
|
@ -1,634 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 2002 Networks Associates Technology, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software was developed for the FreeBSD Project by ThinkSec AS and
|
||||
* NAI Labs, the Security Research Division of Network Associates, Inc.
|
||||
* under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the
|
||||
* DARPA CHATS research program.
|
||||
*
|
||||
* 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$FreeBSD$");
|
||||
|
||||
#ifdef USE_PAM
|
||||
#include <security/pam_appl.h>
|
||||
|
||||
#include "auth.h"
|
||||
#include "auth-pam.h"
|
||||
#include "buffer.h"
|
||||
#include "bufaux.h"
|
||||
#include "canohost.h"
|
||||
#include "log.h"
|
||||
#include "monitor_wrap.h"
|
||||
#include "msg.h"
|
||||
#include "packet.h"
|
||||
#include "readpass.h"
|
||||
#include "servconf.h"
|
||||
#include "ssh2.h"
|
||||
#include "xmalloc.h"
|
||||
|
||||
#ifdef USE_POSIX_THREADS
|
||||
#include <pthread.h>
|
||||
#else
|
||||
/*
|
||||
* Simulate threads with processes.
|
||||
*/
|
||||
typedef pid_t pthread_t;
|
||||
|
||||
static void
|
||||
pthread_exit(void *value __unused)
|
||||
{
|
||||
_exit(0);
|
||||
}
|
||||
|
||||
static int
|
||||
pthread_create(pthread_t *thread, const void *attr __unused,
|
||||
void *(*thread_start)(void *), void *arg)
|
||||
{
|
||||
pid_t pid;
|
||||
|
||||
switch ((pid = fork())) {
|
||||
case -1:
|
||||
error("fork(): %s", strerror(errno));
|
||||
return (-1);
|
||||
case 0:
|
||||
thread_start(arg);
|
||||
_exit(1);
|
||||
default:
|
||||
*thread = pid;
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
pthread_cancel(pthread_t thread)
|
||||
{
|
||||
return (kill(thread, SIGTERM));
|
||||
}
|
||||
|
||||
static int
|
||||
pthread_join(pthread_t thread, void **value __unused)
|
||||
{
|
||||
int status;
|
||||
|
||||
waitpid(thread, &status, 0);
|
||||
return (status);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static pam_handle_t *pam_handle;
|
||||
static int pam_err;
|
||||
static int pam_authenticated;
|
||||
static int pam_new_authtok_reqd;
|
||||
static int pam_session_open;
|
||||
static int pam_cred_established;
|
||||
|
||||
struct pam_ctxt {
|
||||
pthread_t pam_thread;
|
||||
int pam_psock;
|
||||
int pam_csock;
|
||||
int pam_done;
|
||||
};
|
||||
|
||||
static void pam_free_ctx(void *);
|
||||
|
||||
/*
|
||||
* Conversation function for authentication thread.
|
||||
*/
|
||||
static int
|
||||
pam_thread_conv(int n,
|
||||
const struct pam_message **msg,
|
||||
struct pam_response **resp,
|
||||
void *data)
|
||||
{
|
||||
Buffer buffer;
|
||||
struct pam_ctxt *ctxt;
|
||||
int i;
|
||||
|
||||
ctxt = data;
|
||||
if (n <= 0 || n > PAM_MAX_NUM_MSG)
|
||||
return (PAM_CONV_ERR);
|
||||
*resp = xmalloc(n * sizeof **resp);
|
||||
memset(*resp, 0, n * sizeof **resp);
|
||||
buffer_init(&buffer);
|
||||
for (i = 0; i < n; ++i) {
|
||||
(*resp)[i].resp_retcode = 0;
|
||||
(*resp)[i].resp = NULL;
|
||||
switch (msg[i]->msg_style) {
|
||||
case PAM_PROMPT_ECHO_OFF:
|
||||
buffer_put_cstring(&buffer, msg[i]->msg);
|
||||
ssh_msg_send(ctxt->pam_csock, msg[i]->msg_style, &buffer);
|
||||
ssh_msg_recv(ctxt->pam_csock, &buffer);
|
||||
if (buffer_get_char(&buffer) != PAM_AUTHTOK)
|
||||
goto fail;
|
||||
(*resp)[i].resp = buffer_get_string(&buffer, NULL);
|
||||
break;
|
||||
case PAM_PROMPT_ECHO_ON:
|
||||
buffer_put_cstring(&buffer, msg[i]->msg);
|
||||
ssh_msg_send(ctxt->pam_csock, msg[i]->msg_style, &buffer);
|
||||
ssh_msg_recv(ctxt->pam_csock, &buffer);
|
||||
if (buffer_get_char(&buffer) != PAM_AUTHTOK)
|
||||
goto fail;
|
||||
(*resp)[i].resp = buffer_get_string(&buffer, NULL);
|
||||
break;
|
||||
case PAM_ERROR_MSG:
|
||||
buffer_put_cstring(&buffer, msg[i]->msg);
|
||||
ssh_msg_send(ctxt->pam_csock, msg[i]->msg_style, &buffer);
|
||||
break;
|
||||
case PAM_TEXT_INFO:
|
||||
buffer_put_cstring(&buffer, msg[i]->msg);
|
||||
ssh_msg_send(ctxt->pam_csock, msg[i]->msg_style, &buffer);
|
||||
break;
|
||||
default:
|
||||
goto fail;
|
||||
}
|
||||
buffer_clear(&buffer);
|
||||
}
|
||||
buffer_free(&buffer);
|
||||
return (PAM_SUCCESS);
|
||||
fail:
|
||||
for (i = 0; i < n; ++i) {
|
||||
if ((*resp)[i].resp != NULL) {
|
||||
memset((*resp)[i].resp, 0, strlen((*resp)[i].resp));
|
||||
xfree((*resp)[i].resp);
|
||||
}
|
||||
}
|
||||
memset(*resp, 0, n * sizeof **resp);
|
||||
xfree(*resp);
|
||||
*resp = NULL;
|
||||
buffer_free(&buffer);
|
||||
return (PAM_CONV_ERR);
|
||||
}
|
||||
|
||||
/*
|
||||
* Authentication thread.
|
||||
*/
|
||||
static void *
|
||||
pam_thread(void *ctxtp)
|
||||
{
|
||||
struct pam_ctxt *ctxt = ctxtp;
|
||||
Buffer buffer;
|
||||
struct pam_conv pam_conv = { pam_thread_conv, ctxt };
|
||||
|
||||
#ifndef USE_POSIX_THREADS
|
||||
{
|
||||
const char *pam_user;
|
||||
|
||||
pam_get_item(pam_handle, PAM_USER, (const void **)&pam_user);
|
||||
setproctitle("%s [pam]", pam_user);
|
||||
}
|
||||
#endif
|
||||
buffer_init(&buffer);
|
||||
pam_err = pam_set_item(pam_handle, PAM_CONV, (const void *)&pam_conv);
|
||||
if (pam_err != PAM_SUCCESS)
|
||||
goto auth_fail;
|
||||
pam_err = pam_authenticate(pam_handle, 0);
|
||||
if (pam_err != PAM_SUCCESS)
|
||||
goto auth_fail;
|
||||
pam_err = pam_acct_mgmt(pam_handle, 0);
|
||||
if (pam_err != PAM_SUCCESS && pam_err != PAM_NEW_AUTHTOK_REQD)
|
||||
goto auth_fail;
|
||||
buffer_put_cstring(&buffer, "OK");
|
||||
ssh_msg_send(ctxt->pam_csock, pam_err, &buffer);
|
||||
buffer_free(&buffer);
|
||||
pthread_exit(NULL);
|
||||
auth_fail:
|
||||
buffer_put_cstring(&buffer,
|
||||
pam_strerror(pam_handle, pam_err));
|
||||
ssh_msg_send(ctxt->pam_csock, PAM_AUTH_ERR, &buffer);
|
||||
buffer_free(&buffer);
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
pam_thread_cleanup(void *ctxtp)
|
||||
{
|
||||
struct pam_ctxt *ctxt = ctxtp;
|
||||
|
||||
pthread_cancel(ctxt->pam_thread);
|
||||
pthread_join(ctxt->pam_thread, NULL);
|
||||
close(ctxt->pam_psock);
|
||||
close(ctxt->pam_csock);
|
||||
}
|
||||
|
||||
static int
|
||||
pam_null_conv(int n,
|
||||
const struct pam_message **msg,
|
||||
struct pam_response **resp,
|
||||
void *data)
|
||||
{
|
||||
|
||||
return (PAM_CONV_ERR);
|
||||
}
|
||||
|
||||
static struct pam_conv null_conv = { pam_null_conv, NULL };
|
||||
|
||||
static void
|
||||
pam_cleanup(void *arg)
|
||||
{
|
||||
(void)arg;
|
||||
debug("PAM: cleanup");
|
||||
pam_set_item(pam_handle, PAM_CONV, (const void *)&null_conv);
|
||||
if (pam_cred_established) {
|
||||
pam_setcred(pam_handle, PAM_DELETE_CRED);
|
||||
pam_cred_established = 0;
|
||||
}
|
||||
if (pam_session_open) {
|
||||
pam_close_session(pam_handle, PAM_SILENT);
|
||||
pam_session_open = 0;
|
||||
}
|
||||
pam_authenticated = pam_new_authtok_reqd = 0;
|
||||
pam_end(pam_handle, pam_err);
|
||||
pam_handle = NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
pam_init(const char *user)
|
||||
{
|
||||
extern ServerOptions options;
|
||||
extern u_int utmp_len;
|
||||
const char *pam_rhost, *pam_user;
|
||||
|
||||
if (pam_handle != NULL) {
|
||||
/* We already have a PAM context; check if the user matches */
|
||||
pam_err = pam_get_item(pam_handle,
|
||||
PAM_USER, (const void **)&pam_user);
|
||||
if (pam_err == PAM_SUCCESS && strcmp(user, pam_user) == 0)
|
||||
return (0);
|
||||
fatal_remove_cleanup(pam_cleanup, NULL);
|
||||
pam_end(pam_handle, pam_err);
|
||||
pam_handle = NULL;
|
||||
}
|
||||
debug("PAM: initializing for \"%s\"", user);
|
||||
pam_err = pam_start("sshd", user, &null_conv, &pam_handle);
|
||||
if (pam_err != PAM_SUCCESS)
|
||||
return (-1);
|
||||
pam_rhost = get_remote_name_or_ip(utmp_len,
|
||||
options.verify_reverse_mapping);
|
||||
debug("PAM: setting PAM_RHOST to \"%s\"", pam_rhost);
|
||||
pam_err = pam_set_item(pam_handle, PAM_RHOST, pam_rhost);
|
||||
if (pam_err != PAM_SUCCESS) {
|
||||
pam_end(pam_handle, pam_err);
|
||||
pam_handle = NULL;
|
||||
return (-1);
|
||||
}
|
||||
fatal_add_cleanup(pam_cleanup, NULL);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void *
|
||||
pam_init_ctx(Authctxt *authctxt)
|
||||
{
|
||||
struct pam_ctxt *ctxt;
|
||||
int socks[2];
|
||||
|
||||
/* Initialize PAM */
|
||||
if (pam_init(authctxt->user) == -1) {
|
||||
error("PAM: initialization failed");
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
ctxt = xmalloc(sizeof *ctxt);
|
||||
ctxt->pam_done = 0;
|
||||
|
||||
/* Start the authentication thread */
|
||||
if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, socks) == -1) {
|
||||
error("PAM: failed create sockets: %s", strerror(errno));
|
||||
xfree(ctxt);
|
||||
return (NULL);
|
||||
}
|
||||
ctxt->pam_psock = socks[0];
|
||||
ctxt->pam_csock = socks[1];
|
||||
if (pthread_create(&ctxt->pam_thread, NULL, pam_thread, ctxt) == -1) {
|
||||
error("PAM: failed to start authentication thread: %s",
|
||||
strerror(errno));
|
||||
close(socks[0]);
|
||||
close(socks[1]);
|
||||
xfree(ctxt);
|
||||
return (NULL);
|
||||
}
|
||||
fatal_add_cleanup(pam_thread_cleanup, ctxt);
|
||||
return (ctxt);
|
||||
}
|
||||
|
||||
static int
|
||||
pam_query(void *ctx, char **name, char **info,
|
||||
u_int *num, char ***prompts, u_int **echo_on)
|
||||
{
|
||||
Buffer buffer;
|
||||
struct pam_ctxt *ctxt = ctx;
|
||||
size_t plen;
|
||||
u_char type;
|
||||
char *msg;
|
||||
|
||||
buffer_init(&buffer);
|
||||
*name = xstrdup("");
|
||||
*info = xstrdup("");
|
||||
*prompts = xmalloc(sizeof(char *));
|
||||
**prompts = NULL;
|
||||
plen = 0;
|
||||
*echo_on = xmalloc(sizeof(u_int));
|
||||
while (ssh_msg_recv(ctxt->pam_psock, &buffer) == 0) {
|
||||
type = buffer_get_char(&buffer);
|
||||
msg = buffer_get_string(&buffer, NULL);
|
||||
switch (type) {
|
||||
case PAM_PROMPT_ECHO_ON:
|
||||
case PAM_PROMPT_ECHO_OFF:
|
||||
*num = 1;
|
||||
**prompts = xrealloc(**prompts, plen + strlen(msg) + 1);
|
||||
plen += sprintf(**prompts + plen, "%s", msg);
|
||||
**echo_on = (type == PAM_PROMPT_ECHO_ON);
|
||||
xfree(msg);
|
||||
return (0);
|
||||
case PAM_ERROR_MSG:
|
||||
case PAM_TEXT_INFO:
|
||||
/* accumulate messages */
|
||||
**prompts = xrealloc(**prompts, plen + strlen(msg) + 1);
|
||||
plen += sprintf(**prompts + plen, "%s", msg);
|
||||
xfree(msg);
|
||||
break;
|
||||
case PAM_NEW_AUTHTOK_REQD:
|
||||
pam_new_authtok_reqd = 1;
|
||||
/* FALLTHROUGH */
|
||||
case PAM_SUCCESS:
|
||||
case PAM_AUTH_ERR:
|
||||
if (**prompts != NULL) {
|
||||
/* drain any accumulated messages */
|
||||
#if 0 /* not compatible with privsep */
|
||||
packet_start(SSH2_MSG_USERAUTH_BANNER);
|
||||
packet_put_cstring(**prompts);
|
||||
packet_put_cstring("");
|
||||
packet_send();
|
||||
packet_write_wait();
|
||||
#endif
|
||||
xfree(**prompts);
|
||||
**prompts = NULL;
|
||||
}
|
||||
if (type == PAM_SUCCESS) {
|
||||
*num = 0;
|
||||
**echo_on = 0;
|
||||
ctxt->pam_done = 1;
|
||||
xfree(msg);
|
||||
return (0);
|
||||
}
|
||||
error("PAM: %s", msg);
|
||||
default:
|
||||
*num = 0;
|
||||
**echo_on = 0;
|
||||
xfree(msg);
|
||||
ctxt->pam_done = -1;
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
return (-1);
|
||||
}
|
||||
|
||||
static int
|
||||
pam_respond(void *ctx, u_int num, char **resp)
|
||||
{
|
||||
Buffer buffer;
|
||||
struct pam_ctxt *ctxt = ctx;
|
||||
char *msg;
|
||||
|
||||
debug2("PAM: %s", __func__);
|
||||
switch (ctxt->pam_done) {
|
||||
case 1:
|
||||
pam_authenticated = 1;
|
||||
return (0);
|
||||
case 0:
|
||||
break;
|
||||
default:
|
||||
return (-1);
|
||||
}
|
||||
if (num != 1) {
|
||||
error("PAM: expected one response, got %u", num);
|
||||
return (-1);
|
||||
}
|
||||
buffer_init(&buffer);
|
||||
buffer_put_cstring(&buffer, *resp);
|
||||
ssh_msg_send(ctxt->pam_psock, PAM_AUTHTOK, &buffer);
|
||||
buffer_free(&buffer);
|
||||
return (1);
|
||||
}
|
||||
|
||||
static void
|
||||
pam_free_ctx(void *ctxtp)
|
||||
{
|
||||
struct pam_ctxt *ctxt = ctxtp;
|
||||
|
||||
fatal_remove_cleanup(pam_thread_cleanup, ctxt);
|
||||
pam_thread_cleanup(ctxtp);
|
||||
xfree(ctxt);
|
||||
/*
|
||||
* We don't call pam_cleanup() here because we may need the PAM
|
||||
* handle at a later stage, e.g. when setting up a session. It's
|
||||
* still on the cleanup list, so pam_end() *will* be called before
|
||||
* the server process terminates.
|
||||
*/
|
||||
}
|
||||
|
||||
KbdintDevice pam_device = {
|
||||
"pam",
|
||||
pam_init_ctx,
|
||||
pam_query,
|
||||
pam_respond,
|
||||
pam_free_ctx
|
||||
};
|
||||
|
||||
KbdintDevice mm_pam_device = {
|
||||
"pam",
|
||||
mm_pam_init_ctx,
|
||||
mm_pam_query,
|
||||
mm_pam_respond,
|
||||
mm_pam_free_ctx
|
||||
};
|
||||
|
||||
/*
|
||||
* This replaces auth-pam.c
|
||||
*/
|
||||
void
|
||||
start_pam(const char *user)
|
||||
{
|
||||
if (pam_init(user) == -1)
|
||||
fatal("PAM: initialisation failed");
|
||||
}
|
||||
|
||||
void
|
||||
finish_pam(void)
|
||||
{
|
||||
fatal_remove_cleanup(pam_cleanup, NULL);
|
||||
pam_cleanup(NULL);
|
||||
}
|
||||
|
||||
int
|
||||
do_pam_account(const char *user, const char *ruser)
|
||||
{
|
||||
/* XXX */
|
||||
return (1);
|
||||
}
|
||||
|
||||
void
|
||||
do_pam_session(const char *user, const char *tty)
|
||||
{
|
||||
pam_err = pam_set_item(pam_handle, PAM_CONV, (const void *)&null_conv);
|
||||
if (pam_err != PAM_SUCCESS)
|
||||
fatal("PAM: failed to set PAM_CONV: %s",
|
||||
pam_strerror(pam_handle, pam_err));
|
||||
debug("PAM: setting PAM_TTY to \"%s\"", tty);
|
||||
pam_err = pam_set_item(pam_handle, PAM_TTY, tty);
|
||||
if (pam_err != PAM_SUCCESS)
|
||||
fatal("PAM: failed to set PAM_TTY: %s",
|
||||
pam_strerror(pam_handle, pam_err));
|
||||
pam_err = pam_open_session(pam_handle, 0);
|
||||
if (pam_err != PAM_SUCCESS)
|
||||
fatal("PAM: pam_open_session(): %s",
|
||||
pam_strerror(pam_handle, pam_err));
|
||||
pam_session_open = 1;
|
||||
}
|
||||
|
||||
void
|
||||
do_pam_setcred(int init)
|
||||
{
|
||||
pam_err = pam_set_item(pam_handle, PAM_CONV, (const void *)&null_conv);
|
||||
if (pam_err != PAM_SUCCESS)
|
||||
fatal("PAM: failed to set PAM_CONV: %s",
|
||||
pam_strerror(pam_handle, pam_err));
|
||||
if (init) {
|
||||
debug("PAM: establishing credentials");
|
||||
pam_err = pam_setcred(pam_handle, PAM_ESTABLISH_CRED);
|
||||
} else {
|
||||
debug("PAM: reinitializing credentials");
|
||||
pam_err = pam_setcred(pam_handle, PAM_REINITIALIZE_CRED);
|
||||
}
|
||||
if (pam_err == PAM_SUCCESS) {
|
||||
pam_cred_established = 1;
|
||||
return;
|
||||
}
|
||||
if (pam_authenticated)
|
||||
fatal("PAM: pam_setcred(): %s",
|
||||
pam_strerror(pam_handle, pam_err));
|
||||
else
|
||||
debug("PAM: pam_setcred(): %s",
|
||||
pam_strerror(pam_handle, pam_err));
|
||||
}
|
||||
|
||||
int
|
||||
is_pam_password_change_required(void)
|
||||
{
|
||||
return (pam_new_authtok_reqd);
|
||||
}
|
||||
|
||||
static int
|
||||
pam_chauthtok_conv(int n,
|
||||
const struct pam_message **msg,
|
||||
struct pam_response **resp,
|
||||
void *data)
|
||||
{
|
||||
char input[PAM_MAX_MSG_SIZE];
|
||||
int i;
|
||||
|
||||
if (n <= 0 || n > PAM_MAX_NUM_MSG)
|
||||
return (PAM_CONV_ERR);
|
||||
*resp = xmalloc(n * sizeof **resp);
|
||||
for (i = 0; i < n; ++i) {
|
||||
switch (msg[i]->msg_style) {
|
||||
case PAM_PROMPT_ECHO_OFF:
|
||||
(*resp)[i].resp =
|
||||
read_passphrase(msg[i]->msg, RP_ALLOW_STDIN);
|
||||
(*resp)[i].resp_retcode = PAM_SUCCESS;
|
||||
break;
|
||||
case PAM_PROMPT_ECHO_ON:
|
||||
fputs(msg[i]->msg, stderr);
|
||||
fgets(input, sizeof input, stdin);
|
||||
(*resp)[i].resp = xstrdup(input);
|
||||
(*resp)[i].resp_retcode = PAM_SUCCESS;
|
||||
break;
|
||||
case PAM_ERROR_MSG:
|
||||
case PAM_TEXT_INFO:
|
||||
fputs(msg[i]->msg, stderr);
|
||||
(*resp)[i].resp_retcode = PAM_SUCCESS;
|
||||
break;
|
||||
default:
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
return (PAM_SUCCESS);
|
||||
fail:
|
||||
xfree(*resp);
|
||||
*resp = NULL;
|
||||
return (PAM_CONV_ERR);
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX this should be done in the authentication phase, but ssh1 doesn't
|
||||
* support that
|
||||
*/
|
||||
void
|
||||
do_pam_chauthtok(void)
|
||||
{
|
||||
struct pam_conv pam_conv = { pam_chauthtok_conv, NULL };
|
||||
|
||||
if (use_privsep)
|
||||
fatal("PAM: chauthtok not supprted with privsep");
|
||||
pam_err = pam_set_item(pam_handle, PAM_CONV, (const void *)&pam_conv);
|
||||
if (pam_err != PAM_SUCCESS)
|
||||
fatal("PAM: failed to set PAM_CONV: %s",
|
||||
pam_strerror(pam_handle, pam_err));
|
||||
debug("PAM: changing password");
|
||||
pam_err = pam_chauthtok(pam_handle, PAM_CHANGE_EXPIRED_AUTHTOK);
|
||||
if (pam_err != PAM_SUCCESS)
|
||||
fatal("PAM: pam_chauthtok(): %s",
|
||||
pam_strerror(pam_handle, pam_err));
|
||||
}
|
||||
|
||||
void
|
||||
print_pam_messages(void)
|
||||
{
|
||||
/* XXX */
|
||||
}
|
||||
|
||||
char **
|
||||
fetch_pam_environment(void)
|
||||
{
|
||||
#ifdef HAVE_PAM_GETENVLIST
|
||||
debug("PAM: retrieving environment");
|
||||
return (pam_getenvlist(pam_handle));
|
||||
#else
|
||||
return (NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
free_pam_environment(char **env)
|
||||
{
|
||||
char **envp;
|
||||
|
||||
for (envp = env; *envp; envp++)
|
||||
xfree(*envp);
|
||||
xfree(env);
|
||||
}
|
||||
|
||||
#endif /* USE_PAM */
|
@ -1,165 +0,0 @@
|
||||
#include "includes.h"
|
||||
RCSID("$Id: auth2-pam.c,v 1.15 2003/01/08 01:37:03 djm Exp $");
|
||||
|
||||
#ifdef USE_PAM
|
||||
#include <security/pam_appl.h>
|
||||
|
||||
#include "ssh.h"
|
||||
#include "ssh2.h"
|
||||
#include "auth.h"
|
||||
#include "auth-pam.h"
|
||||
#include "packet.h"
|
||||
#include "xmalloc.h"
|
||||
#include "dispatch.h"
|
||||
#include "log.h"
|
||||
|
||||
static int do_pam_conversation_kbd_int(int num_msg,
|
||||
const struct pam_message **msg, struct pam_response **resp,
|
||||
void *appdata_ptr);
|
||||
void input_userauth_info_response_pam(int type, u_int32_t seqnr, void *ctxt);
|
||||
|
||||
struct {
|
||||
int finished, num_received, num_expected;
|
||||
int *prompts;
|
||||
struct pam_response *responses;
|
||||
} context_pam2 = {0, 0, 0, NULL};
|
||||
|
||||
static struct pam_conv conv2 = {
|
||||
do_pam_conversation_kbd_int,
|
||||
NULL,
|
||||
};
|
||||
|
||||
int
|
||||
auth2_pam(Authctxt *authctxt)
|
||||
{
|
||||
int retval = -1;
|
||||
|
||||
if (authctxt->user == NULL)
|
||||
fatal("auth2_pam: internal error: no user");
|
||||
|
||||
conv2.appdata_ptr = authctxt;
|
||||
do_pam_set_conv(&conv2);
|
||||
|
||||
dispatch_set(SSH2_MSG_USERAUTH_INFO_RESPONSE,
|
||||
&input_userauth_info_response_pam);
|
||||
retval = (do_pam_authenticate(0) == PAM_SUCCESS);
|
||||
dispatch_set(SSH2_MSG_USERAUTH_INFO_RESPONSE, NULL);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int
|
||||
do_pam_conversation_kbd_int(int num_msg, const struct pam_message **msg,
|
||||
struct pam_response **resp, void *appdata_ptr)
|
||||
{
|
||||
int i, j, done;
|
||||
char *text;
|
||||
|
||||
context_pam2.finished = 0;
|
||||
context_pam2.num_received = 0;
|
||||
context_pam2.num_expected = 0;
|
||||
context_pam2.prompts = xmalloc(sizeof(int) * num_msg);
|
||||
context_pam2.responses = xmalloc(sizeof(struct pam_response) * num_msg);
|
||||
memset(context_pam2.responses, 0, sizeof(struct pam_response) * num_msg);
|
||||
|
||||
text = NULL;
|
||||
for (i = 0, context_pam2.num_expected = 0; i < num_msg; i++) {
|
||||
int style = PAM_MSG_MEMBER(msg, i, msg_style);
|
||||
switch (style) {
|
||||
case PAM_PROMPT_ECHO_ON:
|
||||
case PAM_PROMPT_ECHO_OFF:
|
||||
context_pam2.num_expected++;
|
||||
break;
|
||||
case PAM_TEXT_INFO:
|
||||
case PAM_ERROR_MSG:
|
||||
default:
|
||||
/* Capture all these messages to be sent at once */
|
||||
message_cat(&text, PAM_MSG_MEMBER(msg, i, msg));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (context_pam2.num_expected == 0)
|
||||
return PAM_SUCCESS;
|
||||
|
||||
packet_start(SSH2_MSG_USERAUTH_INFO_REQUEST);
|
||||
packet_put_cstring(""); /* Name */
|
||||
packet_put_cstring(""); /* Instructions */
|
||||
packet_put_cstring(""); /* Language */
|
||||
packet_put_int(context_pam2.num_expected);
|
||||
|
||||
for (i = 0, j = 0; i < num_msg; i++) {
|
||||
int style = PAM_MSG_MEMBER(msg, i, msg_style);
|
||||
|
||||
/* Skip messages which don't need a reply */
|
||||
if (style != PAM_PROMPT_ECHO_ON && style != PAM_PROMPT_ECHO_OFF)
|
||||
continue;
|
||||
|
||||
context_pam2.prompts[j++] = i;
|
||||
if (text) {
|
||||
message_cat(&text, PAM_MSG_MEMBER(msg, i, msg));
|
||||
packet_put_cstring(text);
|
||||
text = NULL;
|
||||
} else
|
||||
packet_put_cstring(PAM_MSG_MEMBER(msg, i, msg));
|
||||
packet_put_char(style == PAM_PROMPT_ECHO_ON);
|
||||
}
|
||||
packet_send();
|
||||
packet_write_wait();
|
||||
|
||||
/*
|
||||
* Grabbing control of execution and spinning until we get what
|
||||
* we want is probably rude, but it seems to work properly, and
|
||||
* the client *should* be in lock-step with us, so the loop should
|
||||
* only be traversed once.
|
||||
*/
|
||||
while(context_pam2.finished == 0) {
|
||||
done = 1;
|
||||
dispatch_run(DISPATCH_BLOCK, &done, appdata_ptr);
|
||||
if (context_pam2.finished == 0)
|
||||
debug("extra packet during conversation");
|
||||
}
|
||||
|
||||
if (context_pam2.num_received == context_pam2.num_expected) {
|
||||
*resp = context_pam2.responses;
|
||||
return PAM_SUCCESS;
|
||||
} else
|
||||
return PAM_CONV_ERR;
|
||||
}
|
||||
|
||||
void
|
||||
input_userauth_info_response_pam(int type, u_int32_t seqnr, void *ctxt)
|
||||
{
|
||||
Authctxt *authctxt = ctxt;
|
||||
unsigned int nresp = 0, rlen = 0, i = 0;
|
||||
char *resp;
|
||||
|
||||
if (authctxt == NULL)
|
||||
fatal("input_userauth_info_response_pam: no authentication context");
|
||||
|
||||
nresp = packet_get_int(); /* Number of responses. */
|
||||
debug("got %d responses", nresp);
|
||||
|
||||
|
||||
if (nresp != context_pam2.num_expected)
|
||||
fatal("%s: Received incorrect number of responses "
|
||||
"(expected %d, received %u)", __func__,
|
||||
context_pam2.num_expected, nresp);
|
||||
|
||||
if (nresp > 100)
|
||||
fatal("%s: too many replies", __func__);
|
||||
|
||||
for (i = 0; i < nresp; i++) {
|
||||
int j = context_pam2.prompts[i];
|
||||
|
||||
resp = packet_get_string(&rlen);
|
||||
context_pam2.responses[j].resp_retcode = PAM_SUCCESS;
|
||||
context_pam2.responses[j].resp = resp;
|
||||
context_pam2.num_received++;
|
||||
}
|
||||
|
||||
context_pam2.finished = 1;
|
||||
|
||||
packet_check_eom();
|
||||
}
|
||||
#endif
|
@ -1,8 +0,0 @@
|
||||
/* $Id: auth2-pam.h,v 1.2 2001/02/09 01:55:36 djm Exp $ */
|
||||
|
||||
#include "includes.h"
|
||||
#ifdef USE_PAM
|
||||
|
||||
int auth2_pam(Authctxt *authctxt);
|
||||
|
||||
#endif /* USE_PAM */
|
@ -23,7 +23,7 @@
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: auth2.c,v 1.96 2003/02/06 21:22:43 markus Exp $");
|
||||
RCSID("$OpenBSD: auth2.c,v 1.102 2003/08/26 09:58:43 markus Exp $");
|
||||
RCSID("$FreeBSD$");
|
||||
|
||||
#include "canohost.h"
|
||||
@ -38,10 +38,14 @@ RCSID("$FreeBSD$");
|
||||
#include "pathnames.h"
|
||||
#include "monitor_wrap.h"
|
||||
|
||||
#ifdef GSSAPI
|
||||
#include "ssh-gss.h"
|
||||
#endif
|
||||
|
||||
/* import */
|
||||
extern ServerOptions options;
|
||||
extern u_char *session_id2;
|
||||
extern int session_id2_len;
|
||||
extern u_int session_id2_len;
|
||||
|
||||
Authctxt *x_authctxt = NULL;
|
||||
|
||||
@ -52,10 +56,16 @@ extern Authmethod method_pubkey;
|
||||
extern Authmethod method_passwd;
|
||||
extern Authmethod method_kbdint;
|
||||
extern Authmethod method_hostbased;
|
||||
#ifdef GSSAPI
|
||||
extern Authmethod method_gssapi;
|
||||
#endif
|
||||
|
||||
Authmethod *authmethods[] = {
|
||||
&method_none,
|
||||
&method_pubkey,
|
||||
#ifdef GSSAPI
|
||||
&method_gssapi,
|
||||
#endif
|
||||
&method_passwd,
|
||||
&method_kbdint,
|
||||
&method_hostbased,
|
||||
@ -87,10 +97,6 @@ do_authentication2(void)
|
||||
/* challenge-response is implemented via keyboard interactive */
|
||||
if (options.challenge_response_authentication)
|
||||
options.kbd_interactive_authentication = 1;
|
||||
if (options.pam_authentication_via_kbd_int)
|
||||
options.kbd_interactive_authentication = 1;
|
||||
if (use_privsep)
|
||||
options.pam_authentication_via_kbd_int = 0;
|
||||
|
||||
dispatch_init(&dispatch_protocol_error);
|
||||
dispatch_set(SSH2_MSG_SERVICE_REQUEST, &input_service_request);
|
||||
@ -143,7 +149,7 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt)
|
||||
login_cap_t *lc;
|
||||
const char *from_host, *from_ip;
|
||||
|
||||
from_host = get_canonical_hostname(options.verify_reverse_mapping);
|
||||
from_host = get_canonical_hostname(options.use_dns);
|
||||
from_ip = get_remote_ipaddr();
|
||||
#endif
|
||||
|
||||
@ -166,12 +172,15 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt)
|
||||
authctxt->valid = 1;
|
||||
debug2("input_userauth_request: setting up authctxt for %s", user);
|
||||
#ifdef USE_PAM
|
||||
PRIVSEP(start_pam(authctxt->pw->pw_name));
|
||||
if (options.use_pam)
|
||||
PRIVSEP(start_pam(authctxt->pw->pw_name));
|
||||
#endif
|
||||
} else {
|
||||
log("input_userauth_request: illegal user %s", user);
|
||||
logit("input_userauth_request: illegal user %s", user);
|
||||
authctxt->pw = fakepw();
|
||||
#ifdef USE_PAM
|
||||
PRIVSEP(start_pam("NOUSER"));
|
||||
if (options.use_pam)
|
||||
PRIVSEP(start_pam(user));
|
||||
#endif
|
||||
}
|
||||
setproctitle("%s%s", authctxt->pw ? user : "unknown",
|
||||
@ -194,12 +203,12 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt)
|
||||
if (lc == NULL)
|
||||
lc = login_getclassbyname(NULL, authctxt->pw);
|
||||
if (!auth_hostok(lc, from_host, from_ip)) {
|
||||
log("Denied connection for %.200s from %.200s [%.200s].",
|
||||
logit("Denied connection for %.200s from %.200s [%.200s].",
|
||||
authctxt->pw->pw_name, from_host, from_ip);
|
||||
packet_disconnect("Sorry, you are not allowed to connect.");
|
||||
}
|
||||
if (!auth_timeok(lc, time(NULL))) {
|
||||
log("LOGIN %.200s REFUSED (TIME) FROM %.200s",
|
||||
logit("LOGIN %.200s REFUSED (TIME) FROM %.200s",
|
||||
authctxt->pw->pw_name, from_host);
|
||||
packet_disconnect("Logins not available right now.");
|
||||
}
|
||||
@ -210,6 +219,12 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt)
|
||||
|
||||
/* reset state */
|
||||
auth2_challenge_stop(authctxt);
|
||||
|
||||
#ifdef GSSAPI
|
||||
dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
|
||||
dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL);
|
||||
#endif
|
||||
|
||||
authctxt->postponed = 0;
|
||||
|
||||
/* try to authenticate user */
|
||||
@ -240,10 +255,9 @@ userauth_finish(Authctxt *authctxt, int authenticated, char *method)
|
||||
authenticated = 0;
|
||||
|
||||
#ifdef USE_PAM
|
||||
if (!use_privsep && authenticated && authctxt->user &&
|
||||
!do_pam_account(authctxt->user, NULL))
|
||||
if (options.use_pam && authenticated && !PRIVSEP(do_pam_account()))
|
||||
authenticated = 0;
|
||||
#endif /* USE_PAM */
|
||||
#endif
|
||||
|
||||
#ifdef _UNICOS
|
||||
if (authenticated && cray_access_denied(authctxt->user)) {
|
||||
@ -268,13 +282,8 @@ userauth_finish(Authctxt *authctxt, int authenticated, char *method)
|
||||
/* now we can break out */
|
||||
authctxt->success = 1;
|
||||
} else {
|
||||
if (authctxt->failures++ > AUTH_FAIL_MAX) {
|
||||
if (authctxt->failures++ > AUTH_FAIL_MAX)
|
||||
packet_disconnect(AUTH_FAIL_MSG, authctxt->user);
|
||||
}
|
||||
#ifdef _UNICOS
|
||||
if (strcmp(method, "password") == 0)
|
||||
cray_login_failure(authctxt->user, IA_UDBERR);
|
||||
#endif /* _UNICOS */
|
||||
methods = authmethods_get();
|
||||
packet_start(SSH2_MSG_USERAUTH_FAILURE);
|
||||
packet_put_cstring(methods);
|
||||
|
@ -35,7 +35,7 @@
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: authfd.c,v 1.58 2003/01/23 13:50:27 markus Exp $");
|
||||
RCSID("$OpenBSD: authfd.c,v 1.61 2003/06/28 16:23:06 deraadt Exp $");
|
||||
|
||||
#include <openssl/evp.h>
|
||||
|
||||
@ -122,8 +122,8 @@ ssh_request_reply(AuthenticationConnection *auth, Buffer *request, Buffer *reply
|
||||
PUT_32BIT(buf, len);
|
||||
|
||||
/* Send the length and then the packet to the agent. */
|
||||
if (atomicio(write, auth->fd, buf, 4) != 4 ||
|
||||
atomicio(write, auth->fd, buffer_ptr(request),
|
||||
if (atomicio(vwrite, auth->fd, buf, 4) != 4 ||
|
||||
atomicio(vwrite, auth->fd, buffer_ptr(request),
|
||||
buffer_len(request)) != buffer_len(request)) {
|
||||
error("Error writing to authentication socket.");
|
||||
return 0;
|
||||
@ -332,7 +332,7 @@ ssh_get_next_identity(AuthenticationConnection *auth, char **comment, int versio
|
||||
buffer_get_bignum(&auth->identities, key->rsa->n);
|
||||
*comment = buffer_get_string(&auth->identities, NULL);
|
||||
if (bits != BN_num_bits(key->rsa->n))
|
||||
log("Warning: identity keysize mismatch: actual %d, announced %u",
|
||||
logit("Warning: identity keysize mismatch: actual %d, announced %u",
|
||||
BN_num_bits(key->rsa->n), bits);
|
||||
break;
|
||||
case 2:
|
||||
@ -373,7 +373,7 @@ ssh_decrypt_challenge(AuthenticationConnection *auth,
|
||||
if (key->type != KEY_RSA1)
|
||||
return 0;
|
||||
if (response_type == 0) {
|
||||
log("Compatibility with ssh protocol version 1.0 no longer supported.");
|
||||
logit("Compatibility with ssh protocol version 1.0 no longer supported.");
|
||||
return 0;
|
||||
}
|
||||
buffer_init(&buffer);
|
||||
@ -392,7 +392,7 @@ ssh_decrypt_challenge(AuthenticationConnection *auth,
|
||||
type = buffer_get_char(&buffer);
|
||||
|
||||
if (agent_failed(type)) {
|
||||
log("Agent admitted failure to authenticate using the key.");
|
||||
logit("Agent admitted failure to authenticate using the key.");
|
||||
} else if (type != SSH_AGENT_RSA_RESPONSE) {
|
||||
fatal("Bad authentication response: %d", type);
|
||||
} else {
|
||||
@ -441,7 +441,7 @@ ssh_agent_sign(AuthenticationConnection *auth,
|
||||
}
|
||||
type = buffer_get_char(&msg);
|
||||
if (agent_failed(type)) {
|
||||
log("Agent admitted failure to sign using the key.");
|
||||
logit("Agent admitted failure to sign using the key.");
|
||||
} else if (type != SSH2_AGENT_SIGN_RESPONSE) {
|
||||
fatal("Bad authentication response: %d", type);
|
||||
} else {
|
||||
@ -589,16 +589,33 @@ ssh_remove_identity(AuthenticationConnection *auth, Key *key)
|
||||
}
|
||||
|
||||
int
|
||||
ssh_update_card(AuthenticationConnection *auth, int add, const char *reader_id, const char *pin)
|
||||
ssh_update_card(AuthenticationConnection *auth, int add,
|
||||
const char *reader_id, const char *pin, u_int life, u_int confirm)
|
||||
{
|
||||
Buffer msg;
|
||||
int type;
|
||||
int type, constrained = (life || confirm);
|
||||
|
||||
if (add) {
|
||||
type = constrained ?
|
||||
SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED :
|
||||
SSH_AGENTC_ADD_SMARTCARD_KEY;
|
||||
} else
|
||||
type = SSH_AGENTC_REMOVE_SMARTCARD_KEY;
|
||||
|
||||
buffer_init(&msg);
|
||||
buffer_put_char(&msg, add ? SSH_AGENTC_ADD_SMARTCARD_KEY :
|
||||
SSH_AGENTC_REMOVE_SMARTCARD_KEY);
|
||||
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);
|
||||
buffer_put_int(&msg, life);
|
||||
}
|
||||
if (confirm != 0)
|
||||
buffer_put_char(&msg, SSH_AGENT_CONSTRAIN_CONFIRM);
|
||||
}
|
||||
|
||||
if (ssh_request_reply(auth, &msg, &msg) == 0) {
|
||||
buffer_free(&msg);
|
||||
return 0;
|
||||
@ -641,7 +658,7 @@ decode_reply(int type)
|
||||
case SSH_AGENT_FAILURE:
|
||||
case SSH_COM_AGENT2_FAILURE:
|
||||
case SSH2_AGENT_FAILURE:
|
||||
log("SSH_AGENT_FAILURE");
|
||||
logit("SSH_AGENT_FAILURE");
|
||||
return 0;
|
||||
case SSH_AGENT_SUCCESS:
|
||||
return 1;
|
||||
|
@ -36,7 +36,7 @@
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: authfile.c,v 1.52 2003/03/13 11:42:18 markus Exp $");
|
||||
RCSID("$OpenBSD: authfile.c,v 1.54 2003/05/24 09:30:39 djm Exp $");
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/evp.h>
|
||||
@ -514,7 +514,7 @@ key_perm_ok(int fd, const char *filename)
|
||||
error("@ WARNING: UNPROTECTED PRIVATE KEY FILE! @");
|
||||
error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
|
||||
error("Permissions 0%3.3o for '%s' are too open.",
|
||||
st.st_mode & 0777, filename);
|
||||
(u_int)st.st_mode & 0777, filename);
|
||||
error("It is recommended that your private key files are NOT accessible by others.");
|
||||
error("This private key will be ignored.");
|
||||
return 0;
|
||||
@ -629,9 +629,18 @@ key_load_public(const char *filename, char **commentp)
|
||||
Key *pub;
|
||||
char file[MAXPATHLEN];
|
||||
|
||||
/* try rsa1 private key */
|
||||
pub = key_load_public_type(KEY_RSA1, filename, commentp);
|
||||
if (pub != NULL)
|
||||
return pub;
|
||||
|
||||
/* try rsa1 public key */
|
||||
pub = key_new(KEY_RSA1);
|
||||
if (key_try_load_public(pub, filename, commentp) == 1)
|
||||
return pub;
|
||||
key_free(pub);
|
||||
|
||||
/* try ssh2 public key */
|
||||
pub = key_new(KEY_UNSPEC);
|
||||
if (key_try_load_public(pub, filename, commentp) == 1)
|
||||
return pub;
|
||||
|
@ -37,7 +37,7 @@
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: bufaux.c,v 1.28 2002/10/23 10:40:16 markus Exp $");
|
||||
RCSID("$OpenBSD: bufaux.c,v 1.29 2003/04/08 20:21:28 itojun Exp $");
|
||||
RCSID("$FreeBSD$");
|
||||
|
||||
#include <openssl/bn.h>
|
||||
@ -120,7 +120,7 @@ buffer_put_bignum2(Buffer *buffer, BIGNUM *value)
|
||||
/**XXX should be two's-complement */
|
||||
int i, carry;
|
||||
u_char *uc = buf;
|
||||
log("negativ!");
|
||||
logit("negativ!");
|
||||
for (i = bytes-1, carry = 1; i>=0; i--) {
|
||||
uc[i] ^= 0xff;
|
||||
if (carry)
|
||||
@ -166,7 +166,6 @@ buffer_get_int(Buffer *buffer)
|
||||
return GET_32BIT(buf);
|
||||
}
|
||||
|
||||
#ifdef HAVE_U_INT64_T
|
||||
u_int64_t
|
||||
buffer_get_int64(Buffer *buffer)
|
||||
{
|
||||
@ -175,7 +174,6 @@ buffer_get_int64(Buffer *buffer)
|
||||
buffer_get(buffer, (char *) buf, 8);
|
||||
return GET_64BIT(buf);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Stores integers in the buffer, msb first.
|
||||
@ -198,7 +196,6 @@ buffer_put_int(Buffer *buffer, u_int value)
|
||||
buffer_append(buffer, buf, 4);
|
||||
}
|
||||
|
||||
#ifdef HAVE_U_INT64_T
|
||||
void
|
||||
buffer_put_int64(Buffer *buffer, u_int64_t value)
|
||||
{
|
||||
@ -207,7 +204,6 @@ buffer_put_int64(Buffer *buffer, u_int64_t value)
|
||||
PUT_64BIT(buf, value);
|
||||
buffer_append(buffer, buf, 8);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Returns an arbitrary binary string from the buffer. The string cannot
|
||||
|
@ -12,7 +12,7 @@
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: canohost.c,v 1.35 2002/11/26 02:38:54 stevesk Exp $");
|
||||
RCSID("$OpenBSD: canohost.c,v 1.37 2003/06/02 09:17:34 markus Exp $");
|
||||
|
||||
#include "packet.h"
|
||||
#include "xmalloc.h"
|
||||
@ -27,7 +27,7 @@ static void check_ip_options(int, char *);
|
||||
*/
|
||||
|
||||
static char *
|
||||
get_remote_hostname(int socket, int verify_reverse_mapping)
|
||||
get_remote_hostname(int socket, int use_dns)
|
||||
{
|
||||
struct sockaddr_storage from;
|
||||
int i;
|
||||
@ -72,6 +72,9 @@ get_remote_hostname(int socket, int verify_reverse_mapping)
|
||||
NULL, 0, NI_NUMERICHOST) != 0)
|
||||
fatal("get_remote_hostname: getnameinfo NI_NUMERICHOST failed");
|
||||
|
||||
if (!use_dns)
|
||||
return xstrdup(ntop);
|
||||
|
||||
if (from.ss_family == AF_INET)
|
||||
check_ip_options(socket, ntop);
|
||||
|
||||
@ -80,14 +83,24 @@ get_remote_hostname(int socket, int verify_reverse_mapping)
|
||||
if (getnameinfo((struct sockaddr *)&from, fromlen, name, sizeof(name),
|
||||
NULL, 0, NI_NAMEREQD) != 0) {
|
||||
/* Host name not found. Use ip address. */
|
||||
#if 0
|
||||
log("Could not reverse map address %.100s.", ntop);
|
||||
#endif
|
||||
return xstrdup(ntop);
|
||||
}
|
||||
|
||||
/* Got host name. */
|
||||
name[sizeof(name) - 1] = '\0';
|
||||
/*
|
||||
* if reverse lookup result looks like a numeric hostname,
|
||||
* someone is trying to trick us by PTR record like following:
|
||||
* 1.1.1.10.in-addr.arpa. IN PTR 2.3.4.5
|
||||
*/
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_socktype = SOCK_DGRAM; /*dummy*/
|
||||
hints.ai_flags = AI_NUMERICHOST;
|
||||
if (getaddrinfo(name, "0", &hints, &ai) == 0) {
|
||||
logit("Nasty PTR record \"%s\" is set up for %s, ignoring",
|
||||
name, ntop);
|
||||
freeaddrinfo(ai);
|
||||
return xstrdup(ntop);
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert it to all lowercase (which is expected by the rest
|
||||
* of this software).
|
||||
@ -95,9 +108,6 @@ get_remote_hostname(int socket, int verify_reverse_mapping)
|
||||
for (i = 0; name[i]; i++)
|
||||
if (isupper(name[i]))
|
||||
name[i] = tolower(name[i]);
|
||||
|
||||
if (!verify_reverse_mapping)
|
||||
return xstrdup(name);
|
||||
/*
|
||||
* Map it back to an IP address and check that the given
|
||||
* address actually is an address of this host. This is
|
||||
@ -111,7 +121,7 @@ get_remote_hostname(int socket, int verify_reverse_mapping)
|
||||
hints.ai_family = from.ss_family;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
if (getaddrinfo(name, NULL, &hints, &aitop) != 0) {
|
||||
log("reverse mapping checking getaddrinfo for %.700s "
|
||||
logit("reverse mapping checking getaddrinfo for %.700s "
|
||||
"failed - POSSIBLE BREAKIN ATTEMPT!", name);
|
||||
return xstrdup(ntop);
|
||||
}
|
||||
@ -126,7 +136,7 @@ get_remote_hostname(int socket, int verify_reverse_mapping)
|
||||
/* If we reached the end of the list, the address was not there. */
|
||||
if (!ai) {
|
||||
/* Address not found for the host name. */
|
||||
log("Address %.100s maps to %.600s, but this does not "
|
||||
logit("Address %.100s maps to %.600s, but this does not "
|
||||
"map back to the address - POSSIBLE BREAKIN ATTEMPT!",
|
||||
ntop, name);
|
||||
return xstrdup(ntop);
|
||||
@ -149,6 +159,7 @@ get_remote_hostname(int socket, int verify_reverse_mapping)
|
||||
static void
|
||||
check_ip_options(int socket, char *ipaddr)
|
||||
{
|
||||
#ifdef IP_OPTIONS
|
||||
u_char options[200];
|
||||
char text[sizeof(options) * 3 + 1];
|
||||
socklen_t option_size;
|
||||
@ -166,11 +177,12 @@ check_ip_options(int socket, char *ipaddr)
|
||||
for (i = 0; i < option_size; i++)
|
||||
snprintf(text + i*3, sizeof(text) - i*3,
|
||||
" %2.2x", options[i]);
|
||||
log("Connection from %.100s with IP options:%.800s",
|
||||
logit("Connection from %.100s with IP options:%.800s",
|
||||
ipaddr, text);
|
||||
packet_disconnect("Connection from %.100s with IP options:%.800s",
|
||||
ipaddr, text);
|
||||
}
|
||||
#endif /* IP_OPTIONS */
|
||||
}
|
||||
|
||||
/*
|
||||
@ -180,14 +192,14 @@ check_ip_options(int socket, char *ipaddr)
|
||||
*/
|
||||
|
||||
const char *
|
||||
get_canonical_hostname(int verify_reverse_mapping)
|
||||
get_canonical_hostname(int use_dns)
|
||||
{
|
||||
static char *canonical_host_name = NULL;
|
||||
static int verify_reverse_mapping_done = 0;
|
||||
static int use_dns_done = 0;
|
||||
|
||||
/* Check if we have previously retrieved name with same option. */
|
||||
if (canonical_host_name != NULL) {
|
||||
if (verify_reverse_mapping_done != verify_reverse_mapping)
|
||||
if (use_dns_done != use_dns)
|
||||
xfree(canonical_host_name);
|
||||
else
|
||||
return canonical_host_name;
|
||||
@ -196,11 +208,11 @@ get_canonical_hostname(int verify_reverse_mapping)
|
||||
/* Get the real hostname if socket; otherwise return UNKNOWN. */
|
||||
if (packet_connection_is_on_socket())
|
||||
canonical_host_name = get_remote_hostname(
|
||||
packet_get_connection_in(), verify_reverse_mapping);
|
||||
packet_get_connection_in(), use_dns);
|
||||
else
|
||||
canonical_host_name = xstrdup("UNKNOWN");
|
||||
|
||||
verify_reverse_mapping_done = verify_reverse_mapping;
|
||||
use_dns_done = use_dns;
|
||||
return canonical_host_name;
|
||||
}
|
||||
|
||||
@ -294,11 +306,11 @@ get_remote_ipaddr(void)
|
||||
}
|
||||
|
||||
const char *
|
||||
get_remote_name_or_ip(u_int utmp_len, int verify_reverse_mapping)
|
||||
get_remote_name_or_ip(u_int utmp_len, int use_dns)
|
||||
{
|
||||
static const char *remote = "";
|
||||
if (utmp_len > 0)
|
||||
remote = get_canonical_hostname(verify_reverse_mapping);
|
||||
remote = get_canonical_hostname(use_dns);
|
||||
if (utmp_len == 0 || strlen(remote) > utmp_len)
|
||||
remote = get_remote_ipaddr();
|
||||
return remote;
|
||||
|
@ -35,7 +35,7 @@
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: cipher.c,v 1.62 2002/11/21 22:45:31 markus Exp $");
|
||||
RCSID("$OpenBSD: cipher.c,v 1.65 2003/05/17 04:27:52 markus Exp $");
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "log.h"
|
||||
@ -49,11 +49,14 @@ RCSID("$OpenBSD: cipher.c,v 1.62 2002/11/21 22:45:31 markus Exp $");
|
||||
#endif
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x00907000L
|
||||
#include "rijndael.h"
|
||||
static const EVP_CIPHER *evp_rijndael(void);
|
||||
extern const EVP_CIPHER *evp_rijndael(void);
|
||||
extern void ssh_rijndael_iv(EVP_CIPHER_CTX *, int, u_char *, u_int);
|
||||
#endif
|
||||
static const EVP_CIPHER *evp_ssh1_3des(void);
|
||||
static const EVP_CIPHER *evp_ssh1_bf(void);
|
||||
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);
|
||||
extern const EVP_CIPHER *evp_aes_128_ctr(void);
|
||||
extern void ssh_aes_ctr_iv(EVP_CIPHER_CTX *, int, u_char *, u_int);
|
||||
|
||||
struct Cipher {
|
||||
char *name;
|
||||
@ -84,6 +87,11 @@ struct Cipher {
|
||||
{ "rijndael-cbc@lysator.liu.se",
|
||||
SSH_CIPHER_SSH2, 16, 32, EVP_aes_256_cbc },
|
||||
#endif
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x00906000L
|
||||
{ "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
|
||||
|
||||
{ NULL, SSH_CIPHER_ILLEGAL, 0, 0, NULL }
|
||||
};
|
||||
@ -296,298 +304,6 @@ cipher_set_key_string(CipherContext *cc, Cipher *cipher,
|
||||
memset(&md, 0, sizeof(md));
|
||||
}
|
||||
|
||||
/* Implementations for other non-EVP ciphers */
|
||||
|
||||
/*
|
||||
* This is used by SSH1:
|
||||
*
|
||||
* What kind of triple DES are these 2 routines?
|
||||
*
|
||||
* Why is there a redundant initialization vector?
|
||||
*
|
||||
* If only iv3 was used, then, this would till effect have been
|
||||
* outer-cbc. However, there is also a private iv1 == iv2 which
|
||||
* perhaps makes differential analysis easier. On the other hand, the
|
||||
* private iv1 probably makes the CRC-32 attack ineffective. This is a
|
||||
* result of that there is no longer any known iv1 to use when
|
||||
* choosing the X block.
|
||||
*/
|
||||
struct ssh1_3des_ctx
|
||||
{
|
||||
EVP_CIPHER_CTX k1, k2, k3;
|
||||
};
|
||||
|
||||
static int
|
||||
ssh1_3des_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv,
|
||||
int enc)
|
||||
{
|
||||
struct ssh1_3des_ctx *c;
|
||||
u_char *k1, *k2, *k3;
|
||||
|
||||
if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) {
|
||||
c = xmalloc(sizeof(*c));
|
||||
EVP_CIPHER_CTX_set_app_data(ctx, c);
|
||||
}
|
||||
if (key == NULL)
|
||||
return (1);
|
||||
if (enc == -1)
|
||||
enc = ctx->encrypt;
|
||||
k1 = k2 = k3 = (u_char *) key;
|
||||
k2 += 8;
|
||||
if (EVP_CIPHER_CTX_key_length(ctx) >= 16+8) {
|
||||
if (enc)
|
||||
k3 += 16;
|
||||
else
|
||||
k1 += 16;
|
||||
}
|
||||
EVP_CIPHER_CTX_init(&c->k1);
|
||||
EVP_CIPHER_CTX_init(&c->k2);
|
||||
EVP_CIPHER_CTX_init(&c->k3);
|
||||
#ifdef SSH_OLD_EVP
|
||||
EVP_CipherInit(&c->k1, EVP_des_cbc(), k1, NULL, enc);
|
||||
EVP_CipherInit(&c->k2, EVP_des_cbc(), k2, NULL, !enc);
|
||||
EVP_CipherInit(&c->k3, EVP_des_cbc(), k3, NULL, enc);
|
||||
#else
|
||||
if (EVP_CipherInit(&c->k1, EVP_des_cbc(), k1, NULL, enc) == 0 ||
|
||||
EVP_CipherInit(&c->k2, EVP_des_cbc(), k2, NULL, !enc) == 0 ||
|
||||
EVP_CipherInit(&c->k3, EVP_des_cbc(), k3, NULL, enc) == 0) {
|
||||
memset(c, 0, sizeof(*c));
|
||||
xfree(c);
|
||||
EVP_CIPHER_CTX_set_app_data(ctx, NULL);
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
return (1);
|
||||
}
|
||||
|
||||
static int
|
||||
ssh1_3des_cbc(EVP_CIPHER_CTX *ctx, u_char *dest, const u_char *src, u_int len)
|
||||
{
|
||||
struct ssh1_3des_ctx *c;
|
||||
|
||||
if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) {
|
||||
error("ssh1_3des_cbc: no context");
|
||||
return (0);
|
||||
}
|
||||
#ifdef SSH_OLD_EVP
|
||||
EVP_Cipher(&c->k1, dest, (u_char *)src, len);
|
||||
EVP_Cipher(&c->k2, dest, dest, len);
|
||||
EVP_Cipher(&c->k3, dest, dest, len);
|
||||
#else
|
||||
if (EVP_Cipher(&c->k1, dest, (u_char *)src, len) == 0 ||
|
||||
EVP_Cipher(&c->k2, dest, dest, len) == 0 ||
|
||||
EVP_Cipher(&c->k3, dest, dest, len) == 0)
|
||||
return (0);
|
||||
#endif
|
||||
return (1);
|
||||
}
|
||||
|
||||
static int
|
||||
ssh1_3des_cleanup(EVP_CIPHER_CTX *ctx)
|
||||
{
|
||||
struct ssh1_3des_ctx *c;
|
||||
|
||||
if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) {
|
||||
memset(c, 0, sizeof(*c));
|
||||
xfree(c);
|
||||
EVP_CIPHER_CTX_set_app_data(ctx, NULL);
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
||||
static const EVP_CIPHER *
|
||||
evp_ssh1_3des(void)
|
||||
{
|
||||
static EVP_CIPHER ssh1_3des;
|
||||
|
||||
memset(&ssh1_3des, 0, sizeof(EVP_CIPHER));
|
||||
ssh1_3des.nid = NID_undef;
|
||||
ssh1_3des.block_size = 8;
|
||||
ssh1_3des.iv_len = 0;
|
||||
ssh1_3des.key_len = 16;
|
||||
ssh1_3des.init = ssh1_3des_init;
|
||||
ssh1_3des.cleanup = ssh1_3des_cleanup;
|
||||
ssh1_3des.do_cipher = ssh1_3des_cbc;
|
||||
#ifndef SSH_OLD_EVP
|
||||
ssh1_3des.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH;
|
||||
#endif
|
||||
return (&ssh1_3des);
|
||||
}
|
||||
|
||||
/*
|
||||
* SSH1 uses a variation on Blowfish, all bytes must be swapped before
|
||||
* and after encryption/decryption. Thus the swap_bytes stuff (yuk).
|
||||
*/
|
||||
static void
|
||||
swap_bytes(const u_char *src, u_char *dst, int n)
|
||||
{
|
||||
u_char c[4];
|
||||
|
||||
/* Process 4 bytes every lap. */
|
||||
for (n = n / 4; n > 0; n--) {
|
||||
c[3] = *src++;
|
||||
c[2] = *src++;
|
||||
c[1] = *src++;
|
||||
c[0] = *src++;
|
||||
|
||||
*dst++ = c[0];
|
||||
*dst++ = c[1];
|
||||
*dst++ = c[2];
|
||||
*dst++ = c[3];
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef SSH_OLD_EVP
|
||||
static void bf_ssh1_init (EVP_CIPHER_CTX * ctx, const unsigned char *key,
|
||||
const unsigned char *iv, int enc)
|
||||
{
|
||||
if (iv != NULL)
|
||||
memcpy (&(ctx->oiv[0]), iv, 8);
|
||||
memcpy (&(ctx->iv[0]), &(ctx->oiv[0]), 8);
|
||||
if (key != NULL)
|
||||
BF_set_key (&(ctx->c.bf_ks), EVP_CIPHER_CTX_key_length (ctx),
|
||||
key);
|
||||
}
|
||||
#endif
|
||||
static int (*orig_bf)(EVP_CIPHER_CTX *, u_char *, const u_char *, u_int) = NULL;
|
||||
|
||||
static int
|
||||
bf_ssh1_cipher(EVP_CIPHER_CTX *ctx, u_char *out, const u_char *in, u_int len)
|
||||
{
|
||||
int ret;
|
||||
|
||||
swap_bytes(in, out, len);
|
||||
ret = (*orig_bf)(ctx, out, out, len);
|
||||
swap_bytes(out, out, len);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static const EVP_CIPHER *
|
||||
evp_ssh1_bf(void)
|
||||
{
|
||||
static EVP_CIPHER ssh1_bf;
|
||||
|
||||
memcpy(&ssh1_bf, EVP_bf_cbc(), sizeof(EVP_CIPHER));
|
||||
orig_bf = ssh1_bf.do_cipher;
|
||||
ssh1_bf.nid = NID_undef;
|
||||
#ifdef SSH_OLD_EVP
|
||||
ssh1_bf.init = bf_ssh1_init;
|
||||
#endif
|
||||
ssh1_bf.do_cipher = bf_ssh1_cipher;
|
||||
ssh1_bf.key_len = 32;
|
||||
return (&ssh1_bf);
|
||||
}
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x00907000L
|
||||
/* RIJNDAEL */
|
||||
#define RIJNDAEL_BLOCKSIZE 16
|
||||
struct ssh_rijndael_ctx
|
||||
{
|
||||
rijndael_ctx r_ctx;
|
||||
u_char r_iv[RIJNDAEL_BLOCKSIZE];
|
||||
};
|
||||
|
||||
static int
|
||||
ssh_rijndael_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv,
|
||||
int enc)
|
||||
{
|
||||
struct ssh_rijndael_ctx *c;
|
||||
|
||||
if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) {
|
||||
c = xmalloc(sizeof(*c));
|
||||
EVP_CIPHER_CTX_set_app_data(ctx, c);
|
||||
}
|
||||
if (key != NULL) {
|
||||
if (enc == -1)
|
||||
enc = ctx->encrypt;
|
||||
rijndael_set_key(&c->r_ctx, (u_char *)key,
|
||||
8*EVP_CIPHER_CTX_key_length(ctx), enc);
|
||||
}
|
||||
if (iv != NULL)
|
||||
memcpy(c->r_iv, iv, RIJNDAEL_BLOCKSIZE);
|
||||
return (1);
|
||||
}
|
||||
|
||||
static int
|
||||
ssh_rijndael_cbc(EVP_CIPHER_CTX *ctx, u_char *dest, const u_char *src,
|
||||
u_int len)
|
||||
{
|
||||
struct ssh_rijndael_ctx *c;
|
||||
u_char buf[RIJNDAEL_BLOCKSIZE];
|
||||
u_char *cprev, *cnow, *plain, *ivp;
|
||||
int i, j, blocks = len / RIJNDAEL_BLOCKSIZE;
|
||||
|
||||
if (len == 0)
|
||||
return (1);
|
||||
if (len % RIJNDAEL_BLOCKSIZE)
|
||||
fatal("ssh_rijndael_cbc: bad len %d", len);
|
||||
if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) {
|
||||
error("ssh_rijndael_cbc: no context");
|
||||
return (0);
|
||||
}
|
||||
if (ctx->encrypt) {
|
||||
cnow = dest;
|
||||
plain = (u_char *)src;
|
||||
cprev = c->r_iv;
|
||||
for (i = 0; i < blocks; i++, plain+=RIJNDAEL_BLOCKSIZE,
|
||||
cnow+=RIJNDAEL_BLOCKSIZE) {
|
||||
for (j = 0; j < RIJNDAEL_BLOCKSIZE; j++)
|
||||
buf[j] = plain[j] ^ cprev[j];
|
||||
rijndael_encrypt(&c->r_ctx, buf, cnow);
|
||||
cprev = cnow;
|
||||
}
|
||||
memcpy(c->r_iv, cprev, RIJNDAEL_BLOCKSIZE);
|
||||
} else {
|
||||
cnow = (u_char *) (src+len-RIJNDAEL_BLOCKSIZE);
|
||||
plain = dest+len-RIJNDAEL_BLOCKSIZE;
|
||||
|
||||
memcpy(buf, cnow, RIJNDAEL_BLOCKSIZE);
|
||||
for (i = blocks; i > 0; i--, cnow-=RIJNDAEL_BLOCKSIZE,
|
||||
plain-=RIJNDAEL_BLOCKSIZE) {
|
||||
rijndael_decrypt(&c->r_ctx, cnow, plain);
|
||||
ivp = (i == 1) ? c->r_iv : cnow-RIJNDAEL_BLOCKSIZE;
|
||||
for (j = 0; j < RIJNDAEL_BLOCKSIZE; j++)
|
||||
plain[j] ^= ivp[j];
|
||||
}
|
||||
memcpy(c->r_iv, buf, RIJNDAEL_BLOCKSIZE);
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
||||
static int
|
||||
ssh_rijndael_cleanup(EVP_CIPHER_CTX *ctx)
|
||||
{
|
||||
struct ssh_rijndael_ctx *c;
|
||||
|
||||
if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) {
|
||||
memset(c, 0, sizeof(*c));
|
||||
xfree(c);
|
||||
EVP_CIPHER_CTX_set_app_data(ctx, NULL);
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
||||
static const EVP_CIPHER *
|
||||
evp_rijndael(void)
|
||||
{
|
||||
static EVP_CIPHER rijndal_cbc;
|
||||
|
||||
memset(&rijndal_cbc, 0, sizeof(EVP_CIPHER));
|
||||
rijndal_cbc.nid = NID_undef;
|
||||
rijndal_cbc.block_size = RIJNDAEL_BLOCKSIZE;
|
||||
rijndal_cbc.iv_len = RIJNDAEL_BLOCKSIZE;
|
||||
rijndal_cbc.key_len = 16;
|
||||
rijndal_cbc.init = ssh_rijndael_init;
|
||||
rijndal_cbc.cleanup = ssh_rijndael_cleanup;
|
||||
rijndal_cbc.do_cipher = ssh_rijndael_cbc;
|
||||
#ifndef SSH_OLD_EVP
|
||||
rijndal_cbc.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH |
|
||||
EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CUSTOM_IV;
|
||||
#endif
|
||||
return (&rijndal_cbc);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Exports an IV from the CipherContext required to export the key
|
||||
* state back from the unprivileged child to the privileged parent
|
||||
@ -611,7 +327,6 @@ void
|
||||
cipher_get_keyiv(CipherContext *cc, u_char *iv, u_int len)
|
||||
{
|
||||
Cipher *c = cc->cipher;
|
||||
u_char *civ = NULL;
|
||||
int evplen;
|
||||
|
||||
switch (c->number) {
|
||||
@ -624,45 +339,28 @@ cipher_get_keyiv(CipherContext *cc, u_char *iv, u_int len)
|
||||
if (evplen != len)
|
||||
fatal("%s: wrong iv length %d != %d", __func__,
|
||||
evplen, len);
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x00907000L
|
||||
if (c->evptype == evp_rijndael) {
|
||||
struct ssh_rijndael_ctx *aesc;
|
||||
|
||||
aesc = EVP_CIPHER_CTX_get_app_data(&cc->evp);
|
||||
if (aesc == NULL)
|
||||
fatal("%s: no rijndael context", __func__);
|
||||
civ = aesc->r_iv;
|
||||
} else
|
||||
if (c->evptype == evp_rijndael)
|
||||
ssh_rijndael_iv(&cc->evp, 0, iv, len);
|
||||
else
|
||||
#endif
|
||||
{
|
||||
civ = cc->evp.iv;
|
||||
}
|
||||
if (c->evptype == evp_aes_128_ctr)
|
||||
ssh_aes_ctr_iv(&cc->evp, 0, iv, len);
|
||||
else
|
||||
memcpy(iv, cc->evp.iv, len);
|
||||
break;
|
||||
case SSH_CIPHER_3DES:
|
||||
ssh1_3des_iv(&cc->evp, 0, iv, 24);
|
||||
break;
|
||||
case SSH_CIPHER_3DES: {
|
||||
struct ssh1_3des_ctx *desc;
|
||||
if (len != 24)
|
||||
fatal("%s: bad 3des iv length: %d", __func__, len);
|
||||
desc = EVP_CIPHER_CTX_get_app_data(&cc->evp);
|
||||
if (desc == NULL)
|
||||
fatal("%s: no 3des context", __func__);
|
||||
debug3("%s: Copying 3DES IV", __func__);
|
||||
memcpy(iv, desc->k1.iv, 8);
|
||||
memcpy(iv + 8, desc->k2.iv, 8);
|
||||
memcpy(iv + 16, desc->k3.iv, 8);
|
||||
return;
|
||||
}
|
||||
default:
|
||||
fatal("%s: bad cipher %d", __func__, c->number);
|
||||
}
|
||||
memcpy(iv, civ, len);
|
||||
}
|
||||
|
||||
void
|
||||
cipher_set_keyiv(CipherContext *cc, u_char *iv)
|
||||
{
|
||||
Cipher *c = cc->cipher;
|
||||
u_char *div = NULL;
|
||||
int evplen = 0;
|
||||
|
||||
switch (c->number) {
|
||||
@ -672,36 +370,22 @@ cipher_set_keyiv(CipherContext *cc, u_char *iv)
|
||||
evplen = EVP_CIPHER_CTX_iv_length(&cc->evp);
|
||||
if (evplen == 0)
|
||||
return;
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x00907000L
|
||||
if (c->evptype == evp_rijndael) {
|
||||
struct ssh_rijndael_ctx *aesc;
|
||||
|
||||
aesc = EVP_CIPHER_CTX_get_app_data(&cc->evp);
|
||||
if (aesc == NULL)
|
||||
fatal("%s: no rijndael context", __func__);
|
||||
div = aesc->r_iv;
|
||||
} else
|
||||
if (c->evptype == evp_rijndael)
|
||||
ssh_rijndael_iv(&cc->evp, 1, iv, evplen);
|
||||
else
|
||||
#endif
|
||||
{
|
||||
div = cc->evp.iv;
|
||||
}
|
||||
if (c->evptype == evp_aes_128_ctr)
|
||||
ssh_aes_ctr_iv(&cc->evp, 1, iv, evplen);
|
||||
else
|
||||
memcpy(cc->evp.iv, iv, evplen);
|
||||
break;
|
||||
case SSH_CIPHER_3DES:
|
||||
ssh1_3des_iv(&cc->evp, 1, iv, 24);
|
||||
break;
|
||||
case SSH_CIPHER_3DES: {
|
||||
struct ssh1_3des_ctx *desc;
|
||||
desc = EVP_CIPHER_CTX_get_app_data(&cc->evp);
|
||||
if (desc == NULL)
|
||||
fatal("%s: no 3des context", __func__);
|
||||
debug3("%s: Installed 3DES IV", __func__);
|
||||
memcpy(desc->k1.iv, iv, 8);
|
||||
memcpy(desc->k2.iv, iv + 8, 8);
|
||||
memcpy(desc->k3.iv, iv + 16, 8);
|
||||
return;
|
||||
}
|
||||
default:
|
||||
fatal("%s: bad cipher %d", __func__, c->number);
|
||||
}
|
||||
memcpy(div, iv, evplen);
|
||||
}
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x00907000L
|
||||
|
@ -23,7 +23,7 @@
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: compat.c,v 1.66 2003/04/01 10:31:26 markus Exp $");
|
||||
RCSID("$OpenBSD: compat.c,v 1.69 2003/08/29 10:03:15 markus Exp $");
|
||||
RCSID("$FreeBSD$");
|
||||
|
||||
#include "buffer.h"
|
||||
@ -80,7 +80,11 @@ 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},
|
||||
"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},
|
||||
{ "Sun_SSH_1.0*", SSH_BUG_NOREKEY|SSH_BUG_EXTEOF},
|
||||
{ "OpenSSH*", 0 },
|
||||
{ "*MindTerm*", 0 },
|
||||
@ -132,12 +136,9 @@ compat_datafellows(const char *version)
|
||||
"1.2.19*,"
|
||||
"1.2.20*,"
|
||||
"1.2.21*,"
|
||||
"1.2.22*", SSH_BUG_IGNOREMSG|SSH_BUG_K5USER },
|
||||
"1.2.22*", SSH_BUG_IGNOREMSG },
|
||||
{ "1.3.2*", /* F-Secure */
|
||||
SSH_BUG_IGNOREMSG|SSH_BUG_K5USER },
|
||||
{ "1.2.1*,"
|
||||
"1.2.2*,"
|
||||
"1.2.3*", SSH_BUG_K5USER },
|
||||
SSH_BUG_IGNOREMSG },
|
||||
{ "*SSH Compatible Server*", /* Netscreen */
|
||||
SSH_BUG_PASSWORDPAD },
|
||||
{ "*OSU_0*,"
|
||||
@ -189,7 +190,7 @@ proto_spec(const char *spec)
|
||||
ret |= SSH_PROTO_2;
|
||||
break;
|
||||
default:
|
||||
log("ignoring bad proto spec: '%s'.", p);
|
||||
logit("ignoring bad proto spec: '%s'.", p);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: compat.h,v 1.34 2003/04/01 10:31:26 markus Exp $ */
|
||||
/* $OpenBSD: compat.h,v 1.36 2003/08/29 10:03:15 markus Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1999, 2000, 2001 Markus Friedl. All rights reserved.
|
||||
@ -53,9 +53,9 @@
|
||||
#define SSH_BUG_DERIVEKEY 0x00040000
|
||||
#define SSH_BUG_DUMMYCHAN 0x00100000
|
||||
#define SSH_BUG_EXTEOF 0x00200000
|
||||
#define SSH_BUG_K5USER 0x00400000
|
||||
#define SSH_BUG_PROBE 0x00800000
|
||||
#define SSH_BUG_FIRSTKEX 0x01000000
|
||||
#define SSH_BUG_PROBE 0x00400000
|
||||
#define SSH_BUG_FIRSTKEX 0x00800000
|
||||
#define SSH_BUG_GSSAPI_BER 0x01000000
|
||||
|
||||
void enable_compat13(void);
|
||||
void enable_compat20(void);
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $Id: configure.ac,v 1.113 2003/03/21 01:18:09 mouring Exp $
|
||||
# $Id: configure.ac,v 1.154.2.11 2003/09/23 09:24:21 djm Exp $
|
||||
# $FreeBSD$
|
||||
|
||||
AC_INIT
|
||||
@ -10,6 +10,7 @@ AC_CANONICAL_HOST
|
||||
AC_C_BIGENDIAN
|
||||
|
||||
# Checks for programs.
|
||||
AC_PROG_AWK
|
||||
AC_PROG_CPP
|
||||
AC_PROG_RANLIB
|
||||
AC_PROG_INSTALL
|
||||
@ -55,36 +56,56 @@ fi
|
||||
# Check for some target-specific stuff
|
||||
case "$host" in
|
||||
*-*-aix*)
|
||||
AFS_LIBS="-lld"
|
||||
CPPFLAGS="$CPPFLAGS -I/usr/local/include"
|
||||
LDFLAGS="$LDFLAGS -L/usr/local/lib"
|
||||
if (test "$LD" != "gcc" && test -z "$blibpath"); then
|
||||
AC_MSG_CHECKING([if linkage editor ($LD) accepts -blibpath])
|
||||
saved_LDFLAGS="$LDFLAGS"
|
||||
LDFLAGS="$LDFLAGS -blibpath:/usr/lib:/lib:/usr/local/lib"
|
||||
AC_TRY_LINK([],
|
||||
[],
|
||||
[
|
||||
AC_MSG_RESULT(yes)
|
||||
blibpath="/usr/lib:/lib:/usr/local/lib"
|
||||
],
|
||||
[ AC_MSG_RESULT(no) ]
|
||||
)
|
||||
LDFLAGS="$saved_LDFLAGS"
|
||||
AC_MSG_CHECKING([how to specify blibpath for linker ($LD)])
|
||||
if (test -z "$blibpath"); then
|
||||
blibpath="/usr/lib:/lib:/usr/local/lib"
|
||||
fi
|
||||
saved_LDFLAGS="$LDFLAGS"
|
||||
for tryflags in -blibpath: -Wl,-blibpath: -Wl,-rpath, ;do
|
||||
if (test -z "$blibflags"); then
|
||||
LDFLAGS="$saved_LDFLAGS $tryflags$blibpath"
|
||||
AC_TRY_LINK([], [], [blibflags=$tryflags])
|
||||
fi
|
||||
done
|
||||
if (test -z "$blibflags"); then
|
||||
AC_MSG_RESULT(not found)
|
||||
AC_MSG_ERROR([*** must be able to specify blibpath on AIX - check config.log])
|
||||
else
|
||||
AC_MSG_RESULT($blibflags)
|
||||
fi
|
||||
LDFLAGS="$saved_LDFLAGS"
|
||||
dnl Check for authenticate. Might be in libs.a on older AIXes
|
||||
AC_CHECK_FUNC(authenticate, [AC_DEFINE(WITH_AIXAUTHENTICATE)],
|
||||
[AC_CHECK_LIB(s,authenticate,
|
||||
[ AC_DEFINE(WITH_AIXAUTHENTICATE)
|
||||
LIBS="$LIBS -ls"
|
||||
])
|
||||
])
|
||||
dnl Check if loginfailed is declared and takes 4 arguments (AIX >= 5.2)
|
||||
AC_CHECK_DECL(loginfailed,
|
||||
[AC_MSG_CHECKING(if loginfailed takes 4 arguments)
|
||||
AC_TRY_COMPILE(
|
||||
[#include <usersec.h>],
|
||||
[(void)loginfailed("user","host","tty",0);],
|
||||
[AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(AIX_LOGINFAILED_4ARG)],
|
||||
[AC_MSG_RESULT(no)]
|
||||
)],
|
||||
[],
|
||||
[#include <usersec.h>]
|
||||
)
|
||||
AC_CHECK_FUNCS(setauthdb)
|
||||
AC_DEFINE(BROKEN_GETADDRINFO)
|
||||
AC_DEFINE(BROKEN_REALPATH)
|
||||
AC_DEFINE(SETEUID_BREAKS_SETUID)
|
||||
AC_DEFINE(BROKEN_SETREUID)
|
||||
AC_DEFINE(BROKEN_SETREGID)
|
||||
dnl AIX handles lastlog as part of its login message
|
||||
AC_DEFINE(DISABLE_LASTLOG)
|
||||
AC_DEFINE(LOGIN_NEEDS_UTMPX)
|
||||
AC_DEFINE(SETPROCTITLE_STRATEGY,PS_USE_CLOBBER_ARGV)
|
||||
AC_DEFINE(SETPROCTITLE_PS_PADDING, '\0')
|
||||
AC_DEFINE(SPT_TYPE,SPT_REUSEARGV)
|
||||
;;
|
||||
*-*-cygwin*)
|
||||
check_for_libcrypt_later=1
|
||||
@ -92,7 +113,6 @@ case "$host" in
|
||||
AC_DEFINE(HAVE_CYGWIN)
|
||||
AC_DEFINE(USE_PIPES)
|
||||
AC_DEFINE(DISABLE_SHADOW)
|
||||
AC_DEFINE(IPV4_DEFAULT)
|
||||
AC_DEFINE(IP_TOS_IS_BROKEN)
|
||||
AC_DEFINE(NO_X11_UNIX_SOCKETS)
|
||||
AC_DEFINE(NO_IPPORT_RESERVED_CONCEPT)
|
||||
@ -113,6 +133,9 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16))
|
||||
[AC_MSG_RESULT(buggy)
|
||||
AC_DEFINE(BROKEN_GETADDRINFO)],
|
||||
[AC_MSG_RESULT(assume it is working)])
|
||||
AC_DEFINE(SETEUID_BREAKS_SETUID)
|
||||
AC_DEFINE(BROKEN_SETREUID)
|
||||
AC_DEFINE(BROKEN_SETREGID)
|
||||
;;
|
||||
*-*-hpux10.26)
|
||||
if test -z "$GCC"; then
|
||||
@ -126,7 +149,8 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16))
|
||||
AC_DEFINE(LOGIN_NEEDS_UTMPX)
|
||||
AC_DEFINE(DISABLE_SHADOW)
|
||||
AC_DEFINE(DISABLE_UTMP)
|
||||
AC_DEFINE(SETPROCTITLE_STRATEGY,PS_USE_PSTAT)
|
||||
AC_DEFINE(LOCKED_PASSWD_STRING, "*")
|
||||
AC_DEFINE(SPT_TYPE,SPT_PSTAT)
|
||||
LIBS="$LIBS -lsec -lsecpw"
|
||||
AC_CHECK_LIB(xnet, t_error, ,AC_MSG_ERROR([*** -lxnet needed on HP-UX - check config.log ***]))
|
||||
disable_ptmx_check=yes
|
||||
@ -142,7 +166,8 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16))
|
||||
AC_DEFINE(LOGIN_NEEDS_UTMPX)
|
||||
AC_DEFINE(DISABLE_SHADOW)
|
||||
AC_DEFINE(DISABLE_UTMP)
|
||||
AC_DEFINE(SETPROCTITLE_STRATEGY,PS_USE_PSTAT)
|
||||
AC_DEFINE(LOCKED_PASSWD_STRING, "*")
|
||||
AC_DEFINE(SPT_TYPE,SPT_PSTAT)
|
||||
LIBS="$LIBS -lsec"
|
||||
AC_CHECK_LIB(xnet, t_error, ,AC_MSG_ERROR([*** -lxnet needed on HP-UX - check config.log ***]))
|
||||
;;
|
||||
@ -155,7 +180,8 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16))
|
||||
AC_DEFINE(LOGIN_NEEDS_UTMPX)
|
||||
AC_DEFINE(DISABLE_SHADOW)
|
||||
AC_DEFINE(DISABLE_UTMP)
|
||||
AC_DEFINE(SETPROCTITLE_STRATEGY,PS_USE_PSTAT)
|
||||
AC_DEFINE(LOCKED_PASSWD_STRING, "*")
|
||||
AC_DEFINE(SPT_TYPE,SPT_PSTAT)
|
||||
LIBS="$LIBS -lsec"
|
||||
AC_CHECK_LIB(xnet, t_error, ,AC_MSG_ERROR([*** -lxnet needed on HP-UX - check config.log ***]))
|
||||
;;
|
||||
@ -165,6 +191,7 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16))
|
||||
PATH="$PATH:/usr/etc"
|
||||
AC_DEFINE(BROKEN_INET_NTOA)
|
||||
AC_DEFINE(WITH_ABBREV_NO_TTY)
|
||||
AC_DEFINE(LOCKED_PASSWD_STRING, "*LK*")
|
||||
;;
|
||||
*-*-irix6*)
|
||||
CPPFLAGS="$CPPFLAGS -I/usr/local/include"
|
||||
@ -175,16 +202,26 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16))
|
||||
AC_DEFINE(WITH_IRIX_AUDIT)
|
||||
AC_CHECK_FUNC(jlimit_startjob, [AC_DEFINE(WITH_IRIX_JOBS)])
|
||||
AC_DEFINE(BROKEN_INET_NTOA)
|
||||
AC_DEFINE(SETEUID_BREAKS_SETUID)
|
||||
AC_DEFINE(BROKEN_SETREUID)
|
||||
AC_DEFINE(BROKEN_SETREGID)
|
||||
AC_DEFINE(WITH_ABBREV_NO_TTY)
|
||||
AC_DEFINE(LOCKED_PASSWD_STRING, "*LK*")
|
||||
;;
|
||||
*-*-linux*)
|
||||
no_dev_ptmx=1
|
||||
check_for_libcrypt_later=1
|
||||
check_for_openpty_ctty_bug=1
|
||||
AC_DEFINE(DONT_TRY_OTHER_AF)
|
||||
AC_DEFINE(PAM_TTY_KLUDGE)
|
||||
AC_DEFINE(SETPROCTITLE_STRATEGY,PS_USE_CLOBBER_ARGV)
|
||||
AC_DEFINE(SETPROCTITLE_PS_PADDING, '\0')
|
||||
AC_DEFINE(LOCKED_PASSWD_PREFIX, "!!")
|
||||
AC_DEFINE(SPT_TYPE,SPT_REUSEARGV)
|
||||
inet6_default_4in6=yes
|
||||
case `uname -r` in
|
||||
1.*|2.0.*)
|
||||
AC_DEFINE(BROKEN_CMSG_TYPE)
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
mips-sony-bsd|mips-sony-newsos4)
|
||||
AC_DEFINE(HAVE_NEWS4)
|
||||
@ -197,6 +234,11 @@ mips-sony-bsd|mips-sony-newsos4)
|
||||
*-*-freebsd*)
|
||||
check_for_libcrypt_later=1
|
||||
;;
|
||||
*-*-bsdi*)
|
||||
AC_DEFINE(SETEUID_BREAKS_SETUID)
|
||||
AC_DEFINE(BROKEN_SETREUID)
|
||||
AC_DEFINE(BROKEN_SETREGID)
|
||||
;;
|
||||
*-next-*)
|
||||
conf_lastlog_location="/usr/adm/lastlog"
|
||||
conf_utmp_location=/etc/utmp
|
||||
@ -217,7 +259,10 @@ mips-sony-bsd|mips-sony-newsos4)
|
||||
AC_DEFINE(LOGIN_NEEDS_UTMPX)
|
||||
AC_DEFINE(LOGIN_NEEDS_TERM)
|
||||
AC_DEFINE(PAM_TTY_KLUDGE)
|
||||
AC_DEFINE(STREAMS_PUSH_ACQUIRES_CTTY)
|
||||
AC_DEFINE(LOCKED_PASSWD_STRING, "*LK*")
|
||||
# Pushing STREAMS modules will cause sshd to acquire a controlling tty.
|
||||
AC_DEFINE(SSHD_ACQUIRES_CTTY)
|
||||
external_path_file=/etc/default/login
|
||||
# hardwire lastlog location (can't detect it on some versions)
|
||||
conf_lastlog_location="/var/adm/lastlog"
|
||||
AC_MSG_CHECKING(for obsolete utmp and wtmp in solaris2.x)
|
||||
@ -244,6 +289,10 @@ mips-sony-bsd|mips-sony-newsos4)
|
||||
LDFLAGS="$LDFLAGS -L/usr/local/lib"
|
||||
LIBS="$LIBS -lc89"
|
||||
AC_DEFINE(USE_PIPES)
|
||||
AC_DEFINE(SSHD_ACQUIRES_CTTY)
|
||||
AC_DEFINE(SETEUID_BREAKS_SETUID)
|
||||
AC_DEFINE(BROKEN_SETREUID)
|
||||
AC_DEFINE(BROKEN_SETREGID)
|
||||
;;
|
||||
*-sni-sysv*)
|
||||
CPPFLAGS="$CPPFLAGS -I/usr/local/include"
|
||||
@ -252,6 +301,8 @@ mips-sony-bsd|mips-sony-newsos4)
|
||||
IPADDR_IN_DISPLAY=yes
|
||||
AC_DEFINE(USE_PIPES)
|
||||
AC_DEFINE(IP_TOS_IS_BROKEN)
|
||||
AC_DEFINE(SSHD_ACQUIRES_CTTY)
|
||||
external_path_file=/etc/default/login
|
||||
# /usr/ucblib/libucb.a no longer needed on ReliantUNIX
|
||||
# Attention: always take care to bind libsocket and libnsl before libc,
|
||||
# otherwise you will find lots of "SIOCGPGRP errno 22" on syslog
|
||||
@ -260,11 +311,17 @@ mips-sony-bsd|mips-sony-newsos4)
|
||||
CPPFLAGS="$CPPFLAGS -I/usr/local/include"
|
||||
LDFLAGS="$LDFLAGS -L/usr/local/lib"
|
||||
AC_DEFINE(USE_PIPES)
|
||||
AC_DEFINE(SETEUID_BREAKS_SETUID)
|
||||
AC_DEFINE(BROKEN_SETREUID)
|
||||
AC_DEFINE(BROKEN_SETREGID)
|
||||
;;
|
||||
*-*-sysv5*)
|
||||
CPPFLAGS="$CPPFLAGS -I/usr/local/include"
|
||||
LDFLAGS="$LDFLAGS -L/usr/local/lib"
|
||||
AC_DEFINE(USE_PIPES)
|
||||
AC_DEFINE(SETEUID_BREAKS_SETUID)
|
||||
AC_DEFINE(BROKEN_SETREUID)
|
||||
AC_DEFINE(BROKEN_SETREGID)
|
||||
;;
|
||||
*-*-sysv*)
|
||||
CPPFLAGS="$CPPFLAGS -I/usr/local/include"
|
||||
@ -281,6 +338,7 @@ mips-sony-bsd|mips-sony-newsos4)
|
||||
AC_DEFINE(HAVE_SECUREWARE)
|
||||
AC_DEFINE(DISABLE_SHADOW)
|
||||
AC_DEFINE(BROKEN_SAVED_UIDS)
|
||||
AC_DEFINE(WITH_ABBREV_NO_TTY)
|
||||
AC_CHECK_FUNCS(getluid setluid)
|
||||
MANTYPE=man
|
||||
do_sco3_extra_lib_check=yes
|
||||
@ -297,6 +355,10 @@ mips-sony-bsd|mips-sony-newsos4)
|
||||
AC_DEFINE(HAVE_SECUREWARE)
|
||||
AC_DEFINE(DISABLE_SHADOW)
|
||||
AC_DEFINE(DISABLE_FD_PASSING)
|
||||
AC_DEFINE(SETEUID_BREAKS_SETUID)
|
||||
AC_DEFINE(BROKEN_SETREUID)
|
||||
AC_DEFINE(BROKEN_SETREGID)
|
||||
AC_DEFINE(WITH_ABBREV_NO_TTY)
|
||||
AC_CHECK_FUNCS(getluid setluid)
|
||||
MANTYPE=man
|
||||
;;
|
||||
@ -307,6 +369,14 @@ mips-sony-bsd|mips-sony-newsos4)
|
||||
LIBS="$LIBS -lgen -lrsc -lshare -luex -lacm"
|
||||
MANTYPE=cat
|
||||
;;
|
||||
*-*-unicosmp*)
|
||||
AC_DEFINE(WITH_ABBREV_NO_TTY)
|
||||
AC_DEFINE(USE_PIPES)
|
||||
AC_DEFINE(DISABLE_FD_PASSING)
|
||||
LDFLAGS="$LDFLAGS"
|
||||
LIBS="$LIBS -lgen -lacid"
|
||||
MANTYPE=cat
|
||||
;;
|
||||
*-*-unicos*)
|
||||
AC_DEFINE(USE_PIPES)
|
||||
AC_DEFINE(DISABLE_FD_PASSING)
|
||||
@ -339,6 +409,11 @@ mips-sony-bsd|mips-sony-newsos4)
|
||||
fi
|
||||
fi
|
||||
AC_DEFINE(DISABLE_FD_PASSING)
|
||||
AC_DEFINE(BROKEN_GETADDRINFO)
|
||||
AC_DEFINE(SETEUID_BREAKS_SETUID)
|
||||
AC_DEFINE(BROKEN_SETREUID)
|
||||
AC_DEFINE(BROKEN_SETREGID)
|
||||
AC_DEFINE(LOCKED_PASSWD_SUBSTR, "Nologin")
|
||||
;;
|
||||
|
||||
*-*-nto-qnx)
|
||||
@ -384,17 +459,29 @@ AC_ARG_WITH(libs,
|
||||
]
|
||||
)
|
||||
|
||||
AC_MSG_CHECKING(compiler and flags for sanity)
|
||||
AC_TRY_RUN([
|
||||
#include <stdio.h>
|
||||
int main(){exit(0);}
|
||||
],
|
||||
[ AC_MSG_RESULT(yes) ],
|
||||
[
|
||||
AC_MSG_RESULT(no)
|
||||
AC_MSG_ERROR([*** compiler cannot create working executables, check config.log ***])
|
||||
]
|
||||
)
|
||||
|
||||
# Checks for header files.
|
||||
AC_CHECK_HEADERS(bstring.h crypt.h endian.h floatingpoint.h \
|
||||
getopt.h glob.h ia.h lastlog.h libgen.h limits.h login.h \
|
||||
AC_CHECK_HEADERS(bstring.h crypt.h endian.h features.h floatingpoint.h \
|
||||
getopt.h glob.h ia.h lastlog.h limits.h login.h \
|
||||
login_cap.h maillock.h netdb.h netgroup.h \
|
||||
netinet/in_systm.h paths.h pty.h readpassphrase.h \
|
||||
rpc/types.h security/pam_appl.h shadow.h stddef.h stdint.h \
|
||||
strings.h sys/bitypes.h sys/bsdtty.h sys/cdefs.h \
|
||||
sys/mman.h sys/pstat.h sys/select.h sys/stat.h \
|
||||
strings.h sys/strtio.h sys/audit.h sys/bitypes.h sys/bsdtty.h \
|
||||
sys/cdefs.h sys/mman.h sys/pstat.h sys/select.h sys/stat.h \
|
||||
sys/stropts.h sys/sysmacros.h sys/time.h sys/timers.h \
|
||||
sys/un.h time.h tmpdir.h ttyent.h usersec.h \
|
||||
util.h utime.h utmp.h utmpx.h)
|
||||
util.h utime.h utmp.h utmpx.h vis.h)
|
||||
|
||||
# Checks for libraries.
|
||||
AC_CHECK_FUNC(yp_match, , AC_CHECK_LIB(nsl, yp_match))
|
||||
@ -407,8 +494,46 @@ if test "x$with_tcp_wrappers" != "xno" ; then
|
||||
fi
|
||||
fi
|
||||
|
||||
dnl IRIX and Solaris 2.5.1 have dirname() in libgen
|
||||
AC_CHECK_FUNCS(dirname, [AC_CHECK_HEADERS(libgen.h)] ,[
|
||||
AC_CHECK_LIB(gen, dirname,[
|
||||
AC_CACHE_CHECK([for broken dirname],
|
||||
ac_cv_have_broken_dirname, [
|
||||
save_LIBS="$LIBS"
|
||||
LIBS="$LIBS -lgen"
|
||||
AC_TRY_RUN(
|
||||
[
|
||||
#include <libgen.h>
|
||||
#include <string.h>
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
char *s, buf[32];
|
||||
|
||||
strncpy(buf,"/etc", 32);
|
||||
s = dirname(buf);
|
||||
if (!s || strncmp(s, "/", 32) != 0) {
|
||||
exit(1);
|
||||
} else {
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
],
|
||||
[ ac_cv_have_broken_dirname="no" ],
|
||||
[ ac_cv_have_broken_dirname="yes" ]
|
||||
)
|
||||
LIBS="$save_LIBS"
|
||||
])
|
||||
if test "x$ac_cv_have_broken_dirname" = "xno" ; then
|
||||
LIBS="$LIBS -lgen"
|
||||
AC_DEFINE(HAVE_DIRNAME)
|
||||
AC_CHECK_HEADERS(libgen.h)
|
||||
fi
|
||||
])
|
||||
])
|
||||
|
||||
AC_CHECK_FUNC(getspnam, ,
|
||||
AC_CHECK_LIB(gen, getspnam, LIBS="$LIBS -lgen"))
|
||||
AC_SEARCH_LIBS(basename, gen, AC_DEFINE(HAVE_BASENAME))
|
||||
|
||||
AC_ARG_WITH(rpath,
|
||||
[ --without-rpath Disable auto-added -R linker paths],
|
||||
@ -640,60 +765,47 @@ AC_ARG_WITH(tcp-wrappers,
|
||||
|
||||
dnl Checks for library functions. Please keep in alphabetical order
|
||||
AC_CHECK_FUNCS(\
|
||||
arc4random __b64_ntop b64_ntop __b64_pton b64_pton basename bcopy \
|
||||
bindresvport_sa clock fchmod fchown freeaddrinfo futimes \
|
||||
gai_strerror getaddrinfo getcwd getgrouplist getnameinfo getopt \
|
||||
getpeereid _getpty getrlimit getrusage getttyent glob inet_aton \
|
||||
arc4random __b64_ntop b64_ntop __b64_pton b64_pton basename \
|
||||
bcopy bindresvport_sa clock fchmod fchown freeaddrinfo futimes \
|
||||
getaddrinfo getcwd getgrouplist getnameinfo getopt \
|
||||
getpeereid _getpty getrlimit getttyent glob inet_aton \
|
||||
inet_ntoa inet_ntop innetgr login_getcapbool md5_crypt memmove \
|
||||
mkdtemp mmap ngetaddrinfo nsleep ogetaddrinfo openpty pstat \
|
||||
readpassphrase realpath recvmsg rresvport_af sendmsg setdtablesize \
|
||||
setegid setenv seteuid setgroups setlogin setpcred setproctitle \
|
||||
setresgid setreuid setrlimit setsid setvbuf sigaction sigvec \
|
||||
snprintf socketpair strerror strlcat strlcpy strmode strnvis \
|
||||
sysconf tcgetpgrp truncate utimes vhangup vsnprintf waitpid \
|
||||
mkdtemp mmap ngetaddrinfo nsleep ogetaddrinfo openlog_r openpty \
|
||||
pstat readpassphrase realpath recvmsg rresvport_af sendmsg \
|
||||
setdtablesize setegid setenv seteuid setgroups setlogin setpcred \
|
||||
setproctitle setregid setresgid setresuid setreuid setrlimit \
|
||||
setsid setvbuf sigaction sigvec snprintf socketpair strerror \
|
||||
strlcat strlcpy strmode strnvis sysconf tcgetpgrp \
|
||||
truncate utimes vhangup vsnprintf waitpid \
|
||||
)
|
||||
|
||||
# IRIX has a const char return value for gai_strerror()
|
||||
AC_CHECK_FUNCS(gai_strerror,[
|
||||
AC_DEFINE(HAVE_GAI_STRERROR)
|
||||
AC_TRY_COMPILE([
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
|
||||
const char *gai_strerror(int);],[
|
||||
char *str;
|
||||
|
||||
str = gai_strerror(0);],[
|
||||
AC_DEFINE(HAVE_CONST_GAI_STRERROR_PROTO, 1,
|
||||
[Define if gai_strerror() returns const char *])])])
|
||||
|
||||
AC_SEARCH_LIBS(nanosleep, rt posix4, AC_DEFINE(HAVE_NANOSLEEP))
|
||||
|
||||
dnl Make sure strsep prototype is defined before defining HAVE_STRSEP
|
||||
dnl Make sure prototypes are defined for these before using them.
|
||||
AC_CHECK_DECL(strsep, [AC_CHECK_FUNCS(strsep)])
|
||||
AC_CHECK_DECL(getrusage, [AC_CHECK_FUNCS(getrusage)])
|
||||
|
||||
dnl IRIX and Solaris 2.5.1 have dirname() in libgen
|
||||
AC_CHECK_FUNCS(dirname, [AC_CHECK_HEADERS(libgen.h)] ,[
|
||||
AC_CHECK_LIB(gen, dirname,[
|
||||
AC_CACHE_CHECK([for broken dirname],
|
||||
ac_cv_have_broken_dirname, [
|
||||
save_LIBS="$LIBS"
|
||||
LIBS="$LIBS -lgen"
|
||||
AC_TRY_RUN(
|
||||
[
|
||||
#include <libgen.h>
|
||||
#include <string.h>
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
char *s, buf[32];
|
||||
|
||||
strncpy(buf,"/etc", 32);
|
||||
s = dirname(buf);
|
||||
if (!s || strncmp(s, "/", 32) != 0) {
|
||||
exit(1);
|
||||
} else {
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
],
|
||||
[ ac_cv_have_broken_dirname="no" ],
|
||||
[ ac_cv_have_broken_dirname="yes" ]
|
||||
)
|
||||
LIBS="$save_LIBS"
|
||||
])
|
||||
if test "x$ac_cv_have_broken_dirname" = "xno" ; then
|
||||
LIBS="$LIBS -lgen"
|
||||
AC_DEFINE(HAVE_DIRNAME)
|
||||
AC_CHECK_HEADERS(libgen.h)
|
||||
fi
|
||||
])
|
||||
])
|
||||
dnl tcsendbreak might be a macro
|
||||
AC_CHECK_DECL(tcsendbreak,
|
||||
[AC_DEFINE(HAVE_TCSENDBREAK)],
|
||||
[AC_CHECK_FUNCS(tcsendbreak)],
|
||||
[#include <termios.h>]
|
||||
)
|
||||
|
||||
dnl Checks for time functions
|
||||
AC_CHECK_FUNCS(gettimeofday time)
|
||||
@ -757,6 +869,53 @@ unlink(template); exit(0);
|
||||
)
|
||||
fi
|
||||
|
||||
dnl make sure that openpty does not reacquire controlling terminal
|
||||
if test ! -z "$check_for_openpty_ctty_bug"; then
|
||||
AC_MSG_CHECKING(if openpty correctly handles controlling tty)
|
||||
AC_TRY_RUN(
|
||||
[
|
||||
#include <stdio.h>
|
||||
#include <sys/fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
pid_t pid;
|
||||
int fd, ptyfd, ttyfd, status;
|
||||
|
||||
pid = fork();
|
||||
if (pid < 0) { /* failed */
|
||||
exit(1);
|
||||
} else if (pid > 0) { /* parent */
|
||||
waitpid(pid, &status, 0);
|
||||
if (WIFEXITED(status))
|
||||
exit(WEXITSTATUS(status));
|
||||
else
|
||||
exit(2);
|
||||
} else { /* child */
|
||||
close(0); close(1); close(2);
|
||||
setsid();
|
||||
openpty(&ptyfd, &ttyfd, NULL, NULL, NULL);
|
||||
fd = open("/dev/tty", O_RDWR | O_NOCTTY);
|
||||
if (fd >= 0)
|
||||
exit(3); /* Acquired ctty: broken */
|
||||
else
|
||||
exit(0); /* Did not acquire ctty: OK */
|
||||
}
|
||||
}
|
||||
],
|
||||
[
|
||||
AC_MSG_RESULT(yes)
|
||||
],
|
||||
[
|
||||
AC_MSG_RESULT(no)
|
||||
AC_DEFINE(SSHD_ACQUIRES_CTTY)
|
||||
]
|
||||
)
|
||||
fi
|
||||
|
||||
AC_FUNC_GETPGRP
|
||||
|
||||
# Check for PAM libs
|
||||
@ -772,6 +931,7 @@ AC_ARG_WITH(pam,
|
||||
AC_CHECK_LIB(dl, dlopen, , )
|
||||
AC_CHECK_LIB(pam, pam_set_item, , AC_MSG_ERROR([*** libpam missing]))
|
||||
AC_CHECK_FUNCS(pam_getenvlist)
|
||||
AC_CHECK_FUNCS(pam_putenv)
|
||||
|
||||
disable_shadow=yes
|
||||
PAM_MSG="yes"
|
||||
@ -936,13 +1096,15 @@ int main(void) { exit(SSLeay() == OPENSSL_VERSION_NUMBER ? 0 : 1); }
|
||||
],
|
||||
[
|
||||
AC_MSG_RESULT(no)
|
||||
AC_MSG_ERROR(Your OpenSSL headers do not match your library)
|
||||
AC_MSG_ERROR([Your OpenSSL headers do not match your library.
|
||||
Check config.log for details.
|
||||
Also see contrib/findssl.sh for help identifying header/library mismatches.])
|
||||
]
|
||||
)
|
||||
|
||||
# Some Linux systems (Slackware) need crypt() from libcrypt, *not* the
|
||||
# version in OpenSSL. Skip this for PAM
|
||||
if test "x$PAM_MSG" = "xno" -a "x$check_for_libcrypt_later" = "x1"; then
|
||||
if test "x$check_for_libcrypt_later" = "x1"; then
|
||||
AC_CHECK_LIB(crypt, crypt, LIBS="$LIBS -lcrypt")
|
||||
fi
|
||||
|
||||
@ -1787,7 +1949,6 @@ if test "x$ac_cv_libc_defines_sys_nerr" = "xyes" ; then
|
||||
fi
|
||||
|
||||
SCARD_MSG="no"
|
||||
|
||||
# Check whether user wants sectok support
|
||||
AC_ARG_WITH(sectok,
|
||||
[ --with-sectok Enable smartcard support using libsectok],
|
||||
@ -1837,6 +1998,29 @@ if test x$opensc_config_prefix != x ; then
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check whether user wants DNS support
|
||||
DNS_MSG="no"
|
||||
AC_ARG_WITH(dns,
|
||||
[ --with-dns Support for fetching keys from DNS (experimental)],
|
||||
[
|
||||
if test "x$withval" != "xno" ; then
|
||||
DNS_MSG="yes"
|
||||
AC_DEFINE(DNS)
|
||||
AC_SEARCH_LIBS(getrrsetbyname, resolv,
|
||||
[AC_DEFINE(HAVE_GETRRSETBYNAME)],
|
||||
[
|
||||
# Needed by our getrrsetbyname()
|
||||
AC_SEARCH_LIBS(res_query, resolv)
|
||||
AC_SEARCH_LIBS(dn_expand, resolv)
|
||||
AC_CHECK_FUNCS(_getshort _getlong)
|
||||
AC_CHECK_MEMBER(HEADER.ad,
|
||||
[AC_DEFINE(HAVE_HEADER_AD)],,
|
||||
[#include <arpa/nameser.h>])
|
||||
])
|
||||
fi
|
||||
]
|
||||
)
|
||||
|
||||
# Check whether user wants Kerberos 5 support
|
||||
KRB5_MSG="no"
|
||||
AC_ARG_WITH(kerberos5,
|
||||
@ -1869,93 +2053,38 @@ AC_ARG_WITH(kerberos5,
|
||||
if test ! -z "$blibpath" ; then
|
||||
blibpath="$blibpath:${KRB5ROOT}/lib"
|
||||
fi
|
||||
AC_CHECK_LIB(resolv, dn_expand, , )
|
||||
AC_SEARCH_LIBS(dn_expand, resolv)
|
||||
|
||||
AC_CHECK_LIB(gssapi,gss_init_sec_context,
|
||||
[ AC_DEFINE(GSSAPI)
|
||||
K5LIBS="-lgssapi $K5LIBS" ],
|
||||
[ AC_CHECK_LIB(gssapi_krb5,gss_init_sec_context,
|
||||
[ AC_DEFINE(GSSAPI)
|
||||
K5LIBS="-lgssapi_krb5 $K5LIBS" ],
|
||||
AC_MSG_WARN([Cannot find any suitable gss-api library - build may fail]),
|
||||
$K5LIBS)
|
||||
],
|
||||
$K5LIBS)
|
||||
|
||||
AC_CHECK_HEADER(gssapi.h, ,
|
||||
[ unset ac_cv_header_gssapi_h
|
||||
CPPFLAGS="$CPPFLAGS -I${KRB5ROOT}/include/gssapi"
|
||||
AC_CHECK_HEADERS(gssapi.h, ,
|
||||
AC_MSG_WARN([Cannot find any suitable gss-api header - build may fail])
|
||||
)
|
||||
]
|
||||
)
|
||||
|
||||
oldCPP="$CPPFLAGS"
|
||||
CPPFLAGS="$CPPFLAGS -I${KRB5ROOT}/include/gssapi"
|
||||
AC_CHECK_HEADER(gssapi_krb5.h, ,
|
||||
[ CPPFLAGS="$oldCPP" ])
|
||||
|
||||
KRB5=yes
|
||||
fi
|
||||
]
|
||||
)
|
||||
# Check whether user wants Kerberos 4 support
|
||||
KRB4_MSG="no"
|
||||
AC_ARG_WITH(kerberos4,
|
||||
[ --with-kerberos4=PATH Enable Kerberos 4 support],
|
||||
[
|
||||
if test "x$withval" != "xno" ; then
|
||||
if test "x$withval" != "xyes" ; then
|
||||
CPPFLAGS="$CPPFLAGS -I${withval}/include"
|
||||
LDFLAGS="$LDFLAGS -L${withval}/lib"
|
||||
if test ! -z "$need_dash_r" ; then
|
||||
LDFLAGS="$LDFLAGS -R${withval}/lib"
|
||||
fi
|
||||
if test ! -z "$blibpath" ; then
|
||||
blibpath="$blibpath:${withval}/lib"
|
||||
fi
|
||||
else
|
||||
if test -d /usr/include/kerberosIV ; then
|
||||
CPPFLAGS="$CPPFLAGS -I/usr/include/kerberosIV"
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_CHECK_HEADERS(krb.h)
|
||||
if test "$ac_cv_header_krb_h" != yes; then
|
||||
AC_MSG_WARN([Cannot find krb.h, build may fail])
|
||||
fi
|
||||
AC_CHECK_LIB(krb, main)
|
||||
if test "$ac_cv_lib_krb_main" != yes; then
|
||||
AC_CHECK_LIB(krb4, main)
|
||||
if test "$ac_cv_lib_krb4_main" != yes; then
|
||||
AC_MSG_WARN([Cannot find libkrb nor libkrb4, build may fail])
|
||||
else
|
||||
KLIBS="-lkrb4"
|
||||
fi
|
||||
else
|
||||
KLIBS="-lkrb"
|
||||
fi
|
||||
AC_CHECK_LIB(des, des_cbc_encrypt)
|
||||
if test "$ac_cv_lib_des_des_cbc_encrypt" != yes; then
|
||||
AC_CHECK_LIB(des425, des_cbc_encrypt)
|
||||
if test "$ac_cv_lib_des425_des_cbc_encrypt" != yes; then
|
||||
AC_MSG_WARN([Cannot find libdes nor libdes425, build may fail])
|
||||
else
|
||||
KLIBS="-ldes425"
|
||||
fi
|
||||
else
|
||||
KLIBS="-ldes"
|
||||
fi
|
||||
AC_CHECK_LIB(resolv, dn_expand, , )
|
||||
KRB4=yes
|
||||
KRB4_MSG="yes"
|
||||
AC_DEFINE(KRB4)
|
||||
fi
|
||||
]
|
||||
)
|
||||
|
||||
# Check whether user wants AFS support
|
||||
AFS_MSG="no"
|
||||
AC_ARG_WITH(afs,
|
||||
[ --with-afs=PATH Enable AFS support],
|
||||
[
|
||||
if test "x$withval" != "xno" ; then
|
||||
|
||||
if test "x$withval" != "xyes" ; then
|
||||
CPPFLAGS="$CPPFLAGS -I${withval}/include"
|
||||
LDFLAGS="$LDFLAGS -L${withval}/lib"
|
||||
fi
|
||||
|
||||
if test -z "$KRB4" ; then
|
||||
AC_MSG_WARN([AFS requires Kerberos IV support, build may fail])
|
||||
fi
|
||||
|
||||
LIBS="-lkafs $LIBS"
|
||||
if test ! -z "$AFS_LIBS" ; then
|
||||
LIBS="$LIBS $AFS_LIBS"
|
||||
fi
|
||||
AC_DEFINE(AFS)
|
||||
AFS_MSG="yes"
|
||||
fi
|
||||
]
|
||||
)
|
||||
LIBS="$LIBS $KLIBS $K5LIBS"
|
||||
LIBS="$LIBS $K5LIBS"
|
||||
|
||||
# Looking for programs, paths and files
|
||||
|
||||
@ -2125,30 +2254,52 @@ else
|
||||
)
|
||||
fi
|
||||
|
||||
# check for /etc/default/login and use it if present.
|
||||
AC_ARG_ENABLE(etc-default-login,
|
||||
[ --disable-etc-default-login Disable using PATH from /etc/default/login [no]],,
|
||||
[
|
||||
AC_CHECK_FILE("/etc/default/login", [ external_path_file=/etc/default/login ])
|
||||
|
||||
if test "x$external_path_file" = "x/etc/default/login"; then
|
||||
AC_DEFINE(HAVE_ETC_DEFAULT_LOGIN)
|
||||
fi
|
||||
])
|
||||
|
||||
dnl BSD systems use /etc/login.conf so --with-default-path= has no effect
|
||||
if test $ac_cv_func_login_getcapbool = "yes" -a \
|
||||
$ac_cv_header_login_cap_h = "yes" ; then
|
||||
USES_LOGIN_CONF=yes
|
||||
external_path_file=/etc/login.conf
|
||||
fi
|
||||
|
||||
# Whether to mess with the default path
|
||||
SERVER_PATH_MSG="(default)"
|
||||
AC_ARG_WITH(default-path,
|
||||
[ --with-default-path= Specify default \$PATH environment for server],
|
||||
[
|
||||
if test "$USES_LOGIN_CONF" = "yes" ; then
|
||||
if test "x$external_path_file" = "x/etc/login.conf" ; then
|
||||
AC_MSG_WARN([
|
||||
--with-default-path=PATH has no effect on this system.
|
||||
Edit /etc/login.conf instead.])
|
||||
elif test "x$withval" != "xno" ; then
|
||||
if test ! -z "$external_path_file" ; then
|
||||
AC_MSG_WARN([
|
||||
--with-default-path=PATH will only be used if PATH is not defined in
|
||||
$external_path_file .])
|
||||
fi
|
||||
user_path="$withval"
|
||||
SERVER_PATH_MSG="$withval"
|
||||
fi
|
||||
],
|
||||
[ if test "$USES_LOGIN_CONF" = "yes" ; then
|
||||
AC_MSG_WARN([Make sure the path to scp is in /etc/login.conf])
|
||||
[ if test "x$external_path_file" = "x/etc/login.conf" ; then
|
||||
AC_MSG_WARN([Make sure the path to scp is in /etc/login.conf])
|
||||
else
|
||||
AC_TRY_RUN(
|
||||
[
|
||||
if test ! -z "$external_path_file" ; then
|
||||
AC_MSG_WARN([
|
||||
If PATH is defined in $external_path_file, ensure the path to scp is included,
|
||||
otherwise scp will not work.])
|
||||
fi
|
||||
AC_TRY_RUN(
|
||||
[
|
||||
/* find out what STDPATH is */
|
||||
#include <stdio.h>
|
||||
#ifdef HAVE_PATHS_H
|
||||
@ -2202,7 +2353,7 @@ main()
|
||||
fi
|
||||
fi ]
|
||||
)
|
||||
if test "$USES_LOGIN_CONF" != "yes" ; then
|
||||
if test "x$external_path_file" != "x/etc/login.conf" ; then
|
||||
AC_DEFINE_UNQUOTED(USER_PATH, "$user_path")
|
||||
AC_SUBST(user_path)
|
||||
fi
|
||||
@ -2219,18 +2370,6 @@ AC_ARG_WITH(superuser-path,
|
||||
)
|
||||
|
||||
|
||||
# Whether to force IPv4 by default (needed on broken glibc Linux)
|
||||
IPV4_HACK_MSG="no"
|
||||
AC_ARG_WITH(ipv4-default,
|
||||
[ --with-ipv4-default Use IPv4 by connections unless '-6' specified],
|
||||
[
|
||||
if test "x$withval" != "xno" ; then
|
||||
AC_DEFINE(IPV4_DEFAULT)
|
||||
IPV4_HACK_MSG="yes"
|
||||
fi
|
||||
]
|
||||
)
|
||||
|
||||
AC_MSG_CHECKING([if we need to convert IPv4 in IPv6-mapped addresses])
|
||||
IPV4_IN6_HACK_MSG="no"
|
||||
AC_ARG_WITH(4in6,
|
||||
@ -2294,35 +2433,67 @@ AC_SUBST(piddir)
|
||||
dnl allow user to disable some login recording features
|
||||
AC_ARG_ENABLE(lastlog,
|
||||
[ --disable-lastlog disable use of lastlog even if detected [no]],
|
||||
[ AC_DEFINE(DISABLE_LASTLOG) ]
|
||||
[
|
||||
if test "x$enableval" = "xno" ; then
|
||||
AC_DEFINE(DISABLE_LASTLOG)
|
||||
fi
|
||||
]
|
||||
)
|
||||
AC_ARG_ENABLE(utmp,
|
||||
[ --disable-utmp disable use of utmp even if detected [no]],
|
||||
[ AC_DEFINE(DISABLE_UTMP) ]
|
||||
[
|
||||
if test "x$enableval" = "xno" ; then
|
||||
AC_DEFINE(DISABLE_UTMP)
|
||||
fi
|
||||
]
|
||||
)
|
||||
AC_ARG_ENABLE(utmpx,
|
||||
[ --disable-utmpx disable use of utmpx even if detected [no]],
|
||||
[ AC_DEFINE(DISABLE_UTMPX) ]
|
||||
[
|
||||
if test "x$enableval" = "xno" ; then
|
||||
AC_DEFINE(DISABLE_UTMPX)
|
||||
fi
|
||||
]
|
||||
)
|
||||
AC_ARG_ENABLE(wtmp,
|
||||
[ --disable-wtmp disable use of wtmp even if detected [no]],
|
||||
[ AC_DEFINE(DISABLE_WTMP) ]
|
||||
[
|
||||
if test "x$enableval" = "xno" ; then
|
||||
AC_DEFINE(DISABLE_WTMP)
|
||||
fi
|
||||
]
|
||||
)
|
||||
AC_ARG_ENABLE(wtmpx,
|
||||
[ --disable-wtmpx disable use of wtmpx even if detected [no]],
|
||||
[ AC_DEFINE(DISABLE_WTMPX) ]
|
||||
[
|
||||
if test "x$enableval" = "xno" ; then
|
||||
AC_DEFINE(DISABLE_WTMPX)
|
||||
fi
|
||||
]
|
||||
)
|
||||
AC_ARG_ENABLE(libutil,
|
||||
[ --disable-libutil disable use of libutil (login() etc.) [no]],
|
||||
[ AC_DEFINE(DISABLE_LOGIN) ]
|
||||
[
|
||||
if test "x$enableval" = "xno" ; then
|
||||
AC_DEFINE(DISABLE_LOGIN)
|
||||
fi
|
||||
]
|
||||
)
|
||||
AC_ARG_ENABLE(pututline,
|
||||
[ --disable-pututline disable use of pututline() etc. ([uw]tmp) [no]],
|
||||
[ AC_DEFINE(DISABLE_PUTUTLINE) ]
|
||||
[
|
||||
if test "x$enableval" = "xno" ; then
|
||||
AC_DEFINE(DISABLE_PUTUTLINE)
|
||||
fi
|
||||
]
|
||||
)
|
||||
AC_ARG_ENABLE(pututxline,
|
||||
[ --disable-pututxline disable use of pututxline() etc. ([uw]tmpx) [no]],
|
||||
[ AC_DEFINE(DISABLE_PUTUTXLINE) ]
|
||||
[
|
||||
if test "x$enableval" = "xno" ; then
|
||||
AC_DEFINE(DISABLE_PUTUTXLINE)
|
||||
fi
|
||||
]
|
||||
)
|
||||
AC_ARG_WITH(lastlog,
|
||||
[ --with-lastlog=FILE|DIR specify lastlog location [common locations]],
|
||||
@ -2513,8 +2684,8 @@ fi
|
||||
|
||||
|
||||
if test ! -z "$blibpath" ; then
|
||||
LDFLAGS="$LDFLAGS -blibpath:$blibpath"
|
||||
AC_MSG_WARN([Please check and edit -blibpath in LDFLAGS in Makefile])
|
||||
LDFLAGS="$LDFLAGS $blibflags$blibpath"
|
||||
AC_MSG_WARN([Please check and edit blibpath in LDFLAGS in Makefile])
|
||||
fi
|
||||
|
||||
dnl remove pam and dl because they are in $LIBPAM
|
||||
@ -2552,26 +2723,29 @@ echo " Askpass program: $E"
|
||||
echo " Manual pages: $F"
|
||||
echo " PID file: $G"
|
||||
echo " Privilege separation chroot path: $H"
|
||||
if test "$USES_LOGIN_CONF" = "yes" ; then
|
||||
echo " At runtime, sshd will use the path defined in /etc/login.conf"
|
||||
if test "x$external_path_file" = "x/etc/login.conf" ; then
|
||||
echo " At runtime, sshd will use the path defined in $external_path_file"
|
||||
echo " Make sure the path to scp is present, otherwise scp will not work"
|
||||
else
|
||||
echo " sshd default user PATH: $I"
|
||||
if test ! -z "$external_path_file"; then
|
||||
echo " (If PATH is set in $external_path_file it will be used instead. If"
|
||||
echo " used, ensure the path to scp is present, otherwise scp will not work.)"
|
||||
fi
|
||||
fi
|
||||
if test ! -z "$superuser_path" ; then
|
||||
echo " sshd superuser user PATH: $J"
|
||||
fi
|
||||
echo " Manpage format: $MANTYPE"
|
||||
echo " PAM support: ${PAM_MSG}"
|
||||
echo " KerberosIV support: $KRB4_MSG"
|
||||
echo " DNS support: $DNS_MSG"
|
||||
echo " PAM support: $PAM_MSG"
|
||||
echo " KerberosV support: $KRB5_MSG"
|
||||
echo " Smartcard support: $SCARD_MSG"
|
||||
echo " AFS support: $AFS_MSG"
|
||||
echo " S/KEY support: $SKEY_MSG"
|
||||
echo " OPIE support: $OPIE_MSG"
|
||||
echo " TCP Wrappers support: $TCPW_MSG"
|
||||
echo " MD5 password support: $MD5_MSG"
|
||||
echo " IP address in \$DISPLAY hack: $DISPLAY_HACK_MSG"
|
||||
echo " Use IPv4 by default hack: $IPV4_HACK_MSG"
|
||||
echo " Translate v4 in v6 hack: $IPV4_IN6_HACK_MSG"
|
||||
echo " BSD Auth support: $BSD_AUTH_MSG"
|
||||
echo " Random number source: $RAND_MSG"
|
||||
|
@ -36,7 +36,7 @@
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: hostfile.c,v 1.30 2002/07/24 16:11:18 markus Exp $");
|
||||
RCSID("$OpenBSD: hostfile.c,v 1.31 2003/04/08 20:21:28 itojun Exp $");
|
||||
|
||||
#include "packet.h"
|
||||
#include "match.h"
|
||||
@ -77,10 +77,10 @@ hostfile_check_key(int bits, Key *key, const char *host, const char *filename, i
|
||||
if (key == NULL || key->type != KEY_RSA1 || key->rsa == NULL)
|
||||
return 1;
|
||||
if (bits != BN_num_bits(key->rsa->n)) {
|
||||
log("Warning: %s, line %d: keysize mismatch for host %s: "
|
||||
logit("Warning: %s, line %d: keysize mismatch for host %s: "
|
||||
"actual %d vs. announced %d.",
|
||||
filename, linenum, host, BN_num_bits(key->rsa->n), bits);
|
||||
log("Warning: replace %d with %d in %s, line %d.",
|
||||
logit("Warning: replace %d with %d in %s, line %d.",
|
||||
bits, BN_num_bits(key->rsa->n), filename, linenum);
|
||||
}
|
||||
return 1;
|
||||
|
@ -51,9 +51,6 @@ __RCSID(msg)
|
||||
#ifdef HAVE_NETGROUP_H
|
||||
# include <netgroup.h>
|
||||
#endif
|
||||
#if defined(HAVE_NETDB_H)
|
||||
# include <netdb.h>
|
||||
#endif
|
||||
#ifdef HAVE_ENDIAN_H
|
||||
# include <endian.h>
|
||||
#endif
|
||||
@ -69,6 +66,7 @@ __RCSID(msg)
|
||||
#ifdef HAVE_NEXT
|
||||
# include <libc.h>
|
||||
#endif
|
||||
#define __USE_GNU /* before unistd.h, activate extra prototypes for glibc */
|
||||
#include <unistd.h> /* For STDIN_FILENO, etc */
|
||||
#include <termios.h> /* Struct winsize */
|
||||
|
||||
@ -134,12 +132,18 @@ __RCSID(msg)
|
||||
#ifdef HAVE_SYS_MMAN_H
|
||||
#include <sys/mman.h> /* for MAP_ANONYMOUS */
|
||||
#endif
|
||||
#ifdef HAVE_SYS_STRTIO_H
|
||||
#include <sys/strtio.h> /* for TIOCCBRK on HP-UX */
|
||||
#endif
|
||||
|
||||
#include <netinet/in_systm.h> /* For typedefs */
|
||||
#include <netinet/in.h> /* For IPv6 macros */
|
||||
#include <netinet/ip.h> /* For IPTOS macros */
|
||||
#include <netinet/tcp.h>
|
||||
#include <arpa/inet.h>
|
||||
#if defined(HAVE_NETDB_H)
|
||||
# include <netdb.h>
|
||||
#endif
|
||||
#ifdef HAVE_RPC_TYPES_H
|
||||
# include <rpc/types.h> /* For INADDR_LOOPBACK */
|
||||
#endif
|
||||
@ -168,7 +172,6 @@ __RCSID(msg)
|
||||
|
||||
#include "version.h"
|
||||
#include "openbsd-compat/openbsd-compat.h"
|
||||
#include "openbsd-compat/bsd-cygwin_util.h"
|
||||
#include "openbsd-compat/bsd-nextstep.h"
|
||||
|
||||
#include "entropy.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.51 2003/02/12 09:33:04 markus Exp $");
|
||||
RCSID("$OpenBSD: key.c,v 1.54 2003/07/09 13:58:19 avsm Exp $");
|
||||
|
||||
#include <openssl/evp.h>
|
||||
|
||||
@ -169,7 +169,7 @@ key_equal(Key *a, Key *b)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u_char *
|
||||
u_char*
|
||||
key_fingerprint_raw(Key *k, enum fp_type dgst_type, u_int *dgst_raw_length)
|
||||
{
|
||||
const EVP_MD *md = NULL;
|
||||
@ -236,8 +236,10 @@ key_fingerprint_hex(u_char *dgst_raw, u_int dgst_raw_len)
|
||||
for (i = 0; i < dgst_raw_len; i++) {
|
||||
char hex[4];
|
||||
snprintf(hex, sizeof(hex), "%02x:", dgst_raw[i]);
|
||||
strlcat(retval, hex, dgst_raw_len * 3);
|
||||
strlcat(retval, hex, dgst_raw_len * 3 + 1);
|
||||
}
|
||||
|
||||
/* Remove the trailing ':' character */
|
||||
retval[(dgst_raw_len * 3) - 1] = '\0';
|
||||
return retval;
|
||||
}
|
||||
@ -438,7 +440,7 @@ key_read(Key *ret, char **cpp)
|
||||
xfree(blob);
|
||||
return -1;
|
||||
}
|
||||
k = key_from_blob(blob, n);
|
||||
k = key_from_blob(blob, (u_int)n);
|
||||
xfree(blob);
|
||||
if (k == NULL) {
|
||||
error("key_read: key_from_blob %s failed", cp);
|
||||
@ -674,7 +676,7 @@ key_names_valid2(const char *names)
|
||||
}
|
||||
|
||||
Key *
|
||||
key_from_blob(u_char *blob, int blen)
|
||||
key_from_blob(u_char *blob, u_int blen)
|
||||
{
|
||||
Buffer b;
|
||||
char *ktype;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: log.h,v 1.8 2002/07/19 15:43:33 markus Exp $ */
|
||||
/* $OpenBSD: log.h,v 1.9 2003/04/08 20:21:28 itojun Exp $ */
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/*
|
||||
@ -56,7 +56,7 @@ LogLevel log_level_number(char *);
|
||||
|
||||
#define fatal ssh_fatal
|
||||
#define error ssh_error
|
||||
#define log ssh_log
|
||||
#define logit ssh_logit
|
||||
#define verbose ssh_verbose
|
||||
#define debug ssh_debug
|
||||
#define debug2 ssh_debug2
|
||||
@ -64,7 +64,7 @@ LogLevel log_level_number(char *);
|
||||
|
||||
void fatal(const char *, ...) __attribute__((format(printf, 1, 2)));
|
||||
void error(const char *, ...) __attribute__((format(printf, 1, 2)));
|
||||
void log(const char *, ...) __attribute__((format(printf, 1, 2)));
|
||||
void logit(const char *, ...) __attribute__((format(printf, 1, 2)));
|
||||
void verbose(const char *, ...) __attribute__((format(printf, 1, 2)));
|
||||
void debug(const char *, ...) __attribute__((format(printf, 1, 2)));
|
||||
void debug2(const char *, ...) __attribute__((format(printf, 1, 2)));
|
||||
|
@ -12,11 +12,6 @@
|
||||
* 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.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Markus Friedl.
|
||||
* 4. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
@ -163,7 +158,7 @@
|
||||
#include "log.h"
|
||||
#include "atomicio.h"
|
||||
|
||||
RCSID("$Id: loginrec.c,v 1.47 2003/03/10 00:23:07 djm Exp $");
|
||||
RCSID("$Id: loginrec.c,v 1.52 2003/07/06 05:20:46 dtucker Exp $");
|
||||
RCSID("$FreeBSD$");
|
||||
|
||||
#ifdef HAVE_UTIL_H
|
||||
@ -414,7 +409,7 @@ login_write (struct logininfo *li)
|
||||
{
|
||||
#ifndef HAVE_CYGWIN
|
||||
if ((int)geteuid() != 0) {
|
||||
log("Attempt to write login records by non-root user (aborting)");
|
||||
logit("Attempt to write login records by non-root user (aborting)");
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
@ -820,7 +815,7 @@ utmp_write_direct(struct logininfo *li, struct utmp *ut)
|
||||
endttyent();
|
||||
|
||||
if((struct ttyent *)0 == ty) {
|
||||
log("utmp_write_entry: tty not found");
|
||||
logit("utmp_write_entry: tty not found");
|
||||
return(1);
|
||||
}
|
||||
#else /* FIXME */
|
||||
@ -844,8 +839,8 @@ utmp_write_direct(struct logininfo *li, struct utmp *ut)
|
||||
}
|
||||
|
||||
(void)lseek(fd, (off_t)(tty * sizeof(struct utmp)), SEEK_SET);
|
||||
if (atomicio(write, fd, ut, sizeof(*ut)) != sizeof(*ut))
|
||||
log("utmp_write_direct: error writing %s: %s",
|
||||
if (atomicio(vwrite, fd, ut, sizeof(*ut)) != sizeof(*ut))
|
||||
logit("utmp_write_direct: error writing %s: %s",
|
||||
UTMP_FILE, strerror(errno));
|
||||
|
||||
(void)close(fd);
|
||||
@ -864,12 +859,12 @@ utmp_perform_login(struct logininfo *li)
|
||||
construct_utmp(li, &ut);
|
||||
# ifdef UTMP_USE_LIBRARY
|
||||
if (!utmp_write_library(li, &ut)) {
|
||||
log("utmp_perform_login: utmp_write_library() failed");
|
||||
logit("utmp_perform_login: utmp_write_library() failed");
|
||||
return 0;
|
||||
}
|
||||
# else
|
||||
if (!utmp_write_direct(li, &ut)) {
|
||||
log("utmp_perform_login: utmp_write_direct() failed");
|
||||
logit("utmp_perform_login: utmp_write_direct() failed");
|
||||
return 0;
|
||||
}
|
||||
# endif
|
||||
@ -885,12 +880,12 @@ utmp_perform_logout(struct logininfo *li)
|
||||
construct_utmp(li, &ut);
|
||||
# ifdef UTMP_USE_LIBRARY
|
||||
if (!utmp_write_library(li, &ut)) {
|
||||
log("utmp_perform_logout: utmp_write_library() failed");
|
||||
logit("utmp_perform_logout: utmp_write_library() failed");
|
||||
return 0;
|
||||
}
|
||||
# else
|
||||
if (!utmp_write_direct(li, &ut)) {
|
||||
log("utmp_perform_logout: utmp_write_direct() failed");
|
||||
logit("utmp_perform_logout: utmp_write_direct() failed");
|
||||
return 0;
|
||||
}
|
||||
# endif
|
||||
@ -909,7 +904,7 @@ utmp_write_entry(struct logininfo *li)
|
||||
return utmp_perform_logout(li);
|
||||
|
||||
default:
|
||||
log("utmp_write_entry: invalid type field");
|
||||
logit("utmp_write_entry: invalid type field");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -950,7 +945,7 @@ utmpx_write_library(struct logininfo *li, struct utmpx *utx)
|
||||
static int
|
||||
utmpx_write_direct(struct logininfo *li, struct utmpx *utx)
|
||||
{
|
||||
log("utmpx_write_direct: not implemented!");
|
||||
logit("utmpx_write_direct: not implemented!");
|
||||
return 0;
|
||||
}
|
||||
# endif /* UTMPX_USE_LIBRARY */
|
||||
@ -963,12 +958,12 @@ utmpx_perform_login(struct logininfo *li)
|
||||
construct_utmpx(li, &utx);
|
||||
# ifdef UTMPX_USE_LIBRARY
|
||||
if (!utmpx_write_library(li, &utx)) {
|
||||
log("utmpx_perform_login: utmp_write_library() failed");
|
||||
logit("utmpx_perform_login: utmp_write_library() failed");
|
||||
return 0;
|
||||
}
|
||||
# else
|
||||
if (!utmpx_write_direct(li, &ut)) {
|
||||
log("utmpx_perform_login: utmp_write_direct() failed");
|
||||
logit("utmpx_perform_login: utmp_write_direct() failed");
|
||||
return 0;
|
||||
}
|
||||
# endif
|
||||
@ -1006,7 +1001,7 @@ utmpx_write_entry(struct logininfo *li)
|
||||
case LTYPE_LOGOUT:
|
||||
return utmpx_perform_logout(li);
|
||||
default:
|
||||
log("utmpx_write_entry: invalid type field");
|
||||
logit("utmpx_write_entry: invalid type field");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -1028,14 +1023,14 @@ wtmp_write(struct logininfo *li, struct utmp *ut)
|
||||
int fd, ret = 1;
|
||||
|
||||
if ((fd = open(WTMP_FILE, O_WRONLY|O_APPEND, 0)) < 0) {
|
||||
log("wtmp_write: problem writing %s: %s",
|
||||
logit("wtmp_write: problem writing %s: %s",
|
||||
WTMP_FILE, strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
if (fstat(fd, &buf) == 0)
|
||||
if (atomicio(write, fd, ut, sizeof(*ut)) != sizeof(*ut)) {
|
||||
if (atomicio(vwrite, fd, ut, sizeof(*ut)) != sizeof(*ut)) {
|
||||
ftruncate(fd, buf.st_size);
|
||||
log("wtmp_write: problem writing %s: %s",
|
||||
logit("wtmp_write: problem writing %s: %s",
|
||||
WTMP_FILE, strerror(errno));
|
||||
ret = 0;
|
||||
}
|
||||
@ -1072,7 +1067,7 @@ wtmp_write_entry(struct logininfo *li)
|
||||
case LTYPE_LOGOUT:
|
||||
return wtmp_perform_logout(li);
|
||||
default:
|
||||
log("wtmp_write_entry: invalid type field");
|
||||
logit("wtmp_write_entry: invalid type field");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -1121,12 +1116,12 @@ wtmp_get_entry(struct logininfo *li)
|
||||
li->tv_sec = li->tv_usec = 0;
|
||||
|
||||
if ((fd = open(WTMP_FILE, O_RDONLY)) < 0) {
|
||||
log("wtmp_get_entry: problem opening %s: %s",
|
||||
logit("wtmp_get_entry: problem opening %s: %s",
|
||||
WTMP_FILE, strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
if (fstat(fd, &st) != 0) {
|
||||
log("wtmp_get_entry: couldn't stat %s: %s",
|
||||
logit("wtmp_get_entry: couldn't stat %s: %s",
|
||||
WTMP_FILE, strerror(errno));
|
||||
close(fd);
|
||||
return 0;
|
||||
@ -1141,7 +1136,7 @@ wtmp_get_entry(struct logininfo *li)
|
||||
|
||||
while (!found) {
|
||||
if (atomicio(read, fd, &ut, sizeof(ut)) != sizeof(ut)) {
|
||||
log("wtmp_get_entry: read of %s failed: %s",
|
||||
logit("wtmp_get_entry: read of %s failed: %s",
|
||||
WTMP_FILE, strerror(errno));
|
||||
close (fd);
|
||||
return 0;
|
||||
@ -1194,15 +1189,15 @@ wtmpx_write(struct logininfo *li, struct utmpx *utx)
|
||||
int fd, ret = 1;
|
||||
|
||||
if ((fd = open(WTMPX_FILE, O_WRONLY|O_APPEND, 0)) < 0) {
|
||||
log("wtmpx_write: problem opening %s: %s",
|
||||
logit("wtmpx_write: problem opening %s: %s",
|
||||
WTMPX_FILE, strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (fstat(fd, &buf) == 0)
|
||||
if (atomicio(write, fd, utx, sizeof(*utx)) != sizeof(*utx)) {
|
||||
if (atomicio(vwrite, fd, utx, sizeof(*utx)) != sizeof(*utx)) {
|
||||
ftruncate(fd, buf.st_size);
|
||||
log("wtmpx_write: problem writing %s: %s",
|
||||
logit("wtmpx_write: problem writing %s: %s",
|
||||
WTMPX_FILE, strerror(errno));
|
||||
ret = 0;
|
||||
}
|
||||
@ -1241,7 +1236,7 @@ wtmpx_write_entry(struct logininfo *li)
|
||||
case LTYPE_LOGOUT:
|
||||
return wtmpx_perform_logout(li);
|
||||
default:
|
||||
log("wtmpx_write_entry: invalid type field");
|
||||
logit("wtmpx_write_entry: invalid type field");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -1277,12 +1272,12 @@ wtmpx_get_entry(struct logininfo *li)
|
||||
li->tv_sec = li->tv_usec = 0;
|
||||
|
||||
if ((fd = open(WTMPX_FILE, O_RDONLY)) < 0) {
|
||||
log("wtmpx_get_entry: problem opening %s: %s",
|
||||
logit("wtmpx_get_entry: problem opening %s: %s",
|
||||
WTMPX_FILE, strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
if (fstat(fd, &st) != 0) {
|
||||
log("wtmpx_get_entry: couldn't stat %s: %s",
|
||||
logit("wtmpx_get_entry: couldn't stat %s: %s",
|
||||
WTMPX_FILE, strerror(errno));
|
||||
close(fd);
|
||||
return 0;
|
||||
@ -1297,7 +1292,7 @@ wtmpx_get_entry(struct logininfo *li)
|
||||
|
||||
while (!found) {
|
||||
if (atomicio(read, fd, &utx, sizeof(utx)) != sizeof(utx)) {
|
||||
log("wtmpx_get_entry: read of %s failed: %s",
|
||||
logit("wtmpx_get_entry: read of %s failed: %s",
|
||||
WTMPX_FILE, strerror(errno));
|
||||
close (fd);
|
||||
return 0;
|
||||
@ -1342,7 +1337,7 @@ syslogin_perform_login(struct logininfo *li)
|
||||
struct utmp *ut;
|
||||
|
||||
if (! (ut = (struct utmp *)malloc(sizeof(*ut)))) {
|
||||
log("syslogin_perform_login: couldn't malloc()");
|
||||
logit("syslogin_perform_login: couldn't malloc()");
|
||||
return 0;
|
||||
}
|
||||
construct_utmp(li, ut);
|
||||
@ -1361,7 +1356,7 @@ syslogin_perform_logout(struct logininfo *li)
|
||||
(void)line_stripname(line, li->line, sizeof(line));
|
||||
|
||||
if (!logout(line)) {
|
||||
log("syslogin_perform_logout: logout() returned an error");
|
||||
logit("syslogin_perform_logout: logout() returned an error");
|
||||
# ifdef HAVE_LOGWTMP
|
||||
} else {
|
||||
logwtmp(line, "", "");
|
||||
@ -1384,7 +1379,7 @@ syslogin_write_entry(struct logininfo *li)
|
||||
case LTYPE_LOGOUT:
|
||||
return syslogin_perform_logout(li);
|
||||
default:
|
||||
log("syslogin_write_entry: Invalid type field");
|
||||
logit("syslogin_write_entry: Invalid type field");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -1419,7 +1414,7 @@ lastlog_filetype(char *filename)
|
||||
struct stat st;
|
||||
|
||||
if (stat(LASTLOG_FILE, &st) != 0) {
|
||||
log("lastlog_perform_login: Couldn't stat %s: %s", LASTLOG_FILE,
|
||||
logit("lastlog_perform_login: Couldn't stat %s: %s", LASTLOG_FILE,
|
||||
strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
@ -1450,12 +1445,12 @@ lastlog_openseek(struct logininfo *li, int *fd, int filemode)
|
||||
LASTLOG_FILE, li->username);
|
||||
break;
|
||||
default:
|
||||
log("lastlog_openseek: %.100s is not a file or directory!",
|
||||
logit("lastlog_openseek: %.100s is not a file or directory!",
|
||||
LASTLOG_FILE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
*fd = open(lastlog_file, filemode);
|
||||
*fd = open(lastlog_file, filemode, 0600);
|
||||
if ( *fd < 0) {
|
||||
debug("lastlog_openseek: Couldn't open %s: %s",
|
||||
lastlog_file, strerror(errno));
|
||||
@ -1467,7 +1462,7 @@ lastlog_openseek(struct logininfo *li, int *fd, int filemode)
|
||||
offset = (off_t) ((long)li->uid * sizeof(struct lastlog));
|
||||
|
||||
if ( lseek(*fd, offset, SEEK_SET) != offset ) {
|
||||
log("lastlog_openseek: %s->lseek(): %s",
|
||||
logit("lastlog_openseek: %s->lseek(): %s",
|
||||
lastlog_file, strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
@ -1489,9 +1484,9 @@ lastlog_perform_login(struct logininfo *li)
|
||||
return(0);
|
||||
|
||||
/* write the entry */
|
||||
if (atomicio(write, fd, &last, sizeof(last)) != sizeof(last)) {
|
||||
if (atomicio(vwrite, fd, &last, sizeof(last)) != sizeof(last)) {
|
||||
close(fd);
|
||||
log("lastlog_write_filemode: Error writing to %s: %s",
|
||||
logit("lastlog_write_filemode: Error writing to %s: %s",
|
||||
LASTLOG_FILE, strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
@ -1507,7 +1502,7 @@ lastlog_write_entry(struct logininfo *li)
|
||||
case LTYPE_LOGIN:
|
||||
return lastlog_perform_login(li);
|
||||
default:
|
||||
log("lastlog_write_entry: Invalid type field");
|
||||
logit("lastlog_write_entry: Invalid type field");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -1,592 +0,0 @@
|
||||
#!/usr/bin/perl
|
||||
###
|
||||
### Quick usage: mdoc2man.pl < mdoc_manpage.8 > man_manpage.8
|
||||
###
|
||||
###
|
||||
### Copyright (c) 2001 University of Illinois Board of Trustees
|
||||
### Copyright (c) 2001 Mark D. Roth
|
||||
### 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.
|
||||
### 3. All advertising materials mentioning features or use of this software
|
||||
### must display the following acknowledgement:
|
||||
### This product includes software developed by the University of
|
||||
### Illinois at Urbana, and their contributors.
|
||||
### 4. The University nor the names of their
|
||||
### contributors may be used to endorse or promote products derived from
|
||||
### this software without specific prior written permission.
|
||||
###
|
||||
### THIS SOFTWARE IS PROVIDED BY THE TRUSTEES AND CONTRIBUTORS ``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 TRUSTEES OR CONTRIBUTORS 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.
|
||||
###
|
||||
|
||||
use strict;
|
||||
|
||||
my ($name, $date, $id);
|
||||
my ($line);
|
||||
my ($optlist, $oldoptlist, $nospace, $enum, $synopsis);
|
||||
my ($reference, $block, $ext, $extopt, $literal);
|
||||
my (@refauthors, $reftitle, $refissue, $refdate, $refopt);
|
||||
|
||||
|
||||
$optlist = 0; ### 1 = bullet, 2 = enum, 3 = tag, 4 = item
|
||||
$oldoptlist = 0;
|
||||
$nospace = 0;
|
||||
$synopsis = 0;
|
||||
$reference = 0;
|
||||
$block = 0;
|
||||
$ext = 0;
|
||||
$extopt = 0;
|
||||
$literal = 0;
|
||||
|
||||
while ($line = <STDIN>)
|
||||
{
|
||||
if ($line !~ /^\./)
|
||||
{
|
||||
print $line;
|
||||
print ".br\n"
|
||||
if ($literal);
|
||||
next;
|
||||
}
|
||||
|
||||
$line =~ s/^\.//;
|
||||
|
||||
next
|
||||
if ($line =~ m/\\"/);
|
||||
|
||||
$line = ParseMacro($line);
|
||||
print($line)
|
||||
if (defined $line);
|
||||
}
|
||||
|
||||
|
||||
|
||||
sub ParseMacro # ($line)
|
||||
{
|
||||
my ($line) = @_;
|
||||
my (@words, $retval, $option, $parens);
|
||||
|
||||
@words = split(/\s+/, $line);
|
||||
$retval = '';
|
||||
$option = 0;
|
||||
$parens = 0;
|
||||
|
||||
# print('@words = ', scalar(@words), ': ', join(' ', @words), "\n");
|
||||
|
||||
while ($_ = shift @words)
|
||||
{
|
||||
# print "WORD: $_\n";
|
||||
|
||||
next
|
||||
if (/^(Li|Pf)$/);
|
||||
|
||||
if (/^Xo$/)
|
||||
{
|
||||
$ext = 1;
|
||||
$retval .= ' '
|
||||
if ($retval ne '' && $retval !~ m/[\n ]$/);
|
||||
next;
|
||||
}
|
||||
|
||||
if (/^Xc$/)
|
||||
{
|
||||
$ext = 0;
|
||||
$retval .= "\n"
|
||||
if (! $extopt);
|
||||
last;
|
||||
}
|
||||
|
||||
if (/^Bd$/)
|
||||
{
|
||||
$literal = 1
|
||||
if ($words[0] eq '-literal');
|
||||
$retval .= "\n";
|
||||
last;
|
||||
}
|
||||
|
||||
if (/^Ed$/)
|
||||
{
|
||||
$literal = 0;
|
||||
last;
|
||||
}
|
||||
|
||||
if (/^Ns$/)
|
||||
{
|
||||
$nospace = 1
|
||||
if (! $nospace);
|
||||
$retval =~ s/ $//;
|
||||
next;
|
||||
}
|
||||
|
||||
if (/^No$/)
|
||||
{
|
||||
$retval =~ s/ $//;
|
||||
$retval .= shift @words;
|
||||
next;
|
||||
}
|
||||
|
||||
if (/^Dq$/)
|
||||
{
|
||||
$retval .= '``';
|
||||
do
|
||||
{
|
||||
$retval .= (shift @words) . ' ';
|
||||
}
|
||||
while (@words > 0 && $words[0] !~ m/^[\.,]/);
|
||||
$retval =~ s/ $//;
|
||||
$retval .= '\'\'';
|
||||
$nospace = 1
|
||||
if (! $nospace && $words[0] =~ m/^[\.,]/);
|
||||
next;
|
||||
}
|
||||
|
||||
if (/^(Sq|Ql)$/)
|
||||
{
|
||||
$retval .= '`' . (shift @words) . '\'';
|
||||
$nospace = 1
|
||||
if (! $nospace && $words[0] =~ m/^[\.,]/);
|
||||
next;
|
||||
}
|
||||
|
||||
# if (/^Ic$/)
|
||||
# {
|
||||
# $retval .= '\\fB' . shift(@words) . '\\fP';
|
||||
# next;
|
||||
# }
|
||||
|
||||
if (/^Oo$/)
|
||||
{
|
||||
# $retval .= "[\\c\n";
|
||||
$extopt = 1;
|
||||
$nospace = 1
|
||||
if (! $nospace);
|
||||
$retval .= '[';
|
||||
next;
|
||||
}
|
||||
|
||||
if (/^Oc$/)
|
||||
{
|
||||
$extopt = 0;
|
||||
$retval .= ']';
|
||||
next;
|
||||
}
|
||||
|
||||
$retval .= ' '
|
||||
if (! $nospace && $retval ne '' && $retval !~ m/[\n ]$/);
|
||||
$nospace = 0
|
||||
if ($nospace == 1);
|
||||
|
||||
if (/^Dd$/)
|
||||
{
|
||||
$date = join(' ', @words);
|
||||
return undef;
|
||||
}
|
||||
|
||||
if (/^Dt$/)
|
||||
{
|
||||
$id = join(' ', @words);
|
||||
return undef;
|
||||
}
|
||||
|
||||
if (/^Os$/)
|
||||
{
|
||||
$retval .= '.TH '
|
||||
. $id
|
||||
. " \"$date\" \""
|
||||
. join(' ', @words)
|
||||
. "\"";
|
||||
last;
|
||||
}
|
||||
|
||||
if (/^Sh$/)
|
||||
{
|
||||
$retval .= '.SH';
|
||||
if ($words[0] eq 'SYNOPSIS')
|
||||
{
|
||||
$synopsis = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
$synopsis = 0;
|
||||
}
|
||||
next;
|
||||
}
|
||||
|
||||
if (/^Xr$/)
|
||||
{
|
||||
$retval .= '\\fB' . (shift @words) .
|
||||
'\\fP(' . (shift @words) . ')'
|
||||
. (shift @words);
|
||||
last;
|
||||
}
|
||||
|
||||
if (/^Rs/)
|
||||
{
|
||||
@refauthors = ();
|
||||
$reftitle = '';
|
||||
$refissue = '';
|
||||
$refdate = '';
|
||||
$refopt = '';
|
||||
$reference = 1;
|
||||
last;
|
||||
}
|
||||
|
||||
if (/^Re/)
|
||||
{
|
||||
$retval .= "\n";
|
||||
|
||||
# authors
|
||||
while (scalar(@refauthors) > 1)
|
||||
{
|
||||
$retval .= shift(@refauthors) . ', ';
|
||||
}
|
||||
$retval .= 'and '
|
||||
if ($retval ne '');
|
||||
$retval .= shift(@refauthors);
|
||||
|
||||
# title
|
||||
$retval .= ', \\fI' . $reftitle . '\\fP';
|
||||
|
||||
# issue
|
||||
$retval .= ', ' . $refissue
|
||||
if ($refissue ne '');
|
||||
|
||||
# date
|
||||
$retval .= ', ' . $refdate
|
||||
if ($refdate ne '');
|
||||
|
||||
# optional info
|
||||
$retval .= ', ' . $refopt
|
||||
if ($refopt ne '');
|
||||
|
||||
$retval .= ".\n";
|
||||
|
||||
$reference = 0;
|
||||
last;
|
||||
}
|
||||
|
||||
if ($reference)
|
||||
{
|
||||
if (/^%A$/)
|
||||
{
|
||||
unshift(@refauthors, join(' ', @words));
|
||||
last;
|
||||
}
|
||||
|
||||
if (/^%T$/)
|
||||
{
|
||||
$reftitle = join(' ', @words);
|
||||
$reftitle =~ s/^"//;
|
||||
$reftitle =~ s/"$//;
|
||||
last;
|
||||
}
|
||||
|
||||
if (/^%N$/)
|
||||
{
|
||||
$refissue = join(' ', @words);
|
||||
last;
|
||||
}
|
||||
|
||||
if (/^%D$/)
|
||||
{
|
||||
$refdate = join(' ', @words);
|
||||
last;
|
||||
}
|
||||
|
||||
if (/^%O$/)
|
||||
{
|
||||
$refopt = join(' ', @words);
|
||||
last;
|
||||
}
|
||||
}
|
||||
|
||||
if (/^Nm$/)
|
||||
{
|
||||
my $n = $name;
|
||||
$n = shift @words
|
||||
if (@words > 0);
|
||||
$name = $n unless $name;
|
||||
$retval .= ".br\n"
|
||||
if ($synopsis);
|
||||
$retval .= "\\fB$n\\fP";
|
||||
$nospace = 1
|
||||
if (! $nospace && $words[0] =~ m/^[\.,]/);
|
||||
next;
|
||||
}
|
||||
|
||||
if (/^Nd$/)
|
||||
{
|
||||
$retval .= '\\-';
|
||||
next;
|
||||
}
|
||||
|
||||
if (/^Fl$/)
|
||||
{
|
||||
$retval .= '\\fB\\-' . (shift @words) . '\\fP';
|
||||
$nospace = 1
|
||||
if (! $nospace && $words[0] =~ m/^[\.,]/);
|
||||
next;
|
||||
}
|
||||
|
||||
if (/^Ar$/)
|
||||
{
|
||||
$retval .= '\\fI';
|
||||
if (! defined $words[0])
|
||||
{
|
||||
$retval .= 'file ...\\fP';
|
||||
}
|
||||
else
|
||||
{
|
||||
$retval .= shift(@words) . '\\fP';
|
||||
while ($words[0] eq '|')
|
||||
{
|
||||
$retval .= ' ' . shift(@words);
|
||||
$retval .= ' \\fI' . shift(@words);
|
||||
$retval .= '\\fP';
|
||||
}
|
||||
}
|
||||
$nospace = 1
|
||||
if (! $nospace && $words[0] =~ m/^[\.,]/);
|
||||
next;
|
||||
}
|
||||
|
||||
if (/^Cm$/)
|
||||
{
|
||||
$retval .= '\\fB' . (shift @words) . '\\fP';
|
||||
while ($words[0] =~ m/^[\.,:)]$/)
|
||||
{
|
||||
$retval .= shift(@words);
|
||||
}
|
||||
next;
|
||||
}
|
||||
|
||||
if (/^Op$/)
|
||||
{
|
||||
$option = 1;
|
||||
$nospace = 1
|
||||
if (! $nospace);
|
||||
$retval .= '[';
|
||||
# my $tmp = pop(@words);
|
||||
# $tmp .= ']';
|
||||
# push(@words, $tmp);
|
||||
next;
|
||||
}
|
||||
|
||||
if (/^Pp$/)
|
||||
{
|
||||
$retval .= "\n";
|
||||
next;
|
||||
}
|
||||
|
||||
if (/^Ss$/)
|
||||
{
|
||||
$retval .= '.SS';
|
||||
next;
|
||||
}
|
||||
|
||||
if (/^Pa$/ && ! $option)
|
||||
{
|
||||
$retval .= '\\fI';
|
||||
$retval .= '\\&'
|
||||
if ($words[0] =~ m/^\./);
|
||||
$retval .= (shift @words) . '\\fP';
|
||||
while ($words[0] =~ m/^[\.,:;)]$/)
|
||||
{
|
||||
$retval .= shift(@words);
|
||||
}
|
||||
# $nospace = 1
|
||||
# if (! $nospace && $words[0] =~ m/^[\.,:)]/);
|
||||
next;
|
||||
}
|
||||
|
||||
if (/^Dv$/)
|
||||
{
|
||||
$retval .= '.BR';
|
||||
next;
|
||||
}
|
||||
|
||||
if (/^(Em|Ev)$/)
|
||||
{
|
||||
$retval .= '.IR';
|
||||
next;
|
||||
}
|
||||
|
||||
if (/^Pq$/)
|
||||
{
|
||||
$retval .= '(';
|
||||
$nospace = 1;
|
||||
$parens = 1;
|
||||
next;
|
||||
}
|
||||
|
||||
if (/^(S[xy])$/)
|
||||
{
|
||||
$retval .= '.B ' . join(' ', @words);
|
||||
last;
|
||||
}
|
||||
|
||||
if (/^Ic$/)
|
||||
{
|
||||
$retval .= '\\fB';
|
||||
while (defined $words[0]
|
||||
&& $words[0] !~ m/^[\.,]/)
|
||||
{
|
||||
if ($words[0] eq 'Op')
|
||||
{
|
||||
shift(@words);
|
||||
$retval .= '[';
|
||||
my $tmp = pop(@words);
|
||||
$tmp .= ']';
|
||||
push(@words, $tmp);
|
||||
next;
|
||||
}
|
||||
if ($words[0] eq 'Ar')
|
||||
{
|
||||
shift @words;
|
||||
$retval .= '\\fI';
|
||||
$retval .= shift @words;
|
||||
$retval .= '\\fP';
|
||||
}
|
||||
else
|
||||
{
|
||||
$retval .= shift @words;
|
||||
}
|
||||
$retval .= ' '
|
||||
if (! $nospace);
|
||||
}
|
||||
$retval =~ s/ $//;
|
||||
$retval .= '\\fP';
|
||||
$retval .= shift @words
|
||||
if (defined $words[0]);
|
||||
last;
|
||||
}
|
||||
|
||||
if (/^Bl$/)
|
||||
{
|
||||
$oldoptlist = $optlist;
|
||||
if ($words[0] eq '-bullet')
|
||||
{
|
||||
$optlist = 1;
|
||||
}
|
||||
elsif ($words[0] eq '-enum')
|
||||
{
|
||||
$optlist = 2;
|
||||
$enum = 0;
|
||||
}
|
||||
elsif ($words[0] eq '-tag')
|
||||
{
|
||||
$optlist = 3;
|
||||
}
|
||||
elsif ($words[0] eq '-item')
|
||||
{
|
||||
$optlist = 4;
|
||||
}
|
||||
last;
|
||||
}
|
||||
|
||||
if (/^El$/)
|
||||
{
|
||||
$optlist = $oldoptlist;
|
||||
next;
|
||||
}
|
||||
|
||||
if ($optlist && /^It$/)
|
||||
{
|
||||
if ($optlist == 1)
|
||||
{
|
||||
# bullets
|
||||
$retval .= '.IP \\(bu';
|
||||
next;
|
||||
}
|
||||
|
||||
if ($optlist == 2)
|
||||
{
|
||||
# enum
|
||||
$retval .= '.IP ' . (++$enum) . '.';
|
||||
next;
|
||||
}
|
||||
|
||||
if ($optlist == 3)
|
||||
{
|
||||
# tags
|
||||
$retval .= ".TP\n";
|
||||
if ($words[0] =~ m/^(Pa|Ev)$/)
|
||||
{
|
||||
shift @words;
|
||||
$retval .= '.B';
|
||||
}
|
||||
next;
|
||||
}
|
||||
|
||||
if ($optlist == 4)
|
||||
{
|
||||
# item
|
||||
$retval .= ".IP\n";
|
||||
next;
|
||||
}
|
||||
|
||||
next;
|
||||
}
|
||||
|
||||
if (/^Sm$/)
|
||||
{
|
||||
if ($words[0] eq 'off')
|
||||
{
|
||||
$nospace = 2;
|
||||
}
|
||||
elsif ($words[0] eq 'on')
|
||||
{
|
||||
# $retval .= "\n";
|
||||
$nospace = 0;
|
||||
}
|
||||
shift @words;
|
||||
next;
|
||||
}
|
||||
|
||||
$retval .= "$_";
|
||||
}
|
||||
|
||||
return undef
|
||||
if ($retval eq '.');
|
||||
|
||||
$retval =~ s/^\.([^a-zA-Z])/$1/;
|
||||
# $retval =~ s/ $//;
|
||||
|
||||
$retval .= ')'
|
||||
if ($parens == 1);
|
||||
|
||||
$retval .= ']'
|
||||
if ($option == 1);
|
||||
|
||||
# $retval .= ' '
|
||||
# if ($nospace && $retval ne '' && $retval !~ m/\n$/);
|
||||
|
||||
# $retval .= ' '
|
||||
# if ($extended && $retval !~ m/ $/);
|
||||
|
||||
$retval .= ' '
|
||||
if ($ext && ! $extopt && $retval !~ m/ $/);
|
||||
|
||||
$retval .= "\n"
|
||||
if (! $ext && ! $extopt && $retval ne '' && $retval !~ m/\n$/);
|
||||
|
||||
return $retval;
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,7 @@
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: monitor.c,v 1.36 2003/04/01 10:22:21 markus Exp $");
|
||||
RCSID("$OpenBSD: monitor.c,v 1.49 2003/08/28 12:54:34 markus Exp $");
|
||||
RCSID("$FreeBSD$");
|
||||
|
||||
#include <openssl/dh.h>
|
||||
@ -68,6 +68,11 @@ RCSID("$FreeBSD$");
|
||||
#include "ssh2.h"
|
||||
#include "mpaux.h"
|
||||
|
||||
#ifdef GSSAPI
|
||||
#include "ssh-gss.h"
|
||||
static Gssctxt *gsscontext = NULL;
|
||||
#endif
|
||||
|
||||
/* Imports */
|
||||
extern ServerOptions options;
|
||||
extern u_int utmp_len;
|
||||
@ -102,7 +107,7 @@ struct {
|
||||
u_int olen;
|
||||
} child_state;
|
||||
|
||||
/* Functions on the montior that answer unprivileged requests */
|
||||
/* Functions on the monitor that answer unprivileged requests */
|
||||
|
||||
int mm_answer_moduli(int, Buffer *);
|
||||
int mm_answer_sign(int, Buffer *);
|
||||
@ -127,17 +132,17 @@ int mm_answer_sessid(int, Buffer *);
|
||||
|
||||
#ifdef USE_PAM
|
||||
int mm_answer_pam_start(int, Buffer *);
|
||||
int mm_answer_pam_account(int, Buffer *);
|
||||
int mm_answer_pam_init_ctx(int, Buffer *);
|
||||
int mm_answer_pam_query(int, Buffer *);
|
||||
int mm_answer_pam_respond(int, Buffer *);
|
||||
int mm_answer_pam_free_ctx(int, Buffer *);
|
||||
#endif
|
||||
|
||||
#ifdef KRB4
|
||||
int mm_answer_krb4(int, Buffer *);
|
||||
#endif
|
||||
#ifdef KRB5
|
||||
int mm_answer_krb5(int, Buffer *);
|
||||
#ifdef GSSAPI
|
||||
int mm_answer_gss_setup_ctx(int, Buffer *);
|
||||
int mm_answer_gss_accept_ctx(int, Buffer *);
|
||||
int mm_answer_gss_userok(int, Buffer *);
|
||||
#endif
|
||||
|
||||
static Authctxt *authctxt;
|
||||
@ -150,8 +155,9 @@ static int key_blobtype = MM_NOKEY;
|
||||
static char *hostbased_cuser = NULL;
|
||||
static char *hostbased_chost = NULL;
|
||||
static char *auth_method = "unknown";
|
||||
static int session_id2_len = 0;
|
||||
static u_int session_id2_len = 0;
|
||||
static u_char *session_id2 = NULL;
|
||||
static pid_t monitor_child_pid;
|
||||
|
||||
struct mon_table {
|
||||
enum monitor_reqtype type;
|
||||
@ -176,6 +182,7 @@ struct mon_table mon_dispatch_proto20[] = {
|
||||
{MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword},
|
||||
#ifdef USE_PAM
|
||||
{MONITOR_REQ_PAM_START, MON_ONCE, mm_answer_pam_start},
|
||||
{MONITOR_REQ_PAM_ACCOUNT, 0, mm_answer_pam_account},
|
||||
{MONITOR_REQ_PAM_INIT_CTX, MON_ISAUTH, mm_answer_pam_init_ctx},
|
||||
{MONITOR_REQ_PAM_QUERY, MON_ISAUTH, mm_answer_pam_query},
|
||||
{MONITOR_REQ_PAM_RESPOND, MON_ISAUTH, mm_answer_pam_respond},
|
||||
@ -191,6 +198,11 @@ struct mon_table mon_dispatch_proto20[] = {
|
||||
#endif
|
||||
{MONITOR_REQ_KEYALLOWED, MON_ISAUTH, mm_answer_keyallowed},
|
||||
{MONITOR_REQ_KEYVERIFY, MON_AUTH, mm_answer_keyverify},
|
||||
#ifdef GSSAPI
|
||||
{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},
|
||||
#endif
|
||||
{0, 0, NULL}
|
||||
};
|
||||
|
||||
@ -222,16 +234,11 @@ struct mon_table mon_dispatch_proto15[] = {
|
||||
#endif
|
||||
#ifdef USE_PAM
|
||||
{MONITOR_REQ_PAM_START, MON_ONCE, mm_answer_pam_start},
|
||||
{MONITOR_REQ_PAM_ACCOUNT, 0, mm_answer_pam_account},
|
||||
{MONITOR_REQ_PAM_INIT_CTX, MON_ISAUTH, mm_answer_pam_init_ctx},
|
||||
{MONITOR_REQ_PAM_QUERY, MON_ISAUTH, mm_answer_pam_query},
|
||||
{MONITOR_REQ_PAM_RESPOND, MON_ISAUTH, mm_answer_pam_respond},
|
||||
{MONITOR_REQ_PAM_FREE_CTX, MON_ONCE|MON_AUTHDECIDE, mm_answer_pam_free_ctx},
|
||||
#endif
|
||||
#ifdef KRB4
|
||||
{MONITOR_REQ_KRB4, MON_ONCE|MON_AUTH, mm_answer_krb4},
|
||||
#endif
|
||||
#ifdef KRB5
|
||||
{MONITOR_REQ_KRB5, MON_ONCE|MON_AUTH, mm_answer_krb5},
|
||||
#endif
|
||||
{0, 0, NULL}
|
||||
};
|
||||
@ -306,6 +313,18 @@ monitor_child_preauth(struct monitor *pmonitor)
|
||||
if (authctxt->pw->pw_uid == 0 &&
|
||||
!auth_root_allowed(auth_method))
|
||||
authenticated = 0;
|
||||
#ifdef USE_PAM
|
||||
/* PAM needs to perform account checks after auth */
|
||||
if (options.use_pam) {
|
||||
Buffer m;
|
||||
|
||||
buffer_init(&m);
|
||||
mm_request_receive_expect(pmonitor->m_sendfd,
|
||||
MONITOR_REQ_PAM_ACCOUNT, &m);
|
||||
authenticated = mm_answer_pam_account(pmonitor->m_sendfd, &m);
|
||||
buffer_free(&m);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (ent->flags & MON_AUTHDECIDE) {
|
||||
@ -327,9 +346,25 @@ monitor_child_preauth(struct monitor *pmonitor)
|
||||
return (authctxt);
|
||||
}
|
||||
|
||||
static void
|
||||
monitor_set_child_handler(pid_t pid)
|
||||
{
|
||||
monitor_child_pid = pid;
|
||||
}
|
||||
|
||||
static void
|
||||
monitor_child_handler(int signal)
|
||||
{
|
||||
kill(monitor_child_pid, signal);
|
||||
}
|
||||
|
||||
void
|
||||
monitor_child_postauth(struct monitor *pmonitor)
|
||||
{
|
||||
monitor_set_child_handler(pmonitor->m_pid);
|
||||
signal(SIGHUP, &monitor_child_handler);
|
||||
signal(SIGTERM, &monitor_child_handler);
|
||||
|
||||
if (compat20) {
|
||||
mon_dispatch = mon_dispatch_postauth20;
|
||||
|
||||
@ -337,7 +372,6 @@ monitor_child_postauth(struct monitor *pmonitor)
|
||||
monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1);
|
||||
monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1);
|
||||
monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1);
|
||||
|
||||
} else {
|
||||
mon_dispatch = mon_dispatch_postauth15;
|
||||
monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1);
|
||||
@ -573,7 +607,8 @@ mm_answer_pwnamallow(int socket, Buffer *m)
|
||||
}
|
||||
|
||||
#ifdef USE_PAM
|
||||
monitor_permit(mon_dispatch, MONITOR_REQ_PAM_START, 1);
|
||||
if (options.use_pam)
|
||||
monitor_permit(mon_dispatch, MONITOR_REQ_PAM_START, 1);
|
||||
#endif
|
||||
|
||||
return (0);
|
||||
@ -623,7 +658,7 @@ mm_answer_authpassword(int socket, Buffer *m)
|
||||
passwd = buffer_get_string(m, &plen);
|
||||
/* Only authenticate if the context is valid */
|
||||
authenticated = options.password_authentication &&
|
||||
authctxt->valid && auth_password(authctxt, passwd);
|
||||
auth_password(authctxt, passwd);
|
||||
memset(passwd, 0, strlen(passwd));
|
||||
xfree(passwd);
|
||||
|
||||
@ -756,17 +791,39 @@ 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__);
|
||||
|
||||
user = buffer_get_string(m, NULL);
|
||||
|
||||
start_pam(user);
|
||||
|
||||
xfree(user);
|
||||
|
||||
monitor_permit(mon_dispatch, MONITOR_REQ_PAM_ACCOUNT, 1);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void *pam_ctxt, *pam_authok;
|
||||
extern KbdintDevice pam_device;
|
||||
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__);
|
||||
|
||||
ret = do_pam_account();
|
||||
|
||||
buffer_put_int(m, ret);
|
||||
|
||||
mm_request_send(socket, MONITOR_ANS_PAM_ACCOUNT, m);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static void *sshpam_ctxt, *sshpam_authok;
|
||||
extern KbdintDevice sshpam_device;
|
||||
|
||||
int
|
||||
mm_answer_pam_init_ctx(int socket, Buffer *m)
|
||||
@ -774,10 +831,10 @@ mm_answer_pam_init_ctx(int socket, Buffer *m)
|
||||
|
||||
debug3("%s", __func__);
|
||||
authctxt->user = buffer_get_string(m, NULL);
|
||||
pam_ctxt = (pam_device.init_ctx)(authctxt);
|
||||
pam_authok = NULL;
|
||||
sshpam_ctxt = (sshpam_device.init_ctx)(authctxt);
|
||||
sshpam_authok = NULL;
|
||||
buffer_clear(m);
|
||||
if (pam_ctxt != NULL) {
|
||||
if (sshpam_ctxt != NULL) {
|
||||
monitor_permit(mon_dispatch, MONITOR_REQ_PAM_FREE_CTX, 1);
|
||||
buffer_put_int(m, 1);
|
||||
} else {
|
||||
@ -795,10 +852,10 @@ mm_answer_pam_query(int socket, Buffer *m)
|
||||
int i, ret;
|
||||
|
||||
debug3("%s", __func__);
|
||||
pam_authok = NULL;
|
||||
ret = (pam_device.query)(pam_ctxt, &name, &info, &num, &prompts, &echo_on);
|
||||
sshpam_authok = NULL;
|
||||
ret = (sshpam_device.query)(sshpam_ctxt, &name, &info, &num, &prompts, &echo_on);
|
||||
if (ret == 0 && num == 0)
|
||||
pam_authok = pam_ctxt;
|
||||
sshpam_authok = sshpam_ctxt;
|
||||
if (num > 1 || name == NULL || info == NULL)
|
||||
ret = -1;
|
||||
buffer_clear(m);
|
||||
@ -829,25 +886,25 @@ mm_answer_pam_respond(int socket, Buffer *m)
|
||||
int i, ret;
|
||||
|
||||
debug3("%s", __func__);
|
||||
pam_authok = NULL;
|
||||
sshpam_authok = NULL;
|
||||
num = buffer_get_int(m);
|
||||
if (num > 0) {
|
||||
resp = xmalloc(num * sizeof(char *));
|
||||
for (i = 0; i < num; ++i)
|
||||
resp[i] = buffer_get_string(m, NULL);
|
||||
ret = (pam_device.respond)(pam_ctxt, num, resp);
|
||||
ret = (sshpam_device.respond)(sshpam_ctxt, num, resp);
|
||||
for (i = 0; i < num; ++i)
|
||||
xfree(resp[i]);
|
||||
xfree(resp);
|
||||
} else {
|
||||
ret = (pam_device.respond)(pam_ctxt, num, NULL);
|
||||
ret = (sshpam_device.respond)(sshpam_ctxt, num, NULL);
|
||||
}
|
||||
buffer_clear(m);
|
||||
buffer_put_int(m, ret);
|
||||
mm_request_send(socket, MONITOR_ANS_PAM_RESPOND, m);
|
||||
auth_method = "keyboard-interactive/pam";
|
||||
if (ret == 0)
|
||||
pam_authok = pam_ctxt;
|
||||
sshpam_authok = sshpam_ctxt;
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -856,10 +913,10 @@ mm_answer_pam_free_ctx(int socket, Buffer *m)
|
||||
{
|
||||
|
||||
debug3("%s", __func__);
|
||||
(pam_device.free_ctx)(pam_ctxt);
|
||||
(sshpam_device.free_ctx)(sshpam_ctxt);
|
||||
buffer_clear(m);
|
||||
mm_request_send(socket, MONITOR_ANS_PAM_FREE_CTX, m);
|
||||
return (pam_authok == pam_ctxt);
|
||||
return (sshpam_authok == sshpam_ctxt);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -984,7 +1041,7 @@ monitor_valid_userblob(u_char *data, u_int datalen)
|
||||
fail++;
|
||||
p = buffer_get_string(&b, NULL);
|
||||
if (strcmp(authctxt->user, p) != 0) {
|
||||
log("wrong user name passed to monitor: expected %s != %.100s",
|
||||
logit("wrong user name passed to monitor: expected %s != %.100s",
|
||||
authctxt->user, p);
|
||||
fail++;
|
||||
}
|
||||
@ -1032,7 +1089,7 @@ monitor_valid_hostbasedblob(u_char *data, u_int datalen, char *cuser,
|
||||
fail++;
|
||||
p = buffer_get_string(&b, NULL);
|
||||
if (strcmp(authctxt->user, p) != 0) {
|
||||
log("wrong user name passed to monitor: expected %s != %.100s",
|
||||
logit("wrong user name passed to monitor: expected %s != %.100s",
|
||||
authctxt->user, p);
|
||||
fail++;
|
||||
}
|
||||
@ -1142,14 +1199,14 @@ mm_record_login(Session *s, struct passwd *pw)
|
||||
}
|
||||
/* Record that there was a login on that tty from the remote host. */
|
||||
record_login(s->pid, s->tty, pw->pw_name, pw->pw_uid,
|
||||
get_remote_name_or_ip(utmp_len, options.verify_reverse_mapping),
|
||||
get_remote_name_or_ip(utmp_len, options.use_dns),
|
||||
(struct sockaddr *)&from, fromlen);
|
||||
}
|
||||
|
||||
static void
|
||||
mm_session_close(Session *s)
|
||||
{
|
||||
debug3("%s: session %d pid %d", __func__, s->self, s->pid);
|
||||
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);
|
||||
@ -1413,89 +1470,6 @@ mm_answer_rsa_response(int socket, Buffer *m)
|
||||
return (success);
|
||||
}
|
||||
|
||||
#ifdef KRB4
|
||||
int
|
||||
mm_answer_krb4(int socket, Buffer *m)
|
||||
{
|
||||
KTEXT_ST auth, reply;
|
||||
char *client, *p;
|
||||
int success;
|
||||
u_int alen;
|
||||
|
||||
reply.length = auth.length = 0;
|
||||
|
||||
p = buffer_get_string(m, &alen);
|
||||
if (alen >= MAX_KTXT_LEN)
|
||||
fatal("%s: auth too large", __func__);
|
||||
memcpy(auth.dat, p, alen);
|
||||
auth.length = alen;
|
||||
memset(p, 0, alen);
|
||||
xfree(p);
|
||||
|
||||
success = options.kerberos_authentication &&
|
||||
authctxt->valid &&
|
||||
auth_krb4(authctxt, &auth, &client, &reply);
|
||||
|
||||
memset(auth.dat, 0, alen);
|
||||
buffer_clear(m);
|
||||
buffer_put_int(m, success);
|
||||
|
||||
if (success) {
|
||||
buffer_put_cstring(m, client);
|
||||
buffer_put_string(m, reply.dat, reply.length);
|
||||
if (client)
|
||||
xfree(client);
|
||||
if (reply.length)
|
||||
memset(reply.dat, 0, reply.length);
|
||||
}
|
||||
|
||||
debug3("%s: sending result %d", __func__, success);
|
||||
mm_request_send(socket, MONITOR_ANS_KRB4, m);
|
||||
|
||||
auth_method = "kerberos";
|
||||
|
||||
/* Causes monitor loop to terminate if authenticated */
|
||||
return (success);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef KRB5
|
||||
int
|
||||
mm_answer_krb5(int socket, Buffer *m)
|
||||
{
|
||||
krb5_data tkt, reply;
|
||||
char *client_user;
|
||||
u_int len;
|
||||
int success;
|
||||
|
||||
/* use temporary var to avoid size issues on 64bit arch */
|
||||
tkt.data = buffer_get_string(m, &len);
|
||||
tkt.length = len;
|
||||
|
||||
success = options.kerberos_authentication &&
|
||||
authctxt->valid &&
|
||||
auth_krb5(authctxt, &tkt, &client_user, &reply);
|
||||
|
||||
if (tkt.length)
|
||||
xfree(tkt.data);
|
||||
|
||||
buffer_clear(m);
|
||||
buffer_put_int(m, success);
|
||||
|
||||
if (success) {
|
||||
buffer_put_cstring(m, client_user);
|
||||
buffer_put_string(m, reply.data, reply.length);
|
||||
if (client_user)
|
||||
xfree(client_user);
|
||||
if (reply.length)
|
||||
xfree(reply.data);
|
||||
}
|
||||
mm_request_send(socket, MONITOR_ANS_KRB5, m);
|
||||
|
||||
return success;
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
mm_answer_term(int socket, Buffer *req)
|
||||
{
|
||||
@ -1611,6 +1585,8 @@ mm_get_keystate(struct monitor *pmonitor)
|
||||
Buffer m;
|
||||
u_char *blob, *p;
|
||||
u_int bloblen, plen;
|
||||
u_int32_t seqnr, packets;
|
||||
u_int64_t blocks;
|
||||
|
||||
debug3("%s: Waiting for new keys", __func__);
|
||||
|
||||
@ -1640,8 +1616,14 @@ mm_get_keystate(struct monitor *pmonitor)
|
||||
xfree(blob);
|
||||
|
||||
/* Now get sequence numbers for the packets */
|
||||
packet_set_seqnr(MODE_OUT, buffer_get_int(&m));
|
||||
packet_set_seqnr(MODE_IN, buffer_get_int(&m));
|
||||
seqnr = buffer_get_int(&m);
|
||||
blocks = buffer_get_int64(&m);
|
||||
packets = buffer_get_int(&m);
|
||||
packet_set_state(MODE_OUT, seqnr, blocks, packets);
|
||||
seqnr = buffer_get_int(&m);
|
||||
blocks = buffer_get_int64(&m);
|
||||
packets = buffer_get_int(&m);
|
||||
packet_set_state(MODE_IN, seqnr, blocks, packets);
|
||||
|
||||
skip:
|
||||
/* Get the key context */
|
||||
@ -1762,3 +1744,79 @@ monitor_reinit(struct monitor *mon)
|
||||
mon->m_recvfd = pair[0];
|
||||
mon->m_sendfd = pair[1];
|
||||
}
|
||||
|
||||
#ifdef GSSAPI
|
||||
int
|
||||
mm_answer_gss_setup_ctx(int socket, Buffer *m)
|
||||
{
|
||||
gss_OID_desc oid;
|
||||
OM_uint32 major;
|
||||
u_int len;
|
||||
|
||||
oid.elements = buffer_get_string(m, &len);
|
||||
oid.length = len;
|
||||
|
||||
major = ssh_gssapi_server_ctx(&gsscontext, &oid);
|
||||
|
||||
xfree(oid.elements);
|
||||
|
||||
buffer_clear(m);
|
||||
buffer_put_int(m, major);
|
||||
|
||||
mm_request_send(socket,MONITOR_ANS_GSSSETUP, m);
|
||||
|
||||
/* Now we have a context, enable the step */
|
||||
monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 1);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
mm_answer_gss_accept_ctx(int socket, Buffer *m)
|
||||
{
|
||||
gss_buffer_desc in;
|
||||
gss_buffer_desc out = GSS_C_EMPTY_BUFFER;
|
||||
OM_uint32 major,minor;
|
||||
OM_uint32 flags = 0; /* GSI needs this */
|
||||
u_int len;
|
||||
|
||||
in.value = buffer_get_string(m, &len);
|
||||
in.length = len;
|
||||
major = ssh_gssapi_accept_ctx(gsscontext, &in, &out, &flags);
|
||||
xfree(in.value);
|
||||
|
||||
buffer_clear(m);
|
||||
buffer_put_int(m, major);
|
||||
buffer_put_string(m, out.value, out.length);
|
||||
buffer_put_int(m, flags);
|
||||
mm_request_send(socket, MONITOR_ANS_GSSSTEP, 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);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
mm_answer_gss_userok(int socket, Buffer *m)
|
||||
{
|
||||
int authenticated;
|
||||
|
||||
authenticated = authctxt->valid && ssh_gssapi_userok(authctxt->user);
|
||||
|
||||
buffer_clear(m);
|
||||
buffer_put_int(m, authenticated);
|
||||
|
||||
debug3("%s: sending result %d", __func__, authenticated);
|
||||
mm_request_send(socket, MONITOR_ANS_GSSUSEROK, m);
|
||||
|
||||
auth_method="gssapi";
|
||||
|
||||
/* Monitor loop will terminate if authenticated */
|
||||
return (authenticated);
|
||||
}
|
||||
#endif /* GSSAPI */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: monitor.h,v 1.8 2002/09/26 11:38:43 markus Exp $ */
|
||||
/* $OpenBSD: monitor.h,v 1.11 2003/08/28 12:54:34 markus Exp $ */
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/*
|
||||
@ -50,9 +50,11 @@ enum monitor_reqtype {
|
||||
MONITOR_REQ_RSAKEYALLOWED, MONITOR_ANS_RSAKEYALLOWED,
|
||||
MONITOR_REQ_RSACHALLENGE, MONITOR_ANS_RSACHALLENGE,
|
||||
MONITOR_REQ_RSARESPONSE, MONITOR_ANS_RSARESPONSE,
|
||||
MONITOR_REQ_KRB4, MONITOR_ANS_KRB4,
|
||||
MONITOR_REQ_KRB5, MONITOR_ANS_KRB5,
|
||||
MONITOR_REQ_GSSSETUP, MONITOR_ANS_GSSSETUP,
|
||||
MONITOR_REQ_GSSSTEP, MONITOR_ANS_GSSSTEP,
|
||||
MONITOR_REQ_GSSUSEROK, MONITOR_ANS_GSSUSEROK,
|
||||
MONITOR_REQ_PAM_START,
|
||||
MONITOR_REQ_PAM_ACCOUNT, MONITOR_ANS_PAM_ACCOUNT,
|
||||
MONITOR_REQ_PAM_INIT_CTX, MONITOR_ANS_PAM_INIT_CTX,
|
||||
MONITOR_REQ_PAM_QUERY, MONITOR_ANS_PAM_QUERY,
|
||||
MONITOR_REQ_PAM_RESPOND, MONITOR_ANS_PAM_RESPOND,
|
||||
|
@ -25,7 +25,7 @@
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: monitor_wrap.c,v 1.24 2003/04/01 10:22:21 markus Exp $");
|
||||
RCSID("$OpenBSD: monitor_wrap.c,v 1.31 2003/08/28 12:54:34 markus Exp $");
|
||||
RCSID("$FreeBSD$");
|
||||
|
||||
#include <openssl/bn.h>
|
||||
@ -48,11 +48,16 @@ RCSID("$FreeBSD$");
|
||||
#include "atomicio.h"
|
||||
#include "monitor_fdpass.h"
|
||||
#include "getput.h"
|
||||
#include "servconf.h"
|
||||
|
||||
#include "auth.h"
|
||||
#include "channels.h"
|
||||
#include "session.h"
|
||||
|
||||
#ifdef GSSAPI
|
||||
#include "ssh-gss.h"
|
||||
#endif
|
||||
|
||||
/* Imports */
|
||||
extern int compat20;
|
||||
extern Newkeys *newkeys[];
|
||||
@ -60,6 +65,7 @@ extern z_stream incoming_stream;
|
||||
extern z_stream outgoing_stream;
|
||||
extern struct monitor *pmonitor;
|
||||
extern Buffer input, output;
|
||||
extern ServerOptions options;
|
||||
|
||||
void
|
||||
mm_request_send(int socket, enum monitor_reqtype type, Buffer *m)
|
||||
@ -71,9 +77,9 @@ mm_request_send(int socket, enum monitor_reqtype type, Buffer *m)
|
||||
|
||||
PUT_32BIT(buf, mlen + 1);
|
||||
buf[4] = (u_char) type; /* 1st byte of payload is mesg-type */
|
||||
if (atomicio(write, socket, buf, sizeof(buf)) != sizeof(buf))
|
||||
if (atomicio(vwrite, socket, buf, sizeof(buf)) != sizeof(buf))
|
||||
fatal("%s: write", __func__);
|
||||
if (atomicio(write, socket, buffer_ptr(m), mlen) != mlen)
|
||||
if (atomicio(vwrite, socket, buffer_ptr(m), mlen) != mlen)
|
||||
fatal("%s: write", __func__);
|
||||
}
|
||||
|
||||
@ -521,6 +527,8 @@ mm_send_keystate(struct monitor *pmonitor)
|
||||
Buffer m;
|
||||
u_char *blob, *p;
|
||||
u_int bloblen, plen;
|
||||
u_int32_t seqnr, packets;
|
||||
u_int64_t blocks;
|
||||
|
||||
buffer_init(&m);
|
||||
|
||||
@ -569,8 +577,14 @@ mm_send_keystate(struct monitor *pmonitor)
|
||||
buffer_put_string(&m, blob, bloblen);
|
||||
xfree(blob);
|
||||
|
||||
buffer_put_int(&m, packet_get_seqnr(MODE_OUT));
|
||||
buffer_put_int(&m, packet_get_seqnr(MODE_IN));
|
||||
packet_get_state(MODE_OUT, &seqnr, &blocks, &packets);
|
||||
buffer_put_int(&m, seqnr);
|
||||
buffer_put_int64(&m, blocks);
|
||||
buffer_put_int(&m, packets);
|
||||
packet_get_state(MODE_IN, &seqnr, &blocks, &packets);
|
||||
buffer_put_int(&m, seqnr);
|
||||
buffer_put_int64(&m, blocks);
|
||||
buffer_put_int(&m, packets);
|
||||
|
||||
debug3("%s: New keys have been sent", __func__);
|
||||
skip:
|
||||
@ -662,6 +676,8 @@ mm_start_pam(char *user)
|
||||
Buffer m;
|
||||
|
||||
debug3("%s entering", __func__);
|
||||
if (!options.use_pam)
|
||||
fatal("UsePAM=no, but ended up in %s anyway", __func__);
|
||||
|
||||
buffer_init(&m);
|
||||
buffer_put_cstring(&m, user);
|
||||
@ -671,8 +687,32 @@ mm_start_pam(char *user)
|
||||
buffer_free(&m);
|
||||
}
|
||||
|
||||
u_int
|
||||
mm_do_pam_account(void)
|
||||
{
|
||||
Buffer m;
|
||||
u_int ret;
|
||||
|
||||
debug3("%s entering", __func__);
|
||||
if (!options.use_pam)
|
||||
fatal("UsePAM=no, but ended up in %s anyway", __func__);
|
||||
|
||||
buffer_init(&m);
|
||||
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_ACCOUNT, &m);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void *
|
||||
mm_pam_init_ctx(Authctxt *authctxt)
|
||||
mm_sshpam_init_ctx(Authctxt *authctxt)
|
||||
{
|
||||
Buffer m;
|
||||
int success;
|
||||
@ -694,7 +734,7 @@ mm_pam_init_ctx(Authctxt *authctxt)
|
||||
}
|
||||
|
||||
int
|
||||
mm_pam_query(void *ctx, char **name, char **info,
|
||||
mm_sshpam_query(void *ctx, char **name, char **info,
|
||||
u_int *num, char ***prompts, u_int **echo_on)
|
||||
{
|
||||
Buffer m;
|
||||
@ -721,7 +761,7 @@ mm_pam_query(void *ctx, char **name, char **info,
|
||||
}
|
||||
|
||||
int
|
||||
mm_pam_respond(void *ctx, u_int num, char **resp)
|
||||
mm_sshpam_respond(void *ctx, u_int num, char **resp)
|
||||
{
|
||||
Buffer m;
|
||||
int i, ret;
|
||||
@ -741,7 +781,7 @@ mm_pam_respond(void *ctx, u_int num, char **resp)
|
||||
}
|
||||
|
||||
void
|
||||
mm_pam_free_ctx(void *ctxtp)
|
||||
mm_sshpam_free_ctx(void *ctxtp)
|
||||
{
|
||||
Buffer m;
|
||||
|
||||
@ -1034,73 +1074,69 @@ mm_auth_rsa_verify_response(Key *key, BIGNUM *p, u_char response[16])
|
||||
return (success);
|
||||
}
|
||||
|
||||
#ifdef KRB4
|
||||
int
|
||||
mm_auth_krb4(Authctxt *authctxt, void *_auth, char **client, void *_reply)
|
||||
#ifdef GSSAPI
|
||||
OM_uint32
|
||||
mm_ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID oid)
|
||||
{
|
||||
KTEXT auth, reply;
|
||||
Buffer m;
|
||||
u_int rlen;
|
||||
int success = 0;
|
||||
char *p;
|
||||
|
||||
debug3("%s entering", __func__);
|
||||
auth = _auth;
|
||||
reply = _reply;
|
||||
|
||||
buffer_init(&m);
|
||||
buffer_put_string(&m, auth->dat, auth->length);
|
||||
|
||||
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KRB4, &m);
|
||||
mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_KRB4, &m);
|
||||
|
||||
success = buffer_get_int(&m);
|
||||
if (success) {
|
||||
*client = buffer_get_string(&m, NULL);
|
||||
p = buffer_get_string(&m, &rlen);
|
||||
if (rlen >= MAX_KTXT_LEN)
|
||||
fatal("%s: reply from monitor too large", __func__);
|
||||
reply->length = rlen;
|
||||
memcpy(reply->dat, p, rlen);
|
||||
memset(p, 0, rlen);
|
||||
xfree(p);
|
||||
}
|
||||
buffer_free(&m);
|
||||
return (success);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef KRB5
|
||||
int
|
||||
mm_auth_krb5(void *ctx, void *argp, char **userp, void *resp)
|
||||
{
|
||||
krb5_data *tkt, *reply;
|
||||
Buffer m;
|
||||
int success;
|
||||
OM_uint32 major;
|
||||
|
||||
debug3("%s entering", __func__);
|
||||
tkt = (krb5_data *) argp;
|
||||
reply = (krb5_data *) resp;
|
||||
/* Client doesn't get to see the context */
|
||||
*ctx = NULL;
|
||||
|
||||
buffer_init(&m);
|
||||
buffer_put_string(&m, tkt->data, tkt->length);
|
||||
buffer_put_string(&m, oid->elements, oid->length);
|
||||
|
||||
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KRB5, &m);
|
||||
mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_KRB5, &m);
|
||||
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSSETUP, &m);
|
||||
mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSSETUP, &m);
|
||||
|
||||
success = buffer_get_int(&m);
|
||||
if (success) {
|
||||
u_int len;
|
||||
|
||||
*userp = buffer_get_string(&m, NULL);
|
||||
reply->data = buffer_get_string(&m, &len);
|
||||
reply->length = len;
|
||||
} else {
|
||||
memset(reply, 0, sizeof(*reply));
|
||||
*userp = NULL;
|
||||
}
|
||||
major = buffer_get_int(&m);
|
||||
|
||||
buffer_free(&m);
|
||||
return (success);
|
||||
return (major);
|
||||
}
|
||||
#endif
|
||||
|
||||
OM_uint32
|
||||
mm_ssh_gssapi_accept_ctx(Gssctxt *ctx, gss_buffer_desc *in,
|
||||
gss_buffer_desc *out, OM_uint32 *flags)
|
||||
{
|
||||
Buffer m;
|
||||
OM_uint32 major;
|
||||
u_int len;
|
||||
|
||||
buffer_init(&m);
|
||||
buffer_put_string(&m, in->value, in->length);
|
||||
|
||||
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSSTEP, &m);
|
||||
mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSSTEP, &m);
|
||||
|
||||
major = buffer_get_int(&m);
|
||||
out->value = buffer_get_string(&m, &len);
|
||||
out->length = len;
|
||||
if (flags)
|
||||
*flags = buffer_get_int(&m);
|
||||
|
||||
buffer_free(&m);
|
||||
|
||||
return (major);
|
||||
}
|
||||
|
||||
int
|
||||
mm_ssh_gssapi_userok(char *user)
|
||||
{
|
||||
Buffer m;
|
||||
int authenticated = 0;
|
||||
|
||||
buffer_init(&m);
|
||||
|
||||
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSUSEROK, &m);
|
||||
mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSUSEROK,
|
||||
&m);
|
||||
|
||||
authenticated = buffer_get_int(&m);
|
||||
|
||||
buffer_free(&m);
|
||||
debug3("%s: user %sauthenticated",__func__, authenticated ? "" : "not ");
|
||||
return (authenticated);
|
||||
}
|
||||
#endif /* GSSAPI */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: monitor_wrap.h,v 1.8 2002/09/26 11:38:43 markus Exp $ */
|
||||
/* $OpenBSD: monitor_wrap.h,v 1.11 2003/08/28 12:54:34 markus Exp $ */
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/*
|
||||
@ -56,12 +56,21 @@ int mm_auth_rsa_key_allowed(struct passwd *, BIGNUM *, Key **);
|
||||
int mm_auth_rsa_verify_response(Key *, BIGNUM *, u_char *);
|
||||
BIGNUM *mm_auth_rsa_generate_challenge(Key *);
|
||||
|
||||
#ifdef GSSAPI
|
||||
#include "ssh-gss.h"
|
||||
OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **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);
|
||||
#endif
|
||||
|
||||
#ifdef USE_PAM
|
||||
void mm_start_pam(char *);
|
||||
void *mm_pam_init_ctx(struct Authctxt *);
|
||||
int mm_pam_query(void *, char **, char **, u_int *, char ***, u_int **);
|
||||
int mm_pam_respond(void *, u_int, char **);
|
||||
void mm_pam_free_ctx(void *);
|
||||
u_int mm_do_pam_account(void);
|
||||
void *mm_sshpam_init_ctx(struct Authctxt *);
|
||||
int mm_sshpam_query(void *, char **, char **, u_int *, char ***, u_int **);
|
||||
int mm_sshpam_respond(void *, u_int, char **);
|
||||
void mm_sshpam_free_ctx(void *);
|
||||
#endif
|
||||
|
||||
void mm_terminate(void);
|
||||
@ -88,16 +97,6 @@ int mm_bsdauth_respond(void *, u_int, char **);
|
||||
int mm_skey_query(void *, char **, char **, u_int *, char ***, u_int **);
|
||||
int mm_skey_respond(void *, u_int, char **);
|
||||
|
||||
/* auth_krb */
|
||||
#ifdef KRB4
|
||||
int mm_auth_krb4(struct Authctxt *, void *, char **, void *);
|
||||
#endif
|
||||
#ifdef KRB5
|
||||
/* auth and reply are really krb5_data objects, but we don't want to
|
||||
* include all of the krb5 headers here */
|
||||
int mm_auth_krb5(void *authctxt, void *auth, char **client, void *reply);
|
||||
#endif
|
||||
|
||||
/* zlib allocation hooks */
|
||||
|
||||
void *mm_zalloc(struct mm_master *, u_int, u_int);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: myproposal.h,v 1.14 2002/04/03 09:26:11 markus Exp $ */
|
||||
/* $OpenBSD: myproposal.h,v 1.15 2003/05/17 04:27:52 markus Exp $ */
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/*
|
||||
@ -28,7 +28,8 @@
|
||||
#define KEX_DEFAULT_PK_ALG "ssh-dss,ssh-rsa"
|
||||
#define KEX_DEFAULT_ENCRYPT \
|
||||
"aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour," \
|
||||
"aes192-cbc,aes256-cbc,rijndael-cbc@lysator.liu.se"
|
||||
"aes192-cbc,aes256-cbc,rijndael-cbc@lysator.liu.se," \
|
||||
"aes128-ctr,aes192-ctr,aes256-ctr"
|
||||
#define KEX_DEFAULT_MAC \
|
||||
"hmac-md5,hmac-sha1,hmac-ripemd160," \
|
||||
"hmac-ripemd160@openssh.com," \
|
||||
|
@ -1,12 +0,0 @@
|
||||
/* $Id: basename.h,v 1.3 2003/02/25 03:32:16 djm Exp $ */
|
||||
|
||||
#ifndef _BASENAME_H
|
||||
#define _BASENAME_H
|
||||
#include "config.h"
|
||||
|
||||
#if !defined(HAVE_BASENAME)
|
||||
|
||||
char *basename(const char *path);
|
||||
|
||||
#endif /* !defined(HAVE_BASENAME) */
|
||||
#endif /* _BASENAME_H */
|
@ -1,12 +0,0 @@
|
||||
/* $Id: bindresvport.h,v 1.2 2001/02/09 01:55:36 djm Exp $ */
|
||||
|
||||
#ifndef _BSD_BINDRESVPORT_H
|
||||
#define _BSD_BINDRESVPORT_H
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifndef HAVE_BINDRESVPORT_SA
|
||||
int bindresvport_sa(int sd, struct sockaddr *sa);
|
||||
#endif /* !HAVE_BINDRESVPORT_SA */
|
||||
|
||||
#endif /* _BSD_BINDRESVPORT_H */
|
@ -1,37 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1999-2000 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.
|
||||
*/
|
||||
|
||||
/* $Id: bsd-arc4random.h,v 1.2 2001/02/09 01:55:36 djm Exp $ */
|
||||
|
||||
#ifndef _BSD_ARC4RANDOM_H
|
||||
#define _BSD_ARC4RANDOM_H
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifndef HAVE_ARC4RANDOM
|
||||
unsigned int arc4random(void);
|
||||
void arc4random_stir(void);
|
||||
#endif /* !HAVE_ARC4RANDOM */
|
||||
|
||||
#endif /* _BSD_ARC4RANDOM_H */
|
@ -1,14 +0,0 @@
|
||||
/* $Id: bsd-getpeereid.h,v 1.1 2002/09/12 00:33:02 djm Exp $ */
|
||||
|
||||
#ifndef _BSD_GETPEEREID_H
|
||||
#define _BSD_GETPEEREID_H
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <sys/types.h> /* For uid_t, gid_t */
|
||||
|
||||
#ifndef HAVE_GETPEEREID
|
||||
int getpeereid(int , uid_t *, gid_t *);
|
||||
#endif /* HAVE_GETPEEREID */
|
||||
|
||||
#endif /* _BSD_GETPEEREID_H */
|
@ -1,19 +0,0 @@
|
||||
/* $Id: bsd-snprintf.h,v 1.2 2001/02/09 01:55:36 djm Exp $ */
|
||||
|
||||
#ifndef _BSD_SNPRINTF_H
|
||||
#define _BSD_SNPRINTF_H
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <sys/types.h> /* For size_t */
|
||||
|
||||
#ifndef HAVE_SNPRINTF
|
||||
int snprintf(char *str, size_t count, const char *fmt, ...);
|
||||
#endif /* !HAVE_SNPRINTF */
|
||||
|
||||
#ifndef HAVE_VSNPRINTF
|
||||
int vsnprintf(char *str, size_t count, const char *fmt, va_list args);
|
||||
#endif /* !HAVE_SNPRINTF */
|
||||
|
||||
|
||||
#endif /* _BSD_SNPRINTF_H */
|
@ -1,11 +0,0 @@
|
||||
/* $Id: daemon.h,v 1.2 2001/02/09 01:55:36 djm Exp $ */
|
||||
|
||||
#ifndef _BSD_DAEMON_H
|
||||
#define _BSD_DAEMON_H
|
||||
|
||||
#include "config.h"
|
||||
#ifndef HAVE_DAEMON
|
||||
int daemon(int nochdir, int noclose);
|
||||
#endif /* !HAVE_DAEMON */
|
||||
|
||||
#endif /* _BSD_DAEMON_H */
|
@ -1,5 +0,0 @@
|
||||
#ifndef HAVE_DIRNAME
|
||||
|
||||
char *dirname(const char *path);
|
||||
|
||||
#endif
|
@ -1,14 +0,0 @@
|
||||
/*
|
||||
* fake library for ssh
|
||||
*
|
||||
* This file is included in getaddrinfo.c and getnameinfo.c.
|
||||
* See getaddrinfo.c and getnameinfo.c.
|
||||
*/
|
||||
|
||||
/* $Id: fake-gai-errnos.h,v 1.2 2001/02/09 01:55:36 djm Exp $ */
|
||||
|
||||
/* for old netdb.h */
|
||||
#ifndef EAI_NODATA
|
||||
#define EAI_NODATA 1
|
||||
#define EAI_MEMORY 2
|
||||
#endif
|
@ -1,135 +0,0 @@
|
||||
/*
|
||||
* fake library for ssh
|
||||
*
|
||||
* This file includes getaddrinfo(), freeaddrinfo() and gai_strerror().
|
||||
* These funtions are defined in rfc2133.
|
||||
*
|
||||
* But these functions are not implemented correctly. The minimum subset
|
||||
* is implemented for ssh use only. For exapmle, this routine assumes
|
||||
* that ai_family is AF_INET. Don't use it for another purpose.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#include "ssh.h"
|
||||
|
||||
RCSID("$Id: fake-getaddrinfo.c,v 1.5 2003/03/24 02:35:59 djm Exp $");
|
||||
|
||||
#ifndef HAVE_GAI_STRERROR
|
||||
char *gai_strerror(int ecode)
|
||||
{
|
||||
switch (ecode) {
|
||||
case EAI_NODATA:
|
||||
return "no address associated with hostname.";
|
||||
case EAI_MEMORY:
|
||||
return "memory allocation failure.";
|
||||
default:
|
||||
return "unknown error.";
|
||||
}
|
||||
}
|
||||
#endif /* !HAVE_GAI_STRERROR */
|
||||
|
||||
#ifndef HAVE_FREEADDRINFO
|
||||
void freeaddrinfo(struct addrinfo *ai)
|
||||
{
|
||||
struct addrinfo *next;
|
||||
|
||||
do {
|
||||
next = ai->ai_next;
|
||||
free(ai);
|
||||
} while (NULL != (ai = next));
|
||||
}
|
||||
#endif /* !HAVE_FREEADDRINFO */
|
||||
|
||||
#ifndef HAVE_GETADDRINFO
|
||||
static struct addrinfo *malloc_ai(int port, u_long addr)
|
||||
{
|
||||
struct addrinfo *ai;
|
||||
|
||||
ai = malloc(sizeof(struct addrinfo) + sizeof(struct sockaddr_in));
|
||||
if (ai == NULL)
|
||||
return(NULL);
|
||||
|
||||
memset(ai, 0, sizeof(struct addrinfo) + sizeof(struct sockaddr_in));
|
||||
|
||||
ai->ai_addr = (struct sockaddr *)(ai + 1);
|
||||
/* XXX -- ssh doesn't use sa_len */
|
||||
ai->ai_addrlen = sizeof(struct sockaddr_in);
|
||||
ai->ai_addr->sa_family = ai->ai_family = AF_INET;
|
||||
|
||||
((struct sockaddr_in *)(ai)->ai_addr)->sin_port = port;
|
||||
((struct sockaddr_in *)(ai)->ai_addr)->sin_addr.s_addr = addr;
|
||||
|
||||
return(ai);
|
||||
}
|
||||
|
||||
int getaddrinfo(const char *hostname, const char *servname,
|
||||
const struct addrinfo *hints, struct addrinfo **res)
|
||||
{
|
||||
struct addrinfo *cur, *prev = NULL;
|
||||
struct hostent *hp;
|
||||
struct servent *sp;
|
||||
struct in_addr in;
|
||||
int i;
|
||||
long int port;
|
||||
u_long addr;
|
||||
|
||||
port = 0;
|
||||
if (servname != NULL) {
|
||||
char *cp;
|
||||
|
||||
port = strtol(servname, &cp, 10);
|
||||
if (port > 0 && port <= 65535 && *cp == '\0')
|
||||
port = htons(port);
|
||||
else if ((sp = getservbyname(servname, NULL)) != NULL)
|
||||
port = sp->s_port;
|
||||
else
|
||||
port = 0;
|
||||
}
|
||||
|
||||
if (hints && hints->ai_flags & AI_PASSIVE) {
|
||||
addr = htonl(0x00000000);
|
||||
if (hostname && inet_aton(hostname, &in) != 0)
|
||||
addr = in.s_addr;
|
||||
if (NULL != (*res = malloc_ai(port, addr)))
|
||||
return 0;
|
||||
else
|
||||
return EAI_MEMORY;
|
||||
}
|
||||
|
||||
if (!hostname) {
|
||||
if (NULL != (*res = malloc_ai(port, htonl(0x7f000001))))
|
||||
return 0;
|
||||
else
|
||||
return EAI_MEMORY;
|
||||
}
|
||||
|
||||
if (inet_aton(hostname, &in)) {
|
||||
if (NULL != (*res = malloc_ai(port, in.s_addr)))
|
||||
return 0;
|
||||
else
|
||||
return EAI_MEMORY;
|
||||
}
|
||||
|
||||
hp = gethostbyname(hostname);
|
||||
if (hp && hp->h_name && hp->h_name[0] && hp->h_addr_list[0]) {
|
||||
for (i = 0; hp->h_addr_list[i]; i++) {
|
||||
cur = malloc_ai(port, ((struct in_addr *)hp->h_addr_list[i])->s_addr);
|
||||
if (cur == NULL) {
|
||||
if (*res)
|
||||
freeaddrinfo(*res);
|
||||
return EAI_MEMORY;
|
||||
}
|
||||
|
||||
if (prev)
|
||||
prev->ai_next = cur;
|
||||
else
|
||||
*res = cur;
|
||||
|
||||
prev = cur;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
return EAI_NODATA;
|
||||
}
|
||||
#endif /* !HAVE_GETADDRINFO */
|
@ -1,47 +0,0 @@
|
||||
/* $Id: fake-getaddrinfo.h,v 1.4 2003/02/24 01:35:09 djm Exp $ */
|
||||
|
||||
#ifndef _FAKE_GETADDRINFO_H
|
||||
#define _FAKE_GETADDRINFO_H
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "fake-gai-errnos.h"
|
||||
|
||||
#ifndef AI_PASSIVE
|
||||
# define AI_PASSIVE 1
|
||||
# define AI_CANONNAME 2
|
||||
#endif
|
||||
|
||||
#ifndef NI_NUMERICHOST
|
||||
# define NI_NUMERICHOST 2
|
||||
# define NI_NAMEREQD 4
|
||||
# define NI_NUMERICSERV 8
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRUCT_ADDRINFO
|
||||
struct addrinfo {
|
||||
int ai_flags; /* AI_PASSIVE, AI_CANONNAME */
|
||||
int ai_family; /* PF_xxx */
|
||||
int ai_socktype; /* SOCK_xxx */
|
||||
int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
|
||||
size_t ai_addrlen; /* length of ai_addr */
|
||||
char *ai_canonname; /* canonical name for hostname */
|
||||
struct sockaddr *ai_addr; /* binary address */
|
||||
struct addrinfo *ai_next; /* next structure in linked list */
|
||||
};
|
||||
#endif /* !HAVE_STRUCT_ADDRINFO */
|
||||
|
||||
#ifndef HAVE_GETADDRINFO
|
||||
int getaddrinfo(const char *hostname, const char *servname,
|
||||
const struct addrinfo *hints, struct addrinfo **res);
|
||||
#endif /* !HAVE_GETADDRINFO */
|
||||
|
||||
#ifndef HAVE_GAI_STRERROR
|
||||
char *gai_strerror(int ecode);
|
||||
#endif /* !HAVE_GAI_STRERROR */
|
||||
|
||||
#ifndef HAVE_FREEADDRINFO
|
||||
void freeaddrinfo(struct addrinfo *ai);
|
||||
#endif /* !HAVE_FREEADDRINFO */
|
||||
|
||||
#endif /* _FAKE_GETADDRINFO_H */
|
@ -1,55 +0,0 @@
|
||||
/*
|
||||
* fake library for ssh
|
||||
*
|
||||
* This file includes getnameinfo().
|
||||
* These funtions are defined in rfc2133.
|
||||
*
|
||||
* But these functions are not implemented correctly. The minimum subset
|
||||
* is implemented for ssh use only. For exapmle, this routine assumes
|
||||
* that ai_family is AF_INET. Don't use it for another purpose.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#include "ssh.h"
|
||||
|
||||
RCSID("$Id: fake-getnameinfo.c,v 1.2 2001/02/09 01:55:36 djm Exp $");
|
||||
|
||||
#ifndef HAVE_GETNAMEINFO
|
||||
int getnameinfo(const struct sockaddr *sa, size_t salen, char *host,
|
||||
size_t hostlen, char *serv, size_t servlen, int flags)
|
||||
{
|
||||
struct sockaddr_in *sin = (struct sockaddr_in *)sa;
|
||||
struct hostent *hp;
|
||||
char tmpserv[16];
|
||||
|
||||
if (serv) {
|
||||
snprintf(tmpserv, sizeof(tmpserv), "%d", ntohs(sin->sin_port));
|
||||
if (strlen(tmpserv) >= servlen)
|
||||
return EAI_MEMORY;
|
||||
else
|
||||
strcpy(serv, tmpserv);
|
||||
}
|
||||
|
||||
if (host) {
|
||||
if (flags & NI_NUMERICHOST) {
|
||||
if (strlen(inet_ntoa(sin->sin_addr)) >= hostlen)
|
||||
return EAI_MEMORY;
|
||||
|
||||
strcpy(host, inet_ntoa(sin->sin_addr));
|
||||
return 0;
|
||||
} else {
|
||||
hp = gethostbyaddr((char *)&sin->sin_addr,
|
||||
sizeof(struct in_addr), AF_INET);
|
||||
if (hp == NULL)
|
||||
return EAI_NODATA;
|
||||
|
||||
if (strlen(hp->h_name) >= hostlen)
|
||||
return EAI_MEMORY;
|
||||
|
||||
strcpy(host, hp->h_name);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif /* !HAVE_GETNAMEINFO */
|
@ -1,20 +0,0 @@
|
||||
/* $Id: fake-getnameinfo.h,v 1.2 2001/02/09 01:55:36 djm Exp $ */
|
||||
|
||||
#ifndef _FAKE_GETNAMEINFO_H
|
||||
#define _FAKE_GETNAMEINFO_H
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifndef HAVE_GETNAMEINFO
|
||||
int getnameinfo(const struct sockaddr *sa, size_t salen, char *host,
|
||||
size_t hostlen, char *serv, size_t servlen, int flags);
|
||||
#endif /* !HAVE_GETNAMEINFO */
|
||||
|
||||
#ifndef NI_MAXSERV
|
||||
# define NI_MAXSERV 32
|
||||
#endif /* !NI_MAXSERV */
|
||||
#ifndef NI_MAXHOST
|
||||
# define NI_MAXHOST 1025
|
||||
#endif /* !NI_MAXHOST */
|
||||
|
||||
#endif /* _FAKE_GETNAMEINFO_H */
|
@ -1,47 +0,0 @@
|
||||
/* $Id: fake-socket.h,v 1.3 2002/04/12 03:35:40 tim Exp $ */
|
||||
|
||||
#ifndef _FAKE_SOCKET_H
|
||||
#define _FAKE_SOCKET_H
|
||||
|
||||
#include "includes.h"
|
||||
#include "sys/types.h"
|
||||
|
||||
#ifndef HAVE_STRUCT_SOCKADDR_STORAGE
|
||||
# define _SS_MAXSIZE 128 /* Implementation specific max size */
|
||||
# define _SS_PADSIZE (_SS_MAXSIZE - sizeof (struct sockaddr))
|
||||
|
||||
struct sockaddr_storage {
|
||||
struct sockaddr ss_sa;
|
||||
char __ss_pad2[_SS_PADSIZE];
|
||||
};
|
||||
# define ss_family ss_sa.sa_family
|
||||
#endif /* !HAVE_STRUCT_SOCKADDR_STORAGE */
|
||||
|
||||
#ifndef IN6_IS_ADDR_LOOPBACK
|
||||
# define IN6_IS_ADDR_LOOPBACK(a) \
|
||||
(((u_int32_t *) (a))[0] == 0 && ((u_int32_t *) (a))[1] == 0 && \
|
||||
((u_int32_t *) (a))[2] == 0 && ((u_int32_t *) (a))[3] == htonl (1))
|
||||
#endif /* !IN6_IS_ADDR_LOOPBACK */
|
||||
|
||||
#ifndef HAVE_STRUCT_IN6_ADDR
|
||||
struct in6_addr {
|
||||
u_int8_t s6_addr[16];
|
||||
};
|
||||
#endif /* !HAVE_STRUCT_IN6_ADDR */
|
||||
|
||||
#ifndef HAVE_STRUCT_SOCKADDR_IN6
|
||||
struct sockaddr_in6 {
|
||||
unsigned short sin6_family;
|
||||
u_int16_t sin6_port;
|
||||
u_int32_t sin6_flowinfo;
|
||||
struct in6_addr sin6_addr;
|
||||
};
|
||||
#endif /* !HAVE_STRUCT_SOCKADDR_IN6 */
|
||||
|
||||
#ifndef AF_INET6
|
||||
/* Define it to something that should never appear */
|
||||
#define AF_INET6 AF_MAX
|
||||
#endif
|
||||
|
||||
#endif /* !_FAKE_SOCKET_H */
|
||||
|
@ -1,12 +0,0 @@
|
||||
/* $Id: getcwd.h,v 1.2 2001/02/09 01:55:36 djm Exp $ */
|
||||
|
||||
#ifndef _BSD_GETCWD_H
|
||||
#define _BSD_GETCWD_H
|
||||
#include "config.h"
|
||||
|
||||
#if !defined(HAVE_GETCWD)
|
||||
|
||||
char *getcwd(char *pt, size_t size);
|
||||
|
||||
#endif /* !defined(HAVE_GETCWD) */
|
||||
#endif /* _BSD_GETCWD_H */
|
@ -1,16 +0,0 @@
|
||||
/* $Id: getgrouplist.h,v 1.2 2001/02/09 01:55:36 djm Exp $ */
|
||||
|
||||
#ifndef _BSD_GETGROUPLIST_H
|
||||
#define _BSD_GETGROUPLIST_H
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifndef HAVE_GETGROUPLIST
|
||||
|
||||
#include <grp.h>
|
||||
|
||||
int getgrouplist(const char *, gid_t, gid_t *, int *);
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
@ -1,14 +0,0 @@
|
||||
/* $Id: getopt.h,v 1.4 2001/09/18 05:05:21 djm Exp $ */
|
||||
|
||||
#ifndef _BSDGETOPT_H
|
||||
#define _BSDGETOPT_H
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#if !defined(HAVE_GETOPT) || !defined(HAVE_GETOPT_OPTRESET)
|
||||
|
||||
int BSDgetopt(int argc, char * const *argv, const char *opts);
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _BSDGETOPT_H */
|
@ -1,12 +0,0 @@
|
||||
/* $Id: inet_aton.h,v 1.4 2001/07/16 02:07:51 tim Exp $ */
|
||||
|
||||
#ifndef _BSD_INET_ATON_H
|
||||
#define _BSD_INET_ATON_H
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifndef HAVE_INET_ATON
|
||||
int inet_aton(const char *cp, struct in_addr *addr);
|
||||
#endif /* HAVE_INET_ATON */
|
||||
|
||||
#endif /* _BSD_INET_ATON_H */
|
@ -1,12 +0,0 @@
|
||||
/* $Id: inet_ntoa.h,v 1.2 2001/02/09 01:55:36 djm Exp $ */
|
||||
|
||||
#ifndef _BSD_INET_NTOA_H
|
||||
#define _BSD_INET_NTOA_H
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#if defined(BROKEN_INET_NTOA) || !defined(HAVE_INET_NTOA)
|
||||
char *inet_ntoa(struct in_addr in);
|
||||
#endif /* defined(BROKEN_INET_NTOA) || !defined(HAVE_INET_NTOA) */
|
||||
|
||||
#endif /* _BSD_INET_NTOA_H */
|
@ -1,13 +0,0 @@
|
||||
/* $Id: inet_ntop.h,v 1.4 2001/08/09 00:56:53 mouring Exp $ */
|
||||
|
||||
#ifndef _BSD_INET_NTOP_H
|
||||
#define _BSD_INET_NTOP_H
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifndef HAVE_INET_NTOP
|
||||
const char *
|
||||
inet_ntop(int af, const void *src, char *dst, size_t size);
|
||||
#endif /* !HAVE_INET_NTOP */
|
||||
|
||||
#endif /* _BSD_INET_NTOP_H */
|
@ -1,13 +0,0 @@
|
||||
/* $Id: mktemp.h,v 1.3 2003/01/07 04:18:33 djm Exp $ */
|
||||
|
||||
#ifndef _BSD_MKTEMP_H
|
||||
#define _BSD_MKTEMP_H
|
||||
|
||||
#include "config.h"
|
||||
#if !defined(HAVE_MKDTEMP) || defined(HAVE_STRICT_MKSTEMP)
|
||||
int mkstemps(char *path, int slen);
|
||||
int mkstemp(char *path);
|
||||
char *mkdtemp(char *path);
|
||||
#endif /* !defined(HAVE_MKDTEMP) || defined(HAVE_STRICT_MKSTEMP) */
|
||||
|
||||
#endif /* _BSD_MKTEMP_H */
|
@ -1,13 +0,0 @@
|
||||
/* $Id: realpath.h,v 1.2 2001/02/09 01:55:36 djm Exp $ */
|
||||
|
||||
#ifndef _BSD_REALPATH_H
|
||||
#define _BSD_REALPATH_H
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#if !defined(HAVE_REALPATH) || defined(BROKEN_REALPATH)
|
||||
|
||||
char *realpath(const char *path, char *resolved);
|
||||
|
||||
#endif /* !defined(HAVE_REALPATH) || defined(BROKEN_REALPATH) */
|
||||
#endif /* _BSD_REALPATH_H */
|
@ -1,12 +0,0 @@
|
||||
/* $Id: rresvport.h,v 1.2 2001/02/09 01:55:36 djm Exp $ */
|
||||
|
||||
#ifndef _BSD_RRESVPORT_H
|
||||
#define _BSD_RRESVPORT_H
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifndef HAVE_RRESVPORT_AF
|
||||
int rresvport_af(int *alport, sa_family_t af);
|
||||
#endif /* !HAVE_RRESVPORT_AF */
|
||||
|
||||
#endif /* _BSD_RRESVPORT_H */
|
@ -1,14 +0,0 @@
|
||||
/* $Id: setenv.h,v 1.2 2001/02/09 01:55:36 djm Exp $ */
|
||||
|
||||
#ifndef _BSD_SETENV_H
|
||||
#define _BSD_SETENV_H
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifndef HAVE_SETENV
|
||||
|
||||
int setenv(register const char *name, register const char *value, int rewrite);
|
||||
|
||||
#endif /* !HAVE_SETENV */
|
||||
|
||||
#endif /* _BSD_SETENV_H */
|
@ -1,13 +0,0 @@
|
||||
/* $Id: setproctitle.h,v 1.3 2003/01/09 22:53:13 djm Exp $ */
|
||||
|
||||
#ifndef _BSD_SETPROCTITLE_H
|
||||
#define _BSD_SETPROCTITLE_H
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifndef HAVE_SETPROCTITLE
|
||||
void setproctitle(const char *fmt, ...);
|
||||
void compat_init_setproctitle(int argc, char *argv[]);
|
||||
#endif
|
||||
|
||||
#endif /* _BSD_SETPROCTITLE_H */
|
@ -1,12 +0,0 @@
|
||||
/* $Id: strlcat.h,v 1.2 2001/02/09 01:55:36 djm Exp $ */
|
||||
|
||||
#ifndef _BSD_STRLCAT_H
|
||||
#define _BSD_STRLCAT_H
|
||||
|
||||
#include "config.h"
|
||||
#ifndef HAVE_STRLCAT
|
||||
#include <sys/types.h>
|
||||
size_t strlcat(char *dst, const char *src, size_t siz);
|
||||
#endif /* !HAVE_STRLCAT */
|
||||
|
||||
#endif /* _BSD_STRLCAT_H */
|
@ -1,12 +0,0 @@
|
||||
/* $Id: strlcpy.h,v 1.2 2001/02/09 01:55:36 djm Exp $ */
|
||||
|
||||
#ifndef _BSD_STRLCPY_H
|
||||
#define _BSD_STRLCPY_H
|
||||
|
||||
#include "config.h"
|
||||
#ifndef HAVE_STRLCPY
|
||||
#include <sys/types.h>
|
||||
size_t strlcpy(char *dst, const char *src, size_t siz);
|
||||
#endif /* !HAVE_STRLCPY */
|
||||
|
||||
#endif /* _BSD_STRLCPY_H */
|
@ -1,7 +0,0 @@
|
||||
/* $Id: strmode.h,v 1.3 2001/06/09 02:22:17 mouring Exp $ */
|
||||
|
||||
#ifndef HAVE_STRMODE
|
||||
|
||||
void strmode(register mode_t mode, register char *p);
|
||||
|
||||
#endif
|
@ -1,12 +0,0 @@
|
||||
/* $Id: strsep.h,v 1.2 2001/02/09 01:55:36 djm Exp $ */
|
||||
|
||||
#ifndef _BSD_STRSEP_H
|
||||
#define _BSD_STRSEP_H
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifndef HAVE_STRSEP
|
||||
char *strsep(char **stringp, const char *delim);
|
||||
#endif /* HAVE_STRSEP */
|
||||
|
||||
#endif /* _BSD_STRSEP_H */
|
@ -1,23 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
void *xmmap(size_t size);
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: packet.h,v 1.37 2003/04/01 10:22:21 markus Exp $ */
|
||||
/* $OpenBSD: packet.h,v 1.40 2003/06/24 08:23:46 markus Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@ -62,8 +62,8 @@ int packet_get_keyiv_len(int);
|
||||
void packet_get_keyiv(int, u_char *, u_int);
|
||||
int packet_get_keycontext(int, u_char *);
|
||||
void packet_set_keycontext(int, u_char *);
|
||||
u_int32_t packet_get_seqnr(int);
|
||||
void packet_set_seqnr(int, u_int32_t);
|
||||
void packet_get_state(int, u_int32_t *, u_int64_t *, u_int32_t *);
|
||||
void packet_set_state(int, u_int32_t, u_int64_t, u_int32_t);
|
||||
int packet_get_ssh1_cipher(void);
|
||||
void packet_set_iv(int, u_char *);
|
||||
|
||||
@ -81,8 +81,8 @@ void packet_add_padding(u_char);
|
||||
void tty_make_modes(int, struct termios *);
|
||||
void tty_parse_modes(int, int *);
|
||||
|
||||
extern int max_packet_size;
|
||||
int packet_set_maxsize(int);
|
||||
extern u_int max_packet_size;
|
||||
u_int packet_set_maxsize(u_int);
|
||||
#define packet_get_maxsize() max_packet_size
|
||||
|
||||
/* don't allow remaining bytes after the end of the message */
|
||||
@ -90,10 +90,13 @@ int packet_set_maxsize(int);
|
||||
do { \
|
||||
int _len = packet_remaining(); \
|
||||
if (_len > 0) { \
|
||||
log("Packet integrity error (%d bytes remaining) at %s:%d", \
|
||||
logit("Packet integrity error (%d bytes remaining) at %s:%d", \
|
||||
_len ,__FILE__, __LINE__); \
|
||||
packet_disconnect("Packet integrity error."); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
int packet_need_rekeying(void);
|
||||
void packet_set_rekey_limit(u_int32_t);
|
||||
|
||||
#endif /* PACKET_H */
|
||||
|
@ -1,158 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1999 Dug Song. All rights reserved.
|
||||
* Copyright (c) 2002 Markus Friedl. 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.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#include "uuencode.h"
|
||||
|
||||
RCSID("$OpenBSD: radix.c,v 1.22 2002/09/09 14:54:15 markus Exp $");
|
||||
|
||||
#ifdef AFS
|
||||
#include <krb.h>
|
||||
|
||||
#include <radix.h>
|
||||
#include "bufaux.h"
|
||||
|
||||
int
|
||||
creds_to_radix(CREDENTIALS *creds, u_char *buf, size_t buflen)
|
||||
{
|
||||
Buffer b;
|
||||
int ret;
|
||||
|
||||
buffer_init(&b);
|
||||
|
||||
buffer_put_char(&b, 1); /* version */
|
||||
|
||||
buffer_append(&b, creds->service, strlen(creds->service));
|
||||
buffer_put_char(&b, '\0');
|
||||
buffer_append(&b, creds->instance, strlen(creds->instance));
|
||||
buffer_put_char(&b, '\0');
|
||||
buffer_append(&b, creds->realm, strlen(creds->realm));
|
||||
buffer_put_char(&b, '\0');
|
||||
buffer_append(&b, creds->pname, strlen(creds->pname));
|
||||
buffer_put_char(&b, '\0');
|
||||
buffer_append(&b, creds->pinst, strlen(creds->pinst));
|
||||
buffer_put_char(&b, '\0');
|
||||
|
||||
/* Null string to repeat the realm. */
|
||||
buffer_put_char(&b, '\0');
|
||||
|
||||
buffer_put_int(&b, creds->issue_date);
|
||||
buffer_put_int(&b, krb_life_to_time(creds->issue_date,
|
||||
creds->lifetime));
|
||||
buffer_append(&b, creds->session, sizeof(creds->session));
|
||||
buffer_put_short(&b, creds->kvno);
|
||||
|
||||
/* 32 bit size + data */
|
||||
buffer_put_string(&b, creds->ticket_st.dat, creds->ticket_st.length);
|
||||
|
||||
ret = uuencode(buffer_ptr(&b), buffer_len(&b), (char *)buf, buflen);
|
||||
|
||||
buffer_free(&b);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define GETSTRING(b, t, tlen) \
|
||||
do { \
|
||||
int i, found = 0; \
|
||||
for (i = 0; i < tlen; i++) { \
|
||||
if (buffer_len(b) == 0) \
|
||||
goto done; \
|
||||
t[i] = buffer_get_char(b); \
|
||||
if (t[i] == '\0') { \
|
||||
found = 1; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
if (!found) \
|
||||
goto done; \
|
||||
} while(0)
|
||||
|
||||
int
|
||||
radix_to_creds(const char *buf, CREDENTIALS *creds)
|
||||
{
|
||||
Buffer b;
|
||||
u_char *space;
|
||||
char c, version, *p;
|
||||
u_int endTime, len;
|
||||
int blen, ret;
|
||||
|
||||
ret = 0;
|
||||
blen = strlen(buf);
|
||||
|
||||
/* sanity check for size */
|
||||
if (blen > 8192)
|
||||
return 0;
|
||||
|
||||
buffer_init(&b);
|
||||
space = buffer_append_space(&b, blen);
|
||||
|
||||
/* check version and length! */
|
||||
len = uudecode(buf, space, blen);
|
||||
if (len < 1)
|
||||
goto done;
|
||||
|
||||
version = buffer_get_char(&b);
|
||||
|
||||
GETSTRING(&b, creds->service, sizeof creds->service);
|
||||
GETSTRING(&b, creds->instance, sizeof creds->instance);
|
||||
GETSTRING(&b, creds->realm, sizeof creds->realm);
|
||||
GETSTRING(&b, creds->pname, sizeof creds->pname);
|
||||
GETSTRING(&b, creds->pinst, sizeof creds->pinst);
|
||||
|
||||
if (buffer_len(&b) == 0)
|
||||
goto done;
|
||||
|
||||
/* Ignore possibly different realm. */
|
||||
while (buffer_len(&b) > 0 && (c = buffer_get_char(&b)) != '\0')
|
||||
;
|
||||
|
||||
if (buffer_len(&b) == 0)
|
||||
goto done;
|
||||
|
||||
creds->issue_date = buffer_get_int(&b);
|
||||
|
||||
endTime = buffer_get_int(&b);
|
||||
creds->lifetime = krb_time_to_life(creds->issue_date, endTime);
|
||||
|
||||
len = buffer_len(&b);
|
||||
if (len < sizeof(creds->session))
|
||||
goto done;
|
||||
memcpy(&creds->session, buffer_ptr(&b), sizeof(creds->session));
|
||||
buffer_consume(&b, sizeof(creds->session));
|
||||
|
||||
creds->kvno = buffer_get_short(&b);
|
||||
|
||||
p = buffer_get_string(&b, &len);
|
||||
if (len < 0 || len > sizeof(creds->ticket_st.dat))
|
||||
goto done;
|
||||
memcpy(&creds->ticket_st.dat, p, len);
|
||||
creds->ticket_st.length = len;
|
||||
|
||||
ret = 1;
|
||||
done:
|
||||
buffer_free(&b);
|
||||
return ret;
|
||||
}
|
||||
#endif /* AFS */
|
@ -1,28 +0,0 @@
|
||||
/* $OpenBSD: radix.h,v 1.4 2001/06/26 17:27:24 markus Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1999 Dug Song. 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 creds_to_radix(CREDENTIALS *, u_char *, size_t);
|
||||
int radix_to_creds(const char *, CREDENTIALS *);
|
@ -12,7 +12,7 @@
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: readconf.c,v 1.104 2003/04/01 10:22:21 markus Exp $");
|
||||
RCSID("$OpenBSD: readconf.c,v 1.121 2003/09/01 18:15:50 markus Exp $");
|
||||
RCSID("$FreeBSD$");
|
||||
|
||||
#include "ssh.h"
|
||||
@ -58,7 +58,6 @@ RCSID("$FreeBSD$");
|
||||
Host fascist.blob.com
|
||||
Port 23123
|
||||
User tylonen
|
||||
RhostsAuthentication no
|
||||
PasswordAuthentication no
|
||||
|
||||
Host puukko.hut.fi
|
||||
@ -76,7 +75,6 @@ RCSID("$FreeBSD$");
|
||||
Host *
|
||||
ForwardAgent no
|
||||
ForwardX11 no
|
||||
RhostsAuthentication yes
|
||||
PasswordAuthentication yes
|
||||
RSAAuthentication yes
|
||||
RhostsRSAAuthentication yes
|
||||
@ -92,18 +90,9 @@ RCSID("$FreeBSD$");
|
||||
|
||||
typedef enum {
|
||||
oBadOption,
|
||||
oForwardAgent, oForwardX11, oGatewayPorts, oRhostsAuthentication,
|
||||
oForwardAgent, oForwardX11, oGatewayPorts,
|
||||
oPasswordAuthentication, oRSAAuthentication,
|
||||
oChallengeResponseAuthentication, oXAuthLocation,
|
||||
#if defined(KRB4) || defined(KRB5)
|
||||
oKerberosAuthentication,
|
||||
#endif
|
||||
#if defined(AFS) || defined(KRB5)
|
||||
oKerberosTgtPassing,
|
||||
#endif
|
||||
#ifdef AFS
|
||||
oAFSTokenPassing,
|
||||
#endif
|
||||
oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
|
||||
oUser, oHost, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
|
||||
oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
|
||||
@ -115,9 +104,10 @@ typedef enum {
|
||||
oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
|
||||
oHostKeyAlgorithms, oBindAddress, oSmartcardDevice,
|
||||
oClearAllForwardings, oNoHostAuthenticationForLocalhost,
|
||||
oEnableSSHKeysign,
|
||||
oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
|
||||
oAddressFamily, oGssAuthentication, oGssDelegateCreds,
|
||||
oVersionAddendum,
|
||||
oDeprecated
|
||||
oDeprecated, oUnsupported
|
||||
} OpCodes;
|
||||
|
||||
/* Textual representations of the tokens. */
|
||||
@ -131,7 +121,7 @@ static struct {
|
||||
{ "xauthlocation", oXAuthLocation },
|
||||
{ "gatewayports", oGatewayPorts },
|
||||
{ "useprivilegedport", oUsePrivilegedPort },
|
||||
{ "rhostsauthentication", oRhostsAuthentication },
|
||||
{ "rhostsauthentication", oDeprecated },
|
||||
{ "passwordauthentication", oPasswordAuthentication },
|
||||
{ "kbdinteractiveauthentication", oKbdInteractiveAuthentication },
|
||||
{ "kbdinteractivedevices", oKbdInteractiveDevices },
|
||||
@ -143,14 +133,15 @@ static struct {
|
||||
{ "challengeresponseauthentication", oChallengeResponseAuthentication },
|
||||
{ "skeyauthentication", oChallengeResponseAuthentication }, /* alias */
|
||||
{ "tisauthentication", oChallengeResponseAuthentication }, /* alias */
|
||||
#if defined(KRB4) || defined(KRB5)
|
||||
{ "kerberosauthentication", oKerberosAuthentication },
|
||||
#endif
|
||||
#if defined(AFS) || defined(KRB5)
|
||||
{ "kerberostgtpassing", oKerberosTgtPassing },
|
||||
#endif
|
||||
#ifdef AFS
|
||||
{ "afstokenpassing", oAFSTokenPassing },
|
||||
{ "kerberosauthentication", oUnsupported },
|
||||
{ "kerberostgtpassing", oUnsupported },
|
||||
{ "afstokenpassing", oUnsupported },
|
||||
#if defined(GSSAPI)
|
||||
{ "gssapiauthentication", oGssAuthentication },
|
||||
{ "gssapidelegatecredentials", oGssDelegateCreds },
|
||||
#else
|
||||
{ "gssapiauthentication", oUnsupported },
|
||||
{ "gssapidelegatecredentials", oUnsupported },
|
||||
#endif
|
||||
{ "fallbacktorsh", oDeprecated },
|
||||
{ "usersh", oDeprecated },
|
||||
@ -186,10 +177,22 @@ static struct {
|
||||
{ "preferredauthentications", oPreferredAuthentications },
|
||||
{ "hostkeyalgorithms", oHostKeyAlgorithms },
|
||||
{ "bindaddress", oBindAddress },
|
||||
#ifdef SMARTCARD
|
||||
{ "smartcarddevice", oSmartcardDevice },
|
||||
#else
|
||||
{ "smartcarddevice", oUnsupported },
|
||||
#endif
|
||||
{ "clearallforwardings", oClearAllForwardings },
|
||||
{ "enablesshkeysign", oEnableSSHKeysign },
|
||||
#ifdef DNS
|
||||
{ "verifyhostkeydns", oVerifyHostKeyDNS },
|
||||
#else
|
||||
{ "verifyhostkeydns", oUnsupported },
|
||||
#endif
|
||||
{ "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost },
|
||||
{ "rekeylimit", oRekeyLimit },
|
||||
{ "connecttimeout", oConnectTimeout },
|
||||
{ "addressfamily", oAddressFamily },
|
||||
{ "versionaddendum", oVersionAddendum },
|
||||
{ NULL, oBadOption }
|
||||
};
|
||||
@ -284,6 +287,13 @@ process_config_line(Options *options, const char *host,
|
||||
u_short fwd_port, fwd_host_port;
|
||||
char sfwd_host_port[6];
|
||||
|
||||
/* Strip trailing whitespace */
|
||||
for(len = strlen(line) - 1; len > 0; len--) {
|
||||
if (strchr(WHITESPACE, line[len]) == NULL)
|
||||
break;
|
||||
line[len] = '\0';
|
||||
}
|
||||
|
||||
s = line;
|
||||
/* Get the keyword. (Each line is supposed to begin with a keyword). */
|
||||
keyword = strdelim(&s);
|
||||
@ -300,6 +310,20 @@ process_config_line(Options *options, const char *host,
|
||||
/* don't panic, but count bad options */
|
||||
return -1;
|
||||
/* NOTREACHED */
|
||||
case oConnectTimeout:
|
||||
intptr = &options->connection_timeout;
|
||||
/* parse_time: */
|
||||
arg = strdelim(&s);
|
||||
if (!arg || *arg == '\0')
|
||||
fatal("%s line %d: missing time value.",
|
||||
filename, linenum);
|
||||
if ((value = convtime(arg)) == -1)
|
||||
fatal("%s line %d: invalid time value.",
|
||||
filename, linenum);
|
||||
if (*intptr == -1)
|
||||
*intptr = value;
|
||||
break;
|
||||
|
||||
case oForwardAgent:
|
||||
intptr = &options->forward_agent;
|
||||
parse_flag:
|
||||
@ -329,10 +353,6 @@ process_config_line(Options *options, const char *host,
|
||||
intptr = &options->use_privileged_port;
|
||||
goto parse_flag;
|
||||
|
||||
case oRhostsAuthentication:
|
||||
intptr = &options->rhosts_authentication;
|
||||
goto parse_flag;
|
||||
|
||||
case oPasswordAuthentication:
|
||||
intptr = &options->password_authentication;
|
||||
goto parse_flag;
|
||||
@ -364,21 +384,15 @@ process_config_line(Options *options, const char *host,
|
||||
case oChallengeResponseAuthentication:
|
||||
intptr = &options->challenge_response_authentication;
|
||||
goto parse_flag;
|
||||
#if defined(KRB4) || defined(KRB5)
|
||||
case oKerberosAuthentication:
|
||||
intptr = &options->kerberos_authentication;
|
||||
|
||||
case oGssAuthentication:
|
||||
intptr = &options->gss_authentication;
|
||||
goto parse_flag;
|
||||
#endif
|
||||
#if defined(AFS) || defined(KRB5)
|
||||
case oKerberosTgtPassing:
|
||||
intptr = &options->kerberos_tgt_passing;
|
||||
|
||||
case oGssDelegateCreds:
|
||||
intptr = &options->gss_deleg_creds;
|
||||
goto parse_flag;
|
||||
#endif
|
||||
#ifdef AFS
|
||||
case oAFSTokenPassing:
|
||||
intptr = &options->afs_token_passing;
|
||||
goto parse_flag;
|
||||
#endif
|
||||
|
||||
case oBatchMode:
|
||||
intptr = &options->batch_mode;
|
||||
goto parse_flag;
|
||||
@ -387,6 +401,10 @@ process_config_line(Options *options, const char *host,
|
||||
intptr = &options->check_host_ip;
|
||||
goto parse_flag;
|
||||
|
||||
case oVerifyHostKeyDNS:
|
||||
intptr = &options->verify_host_key_dns;
|
||||
goto parse_flag;
|
||||
|
||||
case oStrictHostKeyChecking:
|
||||
intptr = &options->strict_host_key_checking;
|
||||
arg = strdelim(&s);
|
||||
@ -426,6 +444,31 @@ process_config_line(Options *options, const char *host,
|
||||
intptr = &options->compression_level;
|
||||
goto parse_int;
|
||||
|
||||
case oRekeyLimit:
|
||||
intptr = &options->rekey_limit;
|
||||
arg = strdelim(&s);
|
||||
if (!arg || *arg == '\0')
|
||||
fatal("%.200s line %d: Missing argument.", filename, linenum);
|
||||
if (arg[0] < '0' || arg[0] > '9')
|
||||
fatal("%.200s line %d: Bad number.", filename, linenum);
|
||||
value = strtol(arg, &endofnumber, 10);
|
||||
if (arg == endofnumber)
|
||||
fatal("%.200s line %d: Bad number.", filename, linenum);
|
||||
switch (toupper(*endofnumber)) {
|
||||
case 'K':
|
||||
value *= 1<<10;
|
||||
break;
|
||||
case 'M':
|
||||
value *= 1<<20;
|
||||
break;
|
||||
case 'G':
|
||||
value *= 1<<30;
|
||||
break;
|
||||
}
|
||||
if (*activep && *intptr == -1)
|
||||
*intptr = value;
|
||||
break;
|
||||
|
||||
case oIdentityFile:
|
||||
arg = strdelim(&s);
|
||||
if (!arg || *arg == '\0')
|
||||
@ -492,6 +535,8 @@ process_config_line(Options *options, const char *host,
|
||||
goto parse_string;
|
||||
|
||||
case oProxyCommand:
|
||||
if (s == NULL)
|
||||
fatal("%.200s line %d: Missing argument.", filename, linenum);
|
||||
charptr = &options->proxy_command;
|
||||
len = strspn(s, WHITESPACE "=");
|
||||
if (*activep && *charptr == NULL)
|
||||
@ -629,7 +674,7 @@ process_config_line(Options *options, const char *host,
|
||||
fatal("%.200s line %d: Badly formatted port number.",
|
||||
filename, linenum);
|
||||
if (*activep)
|
||||
add_local_forward(options, fwd_port, "socks4", 0);
|
||||
add_local_forward(options, fwd_port, "socks", 0);
|
||||
break;
|
||||
|
||||
case oClearAllForwardings:
|
||||
@ -669,6 +714,21 @@ process_config_line(Options *options, const char *host,
|
||||
*intptr = value;
|
||||
break;
|
||||
|
||||
case oAddressFamily:
|
||||
arg = strdelim(&s);
|
||||
intptr = &options->address_family;
|
||||
if (strcasecmp(arg, "inet") == 0)
|
||||
value = AF_INET;
|
||||
else if (strcasecmp(arg, "inet6") == 0)
|
||||
value = AF_INET6;
|
||||
else if (strcasecmp(arg, "any") == 0)
|
||||
value = AF_UNSPEC;
|
||||
else
|
||||
fatal("Unsupported AddressFamily \"%s\"", arg);
|
||||
if (*activep && *intptr == -1)
|
||||
*intptr = value;
|
||||
break;
|
||||
|
||||
case oEnableSSHKeysign:
|
||||
intptr = &options->enable_ssh_keysign;
|
||||
goto parse_flag;
|
||||
@ -685,6 +745,11 @@ process_config_line(Options *options, const char *host,
|
||||
filename, linenum, keyword);
|
||||
return 0;
|
||||
|
||||
case oUnsupported:
|
||||
error("%s line %d: Unsupported option \"%s\"",
|
||||
filename, linenum, keyword);
|
||||
return 0;
|
||||
|
||||
default:
|
||||
fatal("process_config_line: Unimplemented opcode %d", opcode);
|
||||
}
|
||||
@ -754,19 +819,11 @@ initialize_options(Options * options)
|
||||
options->xauth_location = NULL;
|
||||
options->gateway_ports = -1;
|
||||
options->use_privileged_port = -1;
|
||||
options->rhosts_authentication = -1;
|
||||
options->rsa_authentication = -1;
|
||||
options->pubkey_authentication = -1;
|
||||
options->challenge_response_authentication = -1;
|
||||
#if defined(KRB4) || defined(KRB5)
|
||||
options->kerberos_authentication = -1;
|
||||
#endif
|
||||
#if defined(AFS) || defined(KRB5)
|
||||
options->kerberos_tgt_passing = -1;
|
||||
#endif
|
||||
#ifdef AFS
|
||||
options->afs_token_passing = -1;
|
||||
#endif
|
||||
options->gss_authentication = -1;
|
||||
options->gss_deleg_creds = -1;
|
||||
options->password_authentication = -1;
|
||||
options->kbd_interactive_authentication = -1;
|
||||
options->kbd_interactive_devices = NULL;
|
||||
@ -779,7 +836,9 @@ initialize_options(Options * options)
|
||||
options->keepalives = -1;
|
||||
options->compression_level = -1;
|
||||
options->port = -1;
|
||||
options->address_family = -1;
|
||||
options->connection_attempts = -1;
|
||||
options->connection_timeout = -1;
|
||||
options->number_of_password_prompts = -1;
|
||||
options->cipher = -1;
|
||||
options->ciphers = NULL;
|
||||
@ -805,6 +864,8 @@ initialize_options(Options * options)
|
||||
options->smartcard_device = NULL;
|
||||
options->enable_ssh_keysign = - 1;
|
||||
options->no_host_authentication_for_localhost = - 1;
|
||||
options->rekey_limit = - 1;
|
||||
options->verify_host_key_dns = -1;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -827,26 +888,16 @@ fill_default_options(Options * options)
|
||||
options->gateway_ports = 0;
|
||||
if (options->use_privileged_port == -1)
|
||||
options->use_privileged_port = 0;
|
||||
if (options->rhosts_authentication == -1)
|
||||
options->rhosts_authentication = 0;
|
||||
if (options->rsa_authentication == -1)
|
||||
options->rsa_authentication = 1;
|
||||
if (options->pubkey_authentication == -1)
|
||||
options->pubkey_authentication = 1;
|
||||
if (options->challenge_response_authentication == -1)
|
||||
options->challenge_response_authentication = 1;
|
||||
#if defined(KRB4) || defined(KRB5)
|
||||
if (options->kerberos_authentication == -1)
|
||||
options->kerberos_authentication = 1;
|
||||
#endif
|
||||
#if defined(AFS) || defined(KRB5)
|
||||
if (options->kerberos_tgt_passing == -1)
|
||||
options->kerberos_tgt_passing = 1;
|
||||
#endif
|
||||
#ifdef AFS
|
||||
if (options->afs_token_passing == -1)
|
||||
options->afs_token_passing = 1;
|
||||
#endif
|
||||
if (options->gss_authentication == -1)
|
||||
options->gss_authentication = 1;
|
||||
if (options->gss_deleg_creds == -1)
|
||||
options->gss_deleg_creds = 0;
|
||||
if (options->password_authentication == -1)
|
||||
options->password_authentication = 1;
|
||||
if (options->kbd_interactive_authentication == -1)
|
||||
@ -869,6 +920,8 @@ fill_default_options(Options * options)
|
||||
options->compression_level = 6;
|
||||
if (options->port == -1)
|
||||
options->port = 0; /* Filled in ssh_connect. */
|
||||
if (options->address_family == -1)
|
||||
options->address_family = AF_UNSPEC;
|
||||
if (options->connection_attempts == -1)
|
||||
options->connection_attempts = 1;
|
||||
if (options->number_of_password_prompts == -1)
|
||||
@ -921,6 +974,10 @@ fill_default_options(Options * options)
|
||||
options->no_host_authentication_for_localhost = 0;
|
||||
if (options->enable_ssh_keysign == -1)
|
||||
options->enable_ssh_keysign = 0;
|
||||
if (options->rekey_limit == -1)
|
||||
options->rekey_limit = 0;
|
||||
if (options->verify_host_key_dns == -1)
|
||||
options->verify_host_key_dns = 0;
|
||||
/* options->proxy_command should not be set by default */
|
||||
/* options->user will be set in the main program if appropriate */
|
||||
/* options->hostname will be set in the main program if appropriate */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: readconf.h,v 1.46 2003/04/01 10:22:21 markus Exp $ */
|
||||
/* $OpenBSD: readconf.h,v 1.55 2003/09/01 18:15:50 markus Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@ -33,7 +33,6 @@ typedef struct {
|
||||
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. */
|
||||
int rhosts_authentication; /* Try rhosts authentication. */
|
||||
int rhosts_rsa_authentication; /* Try rhosts with RSA
|
||||
* authentication. */
|
||||
int rsa_authentication; /* Try RSA authentication. */
|
||||
@ -41,15 +40,8 @@ typedef struct {
|
||||
int hostbased_authentication; /* ssh2's rhosts_rsa */
|
||||
int challenge_response_authentication;
|
||||
/* Try S/Key or TIS, authentication. */
|
||||
#if defined(KRB4) || defined(KRB5)
|
||||
int kerberos_authentication; /* Try Kerberos authentication. */
|
||||
#endif
|
||||
#if defined(AFS) || defined(KRB5)
|
||||
int kerberos_tgt_passing; /* Try Kerberos TGT passing. */
|
||||
#endif
|
||||
#ifdef AFS
|
||||
int afs_token_passing; /* Try AFS token passing. */
|
||||
#endif
|
||||
int gss_authentication; /* Try GSS authentication */
|
||||
int gss_deleg_creds; /* Delegate GSS credentials */
|
||||
int password_authentication; /* Try password
|
||||
* authentication. */
|
||||
int kbd_interactive_authentication; /* Try keyboard-interactive auth. */
|
||||
@ -64,8 +56,11 @@ typedef struct {
|
||||
LogLevel log_level; /* Level for logging. */
|
||||
|
||||
int port; /* Port to connect. */
|
||||
int address_family;
|
||||
int connection_attempts; /* Max attempts (seconds) before
|
||||
* giving up */
|
||||
int connection_timeout; /* Max time (seconds) before
|
||||
* aborting connection attempt */
|
||||
int number_of_password_prompts; /* Max number of password
|
||||
* prompts. */
|
||||
int cipher; /* Cipher to use. */
|
||||
@ -86,6 +81,7 @@ typedef struct {
|
||||
char *preferred_authentications;
|
||||
char *bind_address; /* local socket address for connection to sshd */
|
||||
char *smartcard_device; /* Smartcard reader device */
|
||||
int verify_host_key_dns; /* Verify host key using DNS */
|
||||
|
||||
int num_identity_files; /* Number of files for RSA/DSA identities. */
|
||||
char *identity_files[SSH_MAX_IDENTITY_FILES];
|
||||
@ -101,6 +97,7 @@ typedef struct {
|
||||
int clear_forwardings;
|
||||
|
||||
int enable_ssh_keysign;
|
||||
int rekey_limit;
|
||||
int no_host_authentication_for_localhost;
|
||||
} Options;
|
||||
|
||||
|
@ -1,2 +0,0 @@
|
||||
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEAt6ttBacbgvLPsF1VWWfT51t55/5Mj62Xp8EaoH5SNSaLiGIgrrja077lKEept75U4uKFUYU5JJX9GPE9A7Y43LXv+/A6Jm4rEj/U0s4H8tf0UmzVC3t6xh0sRK0hYVNILyoHnIAgdY8CmOiybw7p6DxJY8MRAehD3n9+kFcachU= root@xenon
|
||||
1024 35 132789427207755621599908461558918671787816692978751485815532032934821830960131244604702969298486352138126114080367609979552547448841583955126231410604842765726397407176910594168641969541792069550006878863592030567875913190224374005367884774859544943329148178663694126456638431428703289837638970464685771819219 root@xenon
|
@ -52,11 +52,7 @@
|
||||
* 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.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
@ -75,7 +71,7 @@
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: scp.c,v 1.102 2003/03/05 22:33:43 markus Exp $");
|
||||
RCSID("$OpenBSD: scp.c,v 1.108 2003/07/18 01:54:25 deraadt Exp $");
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "atomicio.h"
|
||||
@ -111,7 +107,16 @@ int showprogress = 1;
|
||||
char *ssh_program = _PATH_SSH_PROGRAM;
|
||||
|
||||
/* This is used to store the pid of ssh_program */
|
||||
pid_t do_cmd_pid;
|
||||
pid_t do_cmd_pid = -1;
|
||||
|
||||
static void
|
||||
killchild(int signo)
|
||||
{
|
||||
if (do_cmd_pid > 1)
|
||||
kill(do_cmd_pid, signo);
|
||||
|
||||
_exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* This function executes the given command as the specified user on the
|
||||
@ -146,7 +151,7 @@ do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout, int argc)
|
||||
close(reserved[0]);
|
||||
close(reserved[1]);
|
||||
|
||||
/* For a child to execute the command on the remote host using ssh. */
|
||||
/* Fork a child to execute the command on the remote host using ssh. */
|
||||
do_cmd_pid = fork();
|
||||
if (do_cmd_pid == 0) {
|
||||
/* Child. */
|
||||
@ -174,6 +179,9 @@ do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout, int argc)
|
||||
*fdout = pin[1];
|
||||
close(pout[1]);
|
||||
*fdin = pout[0];
|
||||
signal(SIGTERM, killchild);
|
||||
signal(SIGINT, killchild);
|
||||
signal(SIGHUP, killchild);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -206,9 +214,7 @@ void toremote(char *, int, char *[]);
|
||||
void usage(void);
|
||||
|
||||
int
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int ch, fflag, tflag, status;
|
||||
double speed;
|
||||
@ -216,7 +222,7 @@ main(argc, argv)
|
||||
extern char *optarg;
|
||||
extern int optind;
|
||||
|
||||
__progname = get_progname(argv[0]);
|
||||
__progname = ssh_get_progname(argv[0]);
|
||||
|
||||
args.list = NULL;
|
||||
addargs(&args, "ssh"); /* overwritten with ssh_program */
|
||||
@ -292,7 +298,7 @@ main(argc, argv)
|
||||
argv += optind;
|
||||
|
||||
if ((pwd = getpwuid(userid = getuid())) == NULL)
|
||||
fatal("unknown user %d", (int) userid);
|
||||
fatal("unknown user %u", (u_int) userid);
|
||||
|
||||
if (!isatty(STDERR_FILENO))
|
||||
showprogress = 0;
|
||||
@ -353,9 +359,7 @@ main(argc, argv)
|
||||
}
|
||||
|
||||
void
|
||||
toremote(targ, argc, argv)
|
||||
char *targ, *argv[];
|
||||
int argc;
|
||||
toremote(char *targ, int argc, char **argv)
|
||||
{
|
||||
int i, len;
|
||||
char *bp, *host, *src, *suser, *thost, *tuser;
|
||||
@ -443,9 +447,7 @@ toremote(targ, argc, argv)
|
||||
}
|
||||
|
||||
void
|
||||
tolocal(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
tolocal(int argc, char **argv)
|
||||
{
|
||||
int i, len;
|
||||
char *bp, *host, *src, *suser;
|
||||
@ -494,9 +496,7 @@ tolocal(argc, argv)
|
||||
}
|
||||
|
||||
void
|
||||
source(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
source(int argc, char **argv)
|
||||
{
|
||||
struct stat stb;
|
||||
static BUF buffer;
|
||||
@ -549,25 +549,18 @@ syserr: run_err("%s: %s", name, strerror(errno));
|
||||
(void) snprintf(buf, sizeof buf, "T%lu 0 %lu 0\n",
|
||||
(u_long) stb.st_mtime,
|
||||
(u_long) stb.st_atime);
|
||||
(void) atomicio(write, remout, buf, strlen(buf));
|
||||
(void) atomicio(vwrite, remout, buf, strlen(buf));
|
||||
if (response() < 0)
|
||||
goto next;
|
||||
}
|
||||
#define FILEMODEMASK (S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO)
|
||||
#ifdef HAVE_LONG_LONG_INT
|
||||
snprintf(buf, sizeof buf, "C%04o %lld %s\n",
|
||||
(u_int) (stb.st_mode & FILEMODEMASK),
|
||||
(long long)stb.st_size, last);
|
||||
#else
|
||||
/* XXX: Handle integer overflow? */
|
||||
snprintf(buf, sizeof buf, "C%04o %lu %s\n",
|
||||
(u_int) (stb.st_mode & FILEMODEMASK),
|
||||
(u_long) stb.st_size, last);
|
||||
#endif
|
||||
(int64_t)stb.st_size, last);
|
||||
if (verbose_mode) {
|
||||
fprintf(stderr, "Sending file modes: %s", buf);
|
||||
}
|
||||
(void) atomicio(write, remout, buf, strlen(buf));
|
||||
(void) atomicio(vwrite, remout, buf, strlen(buf));
|
||||
if (response() < 0)
|
||||
goto next;
|
||||
if ((bp = allocbuf(&buffer, fd, 2048)) == NULL) {
|
||||
@ -587,9 +580,9 @@ next: (void) close(fd);
|
||||
haderr = result >= 0 ? EIO : errno;
|
||||
}
|
||||
if (haderr)
|
||||
(void) atomicio(write, remout, bp->buf, amt);
|
||||
(void) atomicio(vwrite, remout, bp->buf, amt);
|
||||
else {
|
||||
result = atomicio(write, remout, bp->buf, amt);
|
||||
result = atomicio(vwrite, remout, bp->buf, amt);
|
||||
if (result != amt)
|
||||
haderr = result >= 0 ? EIO : errno;
|
||||
statbytes += result;
|
||||
@ -603,7 +596,7 @@ next: (void) close(fd);
|
||||
if (close(fd) < 0 && !haderr)
|
||||
haderr = errno;
|
||||
if (!haderr)
|
||||
(void) atomicio(write, remout, "", 1);
|
||||
(void) atomicio(vwrite, remout, "", 1);
|
||||
else
|
||||
run_err("%s: %s", name, strerror(haderr));
|
||||
(void) response();
|
||||
@ -611,9 +604,7 @@ next: (void) close(fd);
|
||||
}
|
||||
|
||||
void
|
||||
rsource(name, statp)
|
||||
char *name;
|
||||
struct stat *statp;
|
||||
rsource(char *name, struct stat *statp)
|
||||
{
|
||||
DIR *dirp;
|
||||
struct dirent *dp;
|
||||
@ -632,7 +623,7 @@ rsource(name, statp)
|
||||
(void) snprintf(path, sizeof(path), "T%lu 0 %lu 0\n",
|
||||
(u_long) statp->st_mtime,
|
||||
(u_long) statp->st_atime);
|
||||
(void) atomicio(write, remout, path, strlen(path));
|
||||
(void) atomicio(vwrite, remout, path, strlen(path));
|
||||
if (response() < 0) {
|
||||
closedir(dirp);
|
||||
return;
|
||||
@ -642,7 +633,7 @@ rsource(name, statp)
|
||||
(u_int) (statp->st_mode & FILEMODEMASK), 0, last);
|
||||
if (verbose_mode)
|
||||
fprintf(stderr, "Entering directory: %s", path);
|
||||
(void) atomicio(write, remout, path, strlen(path));
|
||||
(void) atomicio(vwrite, remout, path, strlen(path));
|
||||
if (response() < 0) {
|
||||
closedir(dirp);
|
||||
return;
|
||||
@ -661,7 +652,7 @@ rsource(name, statp)
|
||||
source(1, vect);
|
||||
}
|
||||
(void) closedir(dirp);
|
||||
(void) atomicio(write, remout, "E\n", 2);
|
||||
(void) atomicio(vwrite, remout, "E\n", 2);
|
||||
(void) response();
|
||||
}
|
||||
|
||||
@ -720,9 +711,7 @@ bwlimit(int amount)
|
||||
}
|
||||
|
||||
void
|
||||
sink(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
sink(int argc, char **argv)
|
||||
{
|
||||
static BUF buffer;
|
||||
struct stat stb;
|
||||
@ -753,7 +742,7 @@ sink(argc, argv)
|
||||
if (targetshouldbedirectory)
|
||||
verifydir(targ);
|
||||
|
||||
(void) atomicio(write, remout, "", 1);
|
||||
(void) atomicio(vwrite, remout, "", 1);
|
||||
if (stat(targ, &stb) == 0 && S_ISDIR(stb.st_mode))
|
||||
targisdir = 1;
|
||||
for (first = 1;; first = 0) {
|
||||
@ -771,7 +760,7 @@ sink(argc, argv)
|
||||
|
||||
if (buf[0] == '\01' || buf[0] == '\02') {
|
||||
if (iamremote == 0)
|
||||
(void) atomicio(write, STDERR_FILENO,
|
||||
(void) atomicio(vwrite, STDERR_FILENO,
|
||||
buf + 1, strlen(buf + 1));
|
||||
if (buf[0] == '\02')
|
||||
exit(1);
|
||||
@ -779,7 +768,7 @@ sink(argc, argv)
|
||||
continue;
|
||||
}
|
||||
if (buf[0] == 'E') {
|
||||
(void) atomicio(write, remout, "", 1);
|
||||
(void) atomicio(vwrite, remout, "", 1);
|
||||
return;
|
||||
}
|
||||
if (ch == '\n')
|
||||
@ -801,7 +790,7 @@ sink(argc, argv)
|
||||
atime.tv_usec = strtol(cp, &cp, 10);
|
||||
if (!cp || *cp++ != '\0')
|
||||
SCREWUP("atime.usec not delimited");
|
||||
(void) atomicio(write, remout, "", 1);
|
||||
(void) atomicio(vwrite, remout, "", 1);
|
||||
continue;
|
||||
}
|
||||
if (*cp != 'C' && *cp != 'D') {
|
||||
@ -886,7 +875,7 @@ sink(argc, argv)
|
||||
bad: run_err("%s: %s", np, strerror(errno));
|
||||
continue;
|
||||
}
|
||||
(void) atomicio(write, remout, "", 1);
|
||||
(void) atomicio(vwrite, remout, "", 1);
|
||||
if ((bp = allocbuf(&buffer, ofd, 4096)) == NULL) {
|
||||
(void) close(ofd);
|
||||
continue;
|
||||
@ -923,7 +912,7 @@ bad: run_err("%s: %s", np, strerror(errno));
|
||||
if (count == bp->cnt) {
|
||||
/* Keep reading so we stay sync'd up. */
|
||||
if (wrerr == NO) {
|
||||
j = atomicio(write, ofd, bp->buf, count);
|
||||
j = atomicio(vwrite, ofd, bp->buf, count);
|
||||
if (j != count) {
|
||||
wrerr = YES;
|
||||
wrerrno = j >= 0 ? EIO : errno;
|
||||
@ -936,7 +925,7 @@ bad: run_err("%s: %s", np, strerror(errno));
|
||||
if (showprogress)
|
||||
stop_progress_meter();
|
||||
if (count != 0 && wrerr == NO &&
|
||||
(j = atomicio(write, ofd, bp->buf, count)) != count) {
|
||||
(j = atomicio(vwrite, ofd, bp->buf, count)) != count) {
|
||||
wrerr = YES;
|
||||
wrerrno = j >= 0 ? EIO : errno;
|
||||
}
|
||||
@ -981,7 +970,7 @@ bad: run_err("%s: %s", np, strerror(errno));
|
||||
run_err("%s: %s", np, strerror(wrerrno));
|
||||
break;
|
||||
case NO:
|
||||
(void) atomicio(write, remout, "", 1);
|
||||
(void) atomicio(vwrite, remout, "", 1);
|
||||
break;
|
||||
case DISPLAYED:
|
||||
break;
|
||||
@ -1016,7 +1005,7 @@ response(void)
|
||||
} while (cp < &rbuf[sizeof(rbuf) - 1] && ch != '\n');
|
||||
|
||||
if (!iamremote)
|
||||
(void) atomicio(write, STDERR_FILENO, rbuf, cp - rbuf);
|
||||
(void) atomicio(vwrite, STDERR_FILENO, rbuf, cp - rbuf);
|
||||
++errs;
|
||||
if (resp == 1)
|
||||
return (-1);
|
||||
@ -1061,8 +1050,7 @@ run_err(const char *fmt,...)
|
||||
}
|
||||
|
||||
void
|
||||
verifydir(cp)
|
||||
char *cp;
|
||||
verifydir(char *cp)
|
||||
{
|
||||
struct stat stb;
|
||||
|
||||
@ -1076,8 +1064,7 @@ verifydir(cp)
|
||||
}
|
||||
|
||||
int
|
||||
okname(cp0)
|
||||
char *cp0;
|
||||
okname(char *cp0)
|
||||
{
|
||||
int c;
|
||||
char *cp;
|
||||
@ -1107,9 +1094,7 @@ bad: fprintf(stderr, "%s: invalid user name\n", cp0);
|
||||
}
|
||||
|
||||
BUF *
|
||||
allocbuf(bp, fd, blksize)
|
||||
BUF *bp;
|
||||
int fd, blksize;
|
||||
allocbuf(BUF *bp, int fd, int blksize)
|
||||
{
|
||||
size_t size;
|
||||
#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
|
||||
@ -1137,8 +1122,7 @@ allocbuf(bp, fd, blksize)
|
||||
}
|
||||
|
||||
void
|
||||
lostconn(signo)
|
||||
int signo;
|
||||
lostconn(int signo)
|
||||
{
|
||||
if (!iamremote)
|
||||
write(STDERR_FILENO, "lost connection\n", 16);
|
||||
|
@ -10,25 +10,9 @@
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: servconf.c,v 1.116 2003/02/21 09:05:53 markus Exp $");
|
||||
RCSID("$OpenBSD: servconf.c,v 1.127 2003/09/01 18:15:50 markus Exp $");
|
||||
RCSID("$FreeBSD$");
|
||||
|
||||
#if defined(KRB4)
|
||||
#include <krb.h>
|
||||
#endif
|
||||
#if defined(KRB5)
|
||||
#ifdef HEIMDAL
|
||||
#include <krb5.h>
|
||||
#else
|
||||
/* Bodge - but then, so is using the kerberos IV KEYFILE to get a Kerberos V
|
||||
* keytab */
|
||||
#define KEYFILE "/etc/krb5.keytab"
|
||||
#endif
|
||||
#endif
|
||||
#ifdef AFS
|
||||
#include <kafs.h>
|
||||
#endif
|
||||
|
||||
#include "ssh.h"
|
||||
#include "log.h"
|
||||
#include "servconf.h"
|
||||
@ -57,7 +41,7 @@ initialize_server_options(ServerOptions *options)
|
||||
memset(options, 0, sizeof(*options));
|
||||
|
||||
/* Portable-specific options */
|
||||
options->pam_authentication_via_kbd_int = -1;
|
||||
options->use_pam = -1;
|
||||
|
||||
/* Standard Options */
|
||||
options->num_ports = 0;
|
||||
@ -81,23 +65,16 @@ initialize_server_options(ServerOptions *options)
|
||||
options->keepalives = -1;
|
||||
options->log_facility = SYSLOG_FACILITY_NOT_SET;
|
||||
options->log_level = SYSLOG_LEVEL_NOT_SET;
|
||||
options->rhosts_authentication = -1;
|
||||
options->rhosts_rsa_authentication = -1;
|
||||
options->hostbased_authentication = -1;
|
||||
options->hostbased_uses_name_from_packet_only = -1;
|
||||
options->rsa_authentication = -1;
|
||||
options->pubkey_authentication = -1;
|
||||
#if defined(KRB4) || defined(KRB5)
|
||||
options->kerberos_authentication = -1;
|
||||
options->kerberos_or_local_passwd = -1;
|
||||
options->kerberos_ticket_cleanup = -1;
|
||||
#endif
|
||||
#if defined(AFS) || defined(KRB5)
|
||||
options->kerberos_tgt_passing = -1;
|
||||
#endif
|
||||
#ifdef AFS
|
||||
options->afs_token_passing = -1;
|
||||
#endif
|
||||
options->gss_authentication=-1;
|
||||
options->gss_cleanup_creds = -1;
|
||||
options->password_authentication = -1;
|
||||
options->kbd_interactive_authentication = -1;
|
||||
options->challenge_response_authentication = -1;
|
||||
@ -119,7 +96,7 @@ initialize_server_options(ServerOptions *options)
|
||||
options->max_startups_rate = -1;
|
||||
options->max_startups = -1;
|
||||
options->banner = NULL;
|
||||
options->verify_reverse_mapping = -1;
|
||||
options->use_dns = -1;
|
||||
options->client_alive_interval = -1;
|
||||
options->client_alive_count_max = -1;
|
||||
options->authorized_keys_file = NULL;
|
||||
@ -133,8 +110,8 @@ void
|
||||
fill_default_server_options(ServerOptions *options)
|
||||
{
|
||||
/* Portable-specific options */
|
||||
if (options->pam_authentication_via_kbd_int == -1)
|
||||
options->pam_authentication_via_kbd_int = 0;
|
||||
if (options->use_pam == -1)
|
||||
options->use_pam = 0;
|
||||
|
||||
/* Standard Options */
|
||||
if (options->protocol == SSH_PROTO_UNKNOWN)
|
||||
@ -187,8 +164,6 @@ fill_default_server_options(ServerOptions *options)
|
||||
options->log_facility = SYSLOG_FACILITY_AUTH;
|
||||
if (options->log_level == SYSLOG_LEVEL_NOT_SET)
|
||||
options->log_level = SYSLOG_LEVEL_INFO;
|
||||
if (options->rhosts_authentication == -1)
|
||||
options->rhosts_authentication = 0;
|
||||
if (options->rhosts_rsa_authentication == -1)
|
||||
options->rhosts_rsa_authentication = 0;
|
||||
if (options->hostbased_authentication == -1)
|
||||
@ -199,34 +174,16 @@ fill_default_server_options(ServerOptions *options)
|
||||
options->rsa_authentication = 1;
|
||||
if (options->pubkey_authentication == -1)
|
||||
options->pubkey_authentication = 1;
|
||||
#if defined(KRB4) && defined(KRB5)
|
||||
if (options->kerberos_authentication == -1)
|
||||
options->kerberos_authentication =
|
||||
(access(KEYFILE, R_OK) == 0 ||
|
||||
access(krb5_defkeyname, R_OK) == 0);
|
||||
#elif defined(KRB4)
|
||||
if (options->kerberos_authentication == -1)
|
||||
options->kerberos_authentication =
|
||||
(access(KEYFILE, R_OK) == 0);
|
||||
#elif defined(KRB5)
|
||||
if (options->kerberos_authentication == -1)
|
||||
options->kerberos_authentication =
|
||||
(access(krb5_defkeyname, R_OK) == 0);
|
||||
#endif
|
||||
#if defined(KRB4) || defined(KRB5)
|
||||
options->kerberos_authentication = 0;
|
||||
if (options->kerberos_or_local_passwd == -1)
|
||||
options->kerberos_or_local_passwd = 1;
|
||||
if (options->kerberos_ticket_cleanup == -1)
|
||||
options->kerberos_ticket_cleanup = 1;
|
||||
#endif
|
||||
#if defined(AFS) || defined(KRB5)
|
||||
if (options->kerberos_tgt_passing == -1)
|
||||
options->kerberos_tgt_passing = 0;
|
||||
#endif
|
||||
#ifdef AFS
|
||||
if (options->afs_token_passing == -1)
|
||||
options->afs_token_passing = 0;
|
||||
#endif
|
||||
if (options->gss_authentication == -1)
|
||||
options->gss_authentication = 0;
|
||||
if (options->gss_cleanup_creds == -1)
|
||||
options->gss_cleanup_creds = 1;
|
||||
if (options->password_authentication == -1)
|
||||
options->password_authentication = 1;
|
||||
if (options->kbd_interactive_authentication == -1)
|
||||
@ -251,8 +208,8 @@ fill_default_server_options(ServerOptions *options)
|
||||
options->max_startups_rate = 100; /* 100% */
|
||||
if (options->max_startups_begin == -1)
|
||||
options->max_startups_begin = options->max_startups;
|
||||
if (options->verify_reverse_mapping == -1)
|
||||
options->verify_reverse_mapping = 0;
|
||||
if (options->use_dns == -1)
|
||||
options->use_dns = 1;
|
||||
if (options->client_alive_interval == -1)
|
||||
options->client_alive_interval = 0;
|
||||
if (options->client_alive_count_max == -1)
|
||||
@ -286,21 +243,13 @@ fill_default_server_options(ServerOptions *options)
|
||||
typedef enum {
|
||||
sBadOption, /* == unknown option */
|
||||
/* Portable-specific options */
|
||||
sPAMAuthenticationViaKbdInt,
|
||||
sUsePAM,
|
||||
/* Standard Options */
|
||||
sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
|
||||
sPermitRootLogin, sLogFacility, sLogLevel,
|
||||
sRhostsAuthentication, sRhostsRSAAuthentication, sRSAAuthentication,
|
||||
#if defined(KRB4) || defined(KRB5)
|
||||
sRhostsRSAAuthentication, sRSAAuthentication,
|
||||
sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
|
||||
#endif
|
||||
#if defined(AFS) || defined(KRB5)
|
||||
sKerberosTgtPassing,
|
||||
#endif
|
||||
#ifdef AFS
|
||||
sAFSTokenPassing,
|
||||
#endif
|
||||
sChallengeResponseAuthentication,
|
||||
sKerberosTgtPassing, sChallengeResponseAuthentication,
|
||||
sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress,
|
||||
sPrintMotd, sPrintLastLog, sIgnoreRhosts,
|
||||
sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
|
||||
@ -309,12 +258,13 @@ typedef enum {
|
||||
sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
|
||||
sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
|
||||
sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem, sMaxStartups,
|
||||
sBanner, sVerifyReverseMapping, sHostbasedAuthentication,
|
||||
sBanner, sUseDNS, sHostbasedAuthentication,
|
||||
sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
|
||||
sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
|
||||
sGssAuthentication, sGssCleanupCreds,
|
||||
sUsePrivilegeSeparation,
|
||||
sVersionAddendum,
|
||||
sDeprecated
|
||||
sDeprecated, sUnsupported
|
||||
} ServerOpCodes;
|
||||
|
||||
/* Textual representation of the tokens. */
|
||||
@ -323,9 +273,12 @@ static struct {
|
||||
ServerOpCodes opcode;
|
||||
} keywords[] = {
|
||||
/* Portable-specific options */
|
||||
#if 0
|
||||
{ "PAMAuthenticationViaKbdInt", sPAMAuthenticationViaKbdInt },
|
||||
#ifdef USE_PAM
|
||||
{ "usepam", sUsePAM },
|
||||
#else
|
||||
{ "usepam", sUnsupported },
|
||||
#endif
|
||||
{ "pamauthenticationviakbdint", sDeprecated },
|
||||
/* Standard Options */
|
||||
{ "port", sPort },
|
||||
{ "hostkey", sHostKeyFile },
|
||||
@ -337,23 +290,30 @@ static struct {
|
||||
{ "permitrootlogin", sPermitRootLogin },
|
||||
{ "syslogfacility", sLogFacility },
|
||||
{ "loglevel", sLogLevel },
|
||||
{ "rhostsauthentication", sRhostsAuthentication },
|
||||
{ "rhostsauthentication", sDeprecated },
|
||||
{ "rhostsrsaauthentication", sRhostsRSAAuthentication },
|
||||
{ "hostbasedauthentication", sHostbasedAuthentication },
|
||||
{ "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly },
|
||||
{ "rsaauthentication", sRSAAuthentication },
|
||||
{ "pubkeyauthentication", sPubkeyAuthentication },
|
||||
{ "dsaauthentication", sPubkeyAuthentication }, /* alias */
|
||||
#if defined(KRB4) || defined(KRB5)
|
||||
#ifdef KRB5
|
||||
{ "kerberosauthentication", sKerberosAuthentication },
|
||||
{ "kerberosorlocalpasswd", sKerberosOrLocalPasswd },
|
||||
{ "kerberosticketcleanup", sKerberosTicketCleanup },
|
||||
#else
|
||||
{ "kerberosauthentication", sUnsupported },
|
||||
{ "kerberosorlocalpasswd", sUnsupported },
|
||||
{ "kerberosticketcleanup", sUnsupported },
|
||||
#endif
|
||||
#if defined(AFS) || defined(KRB5)
|
||||
{ "kerberostgtpassing", sKerberosTgtPassing },
|
||||
#endif
|
||||
#ifdef AFS
|
||||
{ "afstokenpassing", sAFSTokenPassing },
|
||||
{ "kerberostgtpassing", sUnsupported },
|
||||
{ "afstokenpassing", sUnsupported },
|
||||
#ifdef GSSAPI
|
||||
{ "gssapiauthentication", sGssAuthentication },
|
||||
{ "gssapicleanupcreds", sGssCleanupCreds },
|
||||
#else
|
||||
{ "gssapiauthentication", sUnsupported },
|
||||
{ "gssapicleanupcreds", sUnsupported },
|
||||
#endif
|
||||
{ "passwordauthentication", sPasswordAuthentication },
|
||||
{ "kbdinteractiveauthentication", sKbdInteractiveAuthentication },
|
||||
@ -387,8 +347,9 @@ static struct {
|
||||
{ "subsystem", sSubsystem },
|
||||
{ "maxstartups", sMaxStartups },
|
||||
{ "banner", sBanner },
|
||||
{ "verifyreversemapping", sVerifyReverseMapping },
|
||||
{ "reversemappingcheck", sVerifyReverseMapping },
|
||||
{ "usedns", sUseDNS },
|
||||
{ "verifyreversemapping", sDeprecated },
|
||||
{ "reversemappingcheck", sDeprecated },
|
||||
{ "clientaliveinterval", sClientAliveInterval },
|
||||
{ "clientalivecountmax", sClientAliveCountMax },
|
||||
{ "authorizedkeysfile", sAuthorizedKeysFile },
|
||||
@ -473,8 +434,8 @@ process_server_config_line(ServerOptions *options, char *line,
|
||||
opcode = parse_token(arg, filename, linenum);
|
||||
switch (opcode) {
|
||||
/* Portable-specific options */
|
||||
case sPAMAuthenticationViaKbdInt:
|
||||
intptr = &options->pam_authentication_via_kbd_int;
|
||||
case sUsePAM:
|
||||
intptr = &options->use_pam;
|
||||
goto parse_flag;
|
||||
|
||||
/* Standard Options */
|
||||
@ -637,10 +598,6 @@ process_server_config_line(ServerOptions *options, char *line,
|
||||
intptr = &options->ignore_user_known_hosts;
|
||||
goto parse_flag;
|
||||
|
||||
case sRhostsAuthentication:
|
||||
intptr = &options->rhosts_authentication;
|
||||
goto parse_flag;
|
||||
|
||||
case sRhostsRSAAuthentication:
|
||||
intptr = &options->rhosts_rsa_authentication;
|
||||
goto parse_flag;
|
||||
@ -660,7 +617,7 @@ process_server_config_line(ServerOptions *options, char *line,
|
||||
case sPubkeyAuthentication:
|
||||
intptr = &options->pubkey_authentication;
|
||||
goto parse_flag;
|
||||
#if defined(KRB4) || defined(KRB5)
|
||||
|
||||
case sKerberosAuthentication:
|
||||
intptr = &options->kerberos_authentication;
|
||||
goto parse_flag;
|
||||
@ -672,17 +629,14 @@ process_server_config_line(ServerOptions *options, char *line,
|
||||
case sKerberosTicketCleanup:
|
||||
intptr = &options->kerberos_ticket_cleanup;
|
||||
goto parse_flag;
|
||||
#endif
|
||||
#if defined(AFS) || defined(KRB5)
|
||||
case sKerberosTgtPassing:
|
||||
intptr = &options->kerberos_tgt_passing;
|
||||
|
||||
case sGssAuthentication:
|
||||
intptr = &options->gss_authentication;
|
||||
goto parse_flag;
|
||||
#endif
|
||||
#ifdef AFS
|
||||
case sAFSTokenPassing:
|
||||
intptr = &options->afs_token_passing;
|
||||
|
||||
case sGssCleanupCreds:
|
||||
intptr = &options->gss_cleanup_creds;
|
||||
goto parse_flag;
|
||||
#endif
|
||||
|
||||
case sPasswordAuthentication:
|
||||
intptr = &options->password_authentication;
|
||||
@ -748,8 +702,8 @@ process_server_config_line(ServerOptions *options, char *line,
|
||||
intptr = &options->gateway_ports;
|
||||
goto parse_flag;
|
||||
|
||||
case sVerifyReverseMapping:
|
||||
intptr = &options->verify_reverse_mapping;
|
||||
case sUseDNS:
|
||||
intptr = &options->use_dns;
|
||||
goto parse_flag;
|
||||
|
||||
case sLogFacility:
|
||||
@ -932,7 +886,14 @@ process_server_config_line(ServerOptions *options, char *line,
|
||||
break;
|
||||
|
||||
case sDeprecated:
|
||||
log("%s line %d: Deprecated option %s",
|
||||
logit("%s line %d: Deprecated option %s",
|
||||
filename, linenum, arg);
|
||||
while (arg)
|
||||
arg = strdelim(&cp);
|
||||
break;
|
||||
|
||||
case sUnsupported:
|
||||
logit("%s line %d: Unsupported option %s",
|
||||
filename, linenum, arg);
|
||||
while (arg)
|
||||
arg = strdelim(&cp);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: servconf.h,v 1.59 2002/07/30 17:03:55 markus Exp $ */
|
||||
/* $OpenBSD: servconf.h,v 1.65 2003/09/01 18:15:50 markus Exp $ */
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/*
|
||||
@ -66,15 +66,12 @@ typedef struct {
|
||||
int gateway_ports; /* If true, allow remote connects to forwarded ports. */
|
||||
SyslogFacility log_facility; /* Facility for system logging. */
|
||||
LogLevel log_level; /* Level for system logging. */
|
||||
int rhosts_authentication; /* If true, permit rhosts
|
||||
* authentication. */
|
||||
int rhosts_rsa_authentication; /* If true, permit rhosts RSA
|
||||
* authentication. */
|
||||
int hostbased_authentication; /* If true, permit ssh2 hostbased auth */
|
||||
int hostbased_uses_name_from_packet_only; /* experimental */
|
||||
int rsa_authentication; /* If true, permit RSA authentication. */
|
||||
int pubkey_authentication; /* If true, permit ssh2 pubkey authentication. */
|
||||
#if defined(KRB4) || defined(KRB5)
|
||||
int kerberos_authentication; /* If true, permit Kerberos
|
||||
* authentication. */
|
||||
int kerberos_or_local_passwd; /* If true, permit kerberos
|
||||
@ -84,14 +81,8 @@ typedef struct {
|
||||
* /etc/passwd */
|
||||
int kerberos_ticket_cleanup; /* If true, destroy ticket
|
||||
* file on logout. */
|
||||
#endif
|
||||
#if defined(AFS) || defined(KRB5)
|
||||
int kerberos_tgt_passing; /* If true, permit Kerberos TGT
|
||||
* passing. */
|
||||
#endif
|
||||
#ifdef AFS
|
||||
int afs_token_passing; /* If true, permit AFS token passing. */
|
||||
#endif
|
||||
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
|
||||
* authentication. */
|
||||
int kbd_interactive_authentication; /* If true, permit */
|
||||
@ -119,7 +110,7 @@ typedef struct {
|
||||
int max_startups_rate;
|
||||
int max_startups;
|
||||
char *banner; /* SSH-2 banner message */
|
||||
int verify_reverse_mapping; /* cross-check ip and dns */
|
||||
int use_dns;
|
||||
int client_alive_interval; /*
|
||||
* poke the client this often to
|
||||
* see if it's still there
|
||||
@ -132,7 +123,7 @@ typedef struct {
|
||||
|
||||
char *authorized_keys_file; /* File containing public keys */
|
||||
char *authorized_keys_file2;
|
||||
int pam_authentication_via_kbd_int;
|
||||
int use_pam; /* Enable auth via PAM */
|
||||
} ServerOptions;
|
||||
|
||||
void initialize_server_options(ServerOptions *);
|
||||
|
@ -35,7 +35,7 @@
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: serverloop.c,v 1.106 2003/04/01 10:22:21 markus Exp $");
|
||||
RCSID("$OpenBSD: serverloop.c,v 1.110 2003/06/24 08:23:46 markus Exp $");
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "packet.h"
|
||||
@ -158,7 +158,7 @@ sigchld_handler(int sig)
|
||||
static void
|
||||
make_packets_from_stderr_data(void)
|
||||
{
|
||||
int len;
|
||||
u_int len;
|
||||
|
||||
/* Send buffered stderr data to the client. */
|
||||
while (buffer_len(&stderr_buffer) > 0 &&
|
||||
@ -187,7 +187,7 @@ make_packets_from_stderr_data(void)
|
||||
static void
|
||||
make_packets_from_stdout_data(void)
|
||||
{
|
||||
int len;
|
||||
u_int len;
|
||||
|
||||
/* Send buffered stdout data to the client. */
|
||||
while (buffer_len(&stdout_buffer) > 0 &&
|
||||
@ -771,8 +771,14 @@ server_loop2(Authctxt *authctxt)
|
||||
&nalloc, 0);
|
||||
|
||||
collect_children();
|
||||
if (!rekeying)
|
||||
if (!rekeying) {
|
||||
channel_after_select(readset, writeset);
|
||||
if (packet_need_rekeying()) {
|
||||
debug("need rekeying");
|
||||
xxx_kex->done = 0;
|
||||
kex_send_kexinit(xxx_kex);
|
||||
}
|
||||
}
|
||||
process_input(readset);
|
||||
if (connection_closed)
|
||||
break;
|
||||
@ -874,7 +880,7 @@ server_request_direct_tcpip(char *ctype)
|
||||
return NULL;
|
||||
c = channel_new(ctype, SSH_CHANNEL_CONNECTING,
|
||||
sock, sock, -1, CHAN_TCP_WINDOW_DEFAULT,
|
||||
CHAN_TCP_PACKET_DEFAULT, 0, xstrdup("direct-tcpip"), 1);
|
||||
CHAN_TCP_PACKET_DEFAULT, 0, "direct-tcpip", 1);
|
||||
return c;
|
||||
}
|
||||
|
||||
@ -893,7 +899,7 @@ server_request_session(char *ctype)
|
||||
*/
|
||||
c = channel_new(ctype, SSH_CHANNEL_LARVAL,
|
||||
-1, -1, -1, /*window size*/0, CHAN_SES_PACKET_DEFAULT,
|
||||
0, xstrdup("server-session"), 1);
|
||||
0, "server-session", 1);
|
||||
if (session_open(xxx_authctxt, c->self) != 1) {
|
||||
debug("session open failed, free channel %d", c->self);
|
||||
channel_free(c);
|
||||
@ -971,7 +977,7 @@ server_input_global_request(int type, u_int32_t seq, void *ctxt)
|
||||
pw = auth_get_user();
|
||||
if (pw == NULL)
|
||||
fatal("server_input_global_request: no user");
|
||||
listen_address = packet_get_string(NULL); /* XXX currently ignored */
|
||||
listen_address = packet_get_string(NULL);
|
||||
listen_port = (u_short)packet_get_int();
|
||||
debug("server_input_global_request: tcpip-forward listen %s port %d",
|
||||
listen_address, listen_port);
|
||||
|
@ -33,7 +33,7 @@
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: session.c,v 1.154 2003/03/05 22:33:43 markus Exp $");
|
||||
RCSID("$OpenBSD: session.c,v 1.164 2003/09/18 08:49:45 markus Exp $");
|
||||
RCSID("$FreeBSD$");
|
||||
|
||||
#include "ssh.h"
|
||||
@ -59,10 +59,8 @@ RCSID("$FreeBSD$");
|
||||
#include "session.h"
|
||||
#include "monitor_wrap.h"
|
||||
|
||||
#ifdef HAVE_CYGWIN
|
||||
#include <windows.h>
|
||||
#include <sys/cygwin.h>
|
||||
#define is_winnt (GetVersion() < 0x80000000)
|
||||
#ifdef GSSAPI
|
||||
#include "ssh-gss.h"
|
||||
#endif
|
||||
|
||||
/* func */
|
||||
@ -96,6 +94,7 @@ extern int debug_flag;
|
||||
extern u_int utmp_len;
|
||||
extern int startup_pipe;
|
||||
extern void destroy_sensitive_data(void);
|
||||
extern Buffer loginmsg;
|
||||
|
||||
/* original command from peer. */
|
||||
const char *original_command = NULL;
|
||||
@ -104,10 +103,6 @@ const char *original_command = NULL;
|
||||
#define MAX_SESSIONS 10
|
||||
Session sessions[MAX_SESSIONS];
|
||||
|
||||
#ifdef WITH_AIXAUTHENTICATE
|
||||
char *aixloginmsg;
|
||||
#endif /* WITH_AIXAUTHENTICATE */
|
||||
|
||||
#ifdef HAVE_LOGIN_CAP
|
||||
login_cap_t *lc;
|
||||
#endif
|
||||
@ -193,7 +188,7 @@ auth_input_request_forwarding(struct passwd * pw)
|
||||
nc = channel_new("auth socket",
|
||||
SSH_CHANNEL_AUTH_SOCKET, sock, sock, -1,
|
||||
CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT,
|
||||
0, xstrdup("auth socket"), 1);
|
||||
0, "auth socket", 1);
|
||||
strlcpy(nc->path, auth_sock_name, sizeof(nc->path));
|
||||
return 1;
|
||||
}
|
||||
@ -226,10 +221,6 @@ do_authenticated(Authctxt *authctxt)
|
||||
/* remove agent socket */
|
||||
if (auth_sock_name != NULL)
|
||||
auth_sock_cleanup_proc(authctxt->pw);
|
||||
#ifdef KRB4
|
||||
if (options.kerberos_ticket_cleanup)
|
||||
krb4_cleanup_proc(authctxt);
|
||||
#endif
|
||||
#ifdef KRB5
|
||||
if (options.kerberos_ticket_cleanup)
|
||||
krb5_cleanup_proc(authctxt);
|
||||
@ -342,58 +333,6 @@ do_authenticated1(Authctxt *authctxt)
|
||||
success = 1;
|
||||
break;
|
||||
|
||||
#if defined(AFS) || defined(KRB5)
|
||||
case SSH_CMSG_HAVE_KERBEROS_TGT:
|
||||
if (!options.kerberos_tgt_passing) {
|
||||
verbose("Kerberos TGT passing disabled.");
|
||||
} else {
|
||||
char *kdata = packet_get_string(&dlen);
|
||||
packet_check_eom();
|
||||
|
||||
/* XXX - 0x41, see creds_to_radix version */
|
||||
if (kdata[0] != 0x41) {
|
||||
#ifdef KRB5
|
||||
krb5_data tgt;
|
||||
tgt.data = kdata;
|
||||
tgt.length = dlen;
|
||||
|
||||
if (auth_krb5_tgt(s->authctxt, &tgt))
|
||||
success = 1;
|
||||
else
|
||||
verbose("Kerberos v5 TGT refused for %.100s", s->authctxt->user);
|
||||
#endif /* KRB5 */
|
||||
} else {
|
||||
#ifdef AFS
|
||||
if (auth_krb4_tgt(s->authctxt, kdata))
|
||||
success = 1;
|
||||
else
|
||||
verbose("Kerberos v4 TGT refused for %.100s", s->authctxt->user);
|
||||
#endif /* AFS */
|
||||
}
|
||||
xfree(kdata);
|
||||
}
|
||||
break;
|
||||
#endif /* AFS || KRB5 */
|
||||
|
||||
#ifdef AFS
|
||||
case SSH_CMSG_HAVE_AFS_TOKEN:
|
||||
if (!options.afs_token_passing || !k_hasafs()) {
|
||||
verbose("AFS token passing disabled.");
|
||||
} else {
|
||||
/* Accept AFS token. */
|
||||
char *token = packet_get_string(&dlen);
|
||||
packet_check_eom();
|
||||
|
||||
if (auth_afs_token(s->authctxt, token))
|
||||
success = 1;
|
||||
else
|
||||
verbose("AFS token refused for %.100s",
|
||||
s->authctxt->user);
|
||||
xfree(token);
|
||||
}
|
||||
break;
|
||||
#endif /* AFS */
|
||||
|
||||
case SSH_CMSG_EXEC_SHELL:
|
||||
case SSH_CMSG_EXEC_CMD:
|
||||
if (type == SSH_CMSG_EXEC_CMD) {
|
||||
@ -413,7 +352,7 @@ do_authenticated1(Authctxt *authctxt)
|
||||
* Any unknown messages in this phase are ignored,
|
||||
* and a failure message is returned.
|
||||
*/
|
||||
log("Unknown packet type received after authentication: %d", type);
|
||||
logit("Unknown packet type received after authentication: %d", type);
|
||||
}
|
||||
packet_start(success ? SSH_SMSG_SUCCESS : SSH_SMSG_FAILURE);
|
||||
packet_send();
|
||||
@ -457,11 +396,12 @@ do_exec_no_pty(Session *s, const char *command)
|
||||
session_proctitle(s);
|
||||
|
||||
#if defined(USE_PAM)
|
||||
do_pam_session(s->pw->pw_name, NULL);
|
||||
do_pam_setcred(1);
|
||||
if (is_pam_password_change_required())
|
||||
packet_disconnect("Password change required but no "
|
||||
"TTY available");
|
||||
if (options.use_pam) {
|
||||
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. */
|
||||
@ -584,8 +524,10 @@ do_exec_pty(Session *s, const char *command)
|
||||
ttyfd = s->ttyfd;
|
||||
|
||||
#if defined(USE_PAM)
|
||||
do_pam_session(s->pw->pw_name, s->tty);
|
||||
do_pam_setcred(1);
|
||||
if (options.use_pam) {
|
||||
do_pam_set_tty(s->tty);
|
||||
do_pam_setcred(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Fork the child. */
|
||||
@ -691,7 +633,7 @@ do_pre_login(Session *s)
|
||||
}
|
||||
|
||||
record_utmp_only(pid, s->tty, s->pw->pw_name,
|
||||
get_remote_name_or_ip(utmp_len, options.verify_reverse_mapping),
|
||||
get_remote_name_or_ip(utmp_len, options.use_dns),
|
||||
(struct sockaddr *)&from, fromlen);
|
||||
}
|
||||
#endif
|
||||
@ -709,6 +651,14 @@ do_exec(Session *s, const char *command)
|
||||
debug("Forced command '%.900s'", command);
|
||||
}
|
||||
|
||||
#ifdef GSSAPI
|
||||
if (options.gss_authentication) {
|
||||
temporarily_use_uid(s->pw);
|
||||
ssh_gssapi_storecreds();
|
||||
restore_uid();
|
||||
}
|
||||
#endif
|
||||
|
||||
if (s->ttyfd != -1)
|
||||
do_exec_pty(s, command);
|
||||
else
|
||||
@ -746,7 +696,7 @@ do_login(Session *s, const char *command)
|
||||
if (!use_privsep)
|
||||
record_login(pid, s->tty, pw->pw_name, pw->pw_uid,
|
||||
get_remote_name_or_ip(utmp_len,
|
||||
options.verify_reverse_mapping),
|
||||
options.use_dns),
|
||||
(struct sockaddr *)&from, fromlen);
|
||||
|
||||
#ifdef USE_PAM
|
||||
@ -754,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 (is_pam_password_change_required()) {
|
||||
if (options.use_pam && is_pam_password_change_required()) {
|
||||
print_pam_messages();
|
||||
do_pam_chauthtok();
|
||||
/* XXX - signal [net] parent to enable forwardings */
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -764,13 +715,16 @@ do_login(Session *s, const char *command)
|
||||
return;
|
||||
|
||||
#ifdef USE_PAM
|
||||
if (!is_pam_password_change_required())
|
||||
if (options.use_pam && !is_pam_password_change_required())
|
||||
print_pam_messages();
|
||||
#endif /* USE_PAM */
|
||||
#ifdef WITH_AIXAUTHENTICATE
|
||||
if (aixloginmsg && *aixloginmsg)
|
||||
printf("%s\n", aixloginmsg);
|
||||
#endif /* WITH_AIXAUTHENTICATE */
|
||||
|
||||
/* display post-login message */
|
||||
if (buffer_len(&loginmsg) > 0) {
|
||||
buffer_append(&loginmsg, "\0", 1);
|
||||
printf("%s\n", (char *)buffer_ptr(&loginmsg));
|
||||
}
|
||||
buffer_free(&loginmsg);
|
||||
|
||||
#ifndef NO_SSH_LASTLOG
|
||||
if (options.print_lastlog && s->last_login_time != 0) {
|
||||
@ -859,7 +813,7 @@ check_quietlogin(Session *s, const char *command)
|
||||
* Sets the value of the given variable in the environment. If the variable
|
||||
* already exists, its value is overriden.
|
||||
*/
|
||||
static void
|
||||
void
|
||||
child_set_env(char ***envp, u_int *envsizep, const char *name,
|
||||
const char *value)
|
||||
{
|
||||
@ -867,6 +821,16 @@ child_set_env(char ***envp, u_int *envsizep, const char *name,
|
||||
u_int envsize;
|
||||
u_int i, namelen;
|
||||
|
||||
/*
|
||||
* If we're passed an uninitialized list, allocate a single null
|
||||
* entry before continuing.
|
||||
*/
|
||||
if (*envp == NULL && *envsizep == 0) {
|
||||
*envp = xmalloc(sizeof(char *));
|
||||
*envp[0] = NULL;
|
||||
*envsizep = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the slot where the value should be stored. If the variable
|
||||
* already exists, we reuse the slot; otherwise we append a new slot
|
||||
@ -944,6 +908,61 @@ read_environment_file(char ***env, u_int *envsize,
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
#ifdef HAVE_ETC_DEFAULT_LOGIN
|
||||
/*
|
||||
* Return named variable from specified environment, or NULL if not present.
|
||||
*/
|
||||
static char *
|
||||
child_get_env(char **env, const char *name)
|
||||
{
|
||||
int i;
|
||||
size_t len;
|
||||
|
||||
len = strlen(name);
|
||||
for (i=0; env[i] != NULL; i++)
|
||||
if (strncmp(name, env[i], len) == 0 && env[i][len] == '=')
|
||||
return(env[i] + len + 1);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read /etc/default/login.
|
||||
* We pick up the PATH (or SUPATH for root) and UMASK.
|
||||
*/
|
||||
static void
|
||||
read_etc_default_login(char ***env, u_int *envsize, uid_t uid)
|
||||
{
|
||||
char **tmpenv = NULL, *var;
|
||||
u_int i, tmpenvsize = 0;
|
||||
mode_t mask;
|
||||
|
||||
/*
|
||||
* We don't want to copy the whole file to the child's environment,
|
||||
* so we use a temporary environment and copy the variables we're
|
||||
* interested in.
|
||||
*/
|
||||
read_environment_file(&tmpenv, &tmpenvsize, "/etc/default/login");
|
||||
|
||||
if (tmpenv == NULL)
|
||||
return;
|
||||
|
||||
if (uid == 0)
|
||||
var = child_get_env(tmpenv, "SUPATH");
|
||||
else
|
||||
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);
|
||||
|
||||
for (i = 0; tmpenv[i] != NULL; i++)
|
||||
xfree(tmpenv[i]);
|
||||
xfree(tmpenv);
|
||||
}
|
||||
#endif /* HAVE_ETC_DEFAULT_LOGIN */
|
||||
|
||||
void copy_environment(char **source, char ***env, u_int *envsize)
|
||||
{
|
||||
char *var_name, *var_val;
|
||||
@ -972,7 +991,7 @@ do_setup_env(Session *s, const char *shell)
|
||||
{
|
||||
char buf[256];
|
||||
u_int i, envsize;
|
||||
char **env, *laddr;
|
||||
char **env, *laddr, *path = NULL;
|
||||
#ifdef HAVE_LOGIN_CAP
|
||||
extern char **environ;
|
||||
char **senv, **var;
|
||||
@ -994,6 +1013,14 @@ do_setup_env(Session *s, const char *shell)
|
||||
|
||||
if (getenv("TZ"))
|
||||
child_set_env(&env, &envsize, "TZ", getenv("TZ"));
|
||||
|
||||
#ifdef GSSAPI
|
||||
/* Allow any GSSAPI methods that we've used to alter
|
||||
* the childs environment as they see fit
|
||||
*/
|
||||
ssh_gssapi_do_child(&env, &envsize);
|
||||
#endif
|
||||
|
||||
if (!options.use_login) {
|
||||
/* Set basic environment. */
|
||||
child_set_env(&env, &envsize, "USER", pw->pw_name);
|
||||
@ -1026,12 +1053,15 @@ do_setup_env(Session *s, const char *shell)
|
||||
* needed for loading shared libraries. So the path better
|
||||
* remains intact here.
|
||||
*/
|
||||
# ifdef SUPERUSER_PATH
|
||||
child_set_env(&env, &envsize, "PATH",
|
||||
s->pw->pw_uid == 0 ? SUPERUSER_PATH : _PATH_STDPATH);
|
||||
# else
|
||||
child_set_env(&env, &envsize, "PATH", _PATH_STDPATH);
|
||||
# endif /* SUPERUSER_PATH */
|
||||
# ifdef HAVE_ETC_DEFAULT_LOGIN
|
||||
read_etc_default_login(&env, &envsize, pw->pw_uid);
|
||||
path = child_get_env(env, "PATH");
|
||||
# endif /* HAVE_ETC_DEFAULT_LOGIN */
|
||||
if (path == NULL || *path == '\0') {
|
||||
child_set_env(&env, &envsize, "PATH",
|
||||
s->pw->pw_uid == 0 ?
|
||||
SUPERUSER_PATH : _PATH_STDPATH);
|
||||
}
|
||||
# endif /* HAVE_CYGWIN */
|
||||
#endif /* HAVE_LOGIN_CAP */
|
||||
|
||||
@ -1094,11 +1124,6 @@ do_setup_env(Session *s, const char *shell)
|
||||
read_environment_file(&env, &envsize, "/etc/environment");
|
||||
}
|
||||
#endif
|
||||
#ifdef KRB4
|
||||
if (s->authctxt->krb4_ticket_file)
|
||||
child_set_env(&env, &envsize, "KRBTKFILE",
|
||||
s->authctxt->krb4_ticket_file);
|
||||
#endif
|
||||
#ifdef KRB5
|
||||
if (s->authctxt->krb5_ticket_file)
|
||||
child_set_env(&env, &envsize, "KRB5CCNAME",
|
||||
@ -1109,10 +1134,9 @@ do_setup_env(Session *s, const char *shell)
|
||||
* Pull in any environment variables that may have
|
||||
* been set by PAM.
|
||||
*/
|
||||
{
|
||||
char **p;
|
||||
if (options.use_pam) {
|
||||
char **p = fetch_pam_environment();
|
||||
|
||||
p = fetch_pam_environment();
|
||||
copy_environment(p, &env, &envsize);
|
||||
free_pam_environment(p);
|
||||
}
|
||||
@ -1224,7 +1248,7 @@ do_nologin(struct passwd *pw)
|
||||
#endif
|
||||
if (f) {
|
||||
/* /etc/nologin exists. Print its contents and exit. */
|
||||
log("User %.100s not allowed because %s exists",
|
||||
logit("User %.100s not allowed because %s exists",
|
||||
pw->pw_name, _PATH_NOLOGIN);
|
||||
while (fgets(buf, sizeof(buf), f))
|
||||
fputs(buf, stderr);
|
||||
@ -1244,7 +1268,8 @@ do_setusercontext(struct passwd *pw)
|
||||
{
|
||||
|
||||
#ifdef HAVE_SETPCRED
|
||||
setpcred(pw->pw_name);
|
||||
if (setpcred(pw->pw_name, (char **)NULL) == -1)
|
||||
fatal("Failed to set process credentials");
|
||||
#endif /* HAVE_SETPCRED */
|
||||
#ifdef HAVE_LOGIN_CAP
|
||||
# ifdef __bsdi__
|
||||
@ -1280,7 +1305,10 @@ do_setusercontext(struct passwd *pw)
|
||||
* These will have been wiped by the above initgroups() call.
|
||||
* Reestablish them here.
|
||||
*/
|
||||
do_pam_setcred(0);
|
||||
if (options.use_pam) {
|
||||
do_pam_session();
|
||||
do_pam_setcred(0);
|
||||
}
|
||||
# endif /* USE_PAM */
|
||||
# if defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY)
|
||||
irix_setusercontext(pw);
|
||||
@ -1384,7 +1412,7 @@ do_child(Session *s, const char *command)
|
||||
/* we have to stash the hostname before we close our socket. */
|
||||
if (options.use_login)
|
||||
hostname = get_remote_name_or_ip(utmp_len,
|
||||
options.verify_reverse_mapping);
|
||||
options.use_dns);
|
||||
/*
|
||||
* Close the connection descriptors; note that this is the child, and
|
||||
* the server will still have the socket open, and it is important
|
||||
@ -1430,18 +1458,6 @@ do_child(Session *s, const char *command)
|
||||
*/
|
||||
environ = env;
|
||||
|
||||
#ifdef AFS
|
||||
/* Try to get AFS tokens for the local cell. */
|
||||
if (k_hasafs()) {
|
||||
char cell[64];
|
||||
|
||||
if (k_afs_cell_of_file(pw->pw_dir, cell, sizeof(cell)) == 0)
|
||||
krb_afslog(cell, 0);
|
||||
|
||||
krb_afslog(0, 0);
|
||||
}
|
||||
#endif /* AFS */
|
||||
|
||||
/* 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",
|
||||
@ -1711,7 +1727,7 @@ session_subsystem_req(Session *s)
|
||||
int i;
|
||||
|
||||
packet_check_eom();
|
||||
log("subsystem request for %.100s", subsys);
|
||||
logit("subsystem request for %.100s", subsys);
|
||||
|
||||
for (i = 0; i < options.num_subsystems; i++) {
|
||||
if (strcmp(subsys, options.subsystem_name[i]) == 0) {
|
||||
@ -1730,7 +1746,7 @@ session_subsystem_req(Session *s)
|
||||
}
|
||||
|
||||
if (!success)
|
||||
log("subsystem request for %.100s failed, subsystem not found",
|
||||
logit("subsystem request for %.100s failed, subsystem not found",
|
||||
subsys);
|
||||
|
||||
xfree(subsys);
|
||||
@ -1777,6 +1793,20 @@ session_exec_req(Session *s)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
session_break_req(Session *s)
|
||||
{
|
||||
u_int break_length;
|
||||
|
||||
break_length = packet_get_int(); /* ignored */
|
||||
packet_check_eom();
|
||||
|
||||
if (s->ttyfd == -1 ||
|
||||
tcsendbreak(s->ttyfd, 0) < 0)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
session_auth_agent_req(Session *s)
|
||||
{
|
||||
@ -1801,7 +1831,7 @@ session_input_channel_req(Channel *c, const char *rtype)
|
||||
Session *s;
|
||||
|
||||
if ((s = session_by_channel(c->self)) == NULL) {
|
||||
log("session_input_channel_req: no session %d req %.100s",
|
||||
logit("session_input_channel_req: no session %d req %.100s",
|
||||
c->self, rtype);
|
||||
return 0;
|
||||
}
|
||||
@ -1824,6 +1854,8 @@ session_input_channel_req(Channel *c, const char *rtype)
|
||||
success = session_auth_agent_req(s);
|
||||
} else if (strcmp(rtype, "subsystem") == 0) {
|
||||
success = session_subsystem_req(s);
|
||||
} else if (strcmp(rtype, "break") == 0) {
|
||||
success = session_break_req(s);
|
||||
}
|
||||
}
|
||||
if (strcmp(rtype, "window-change") == 0) {
|
||||
@ -2160,4 +2192,8 @@ static void
|
||||
do_authenticated2(Authctxt *authctxt)
|
||||
{
|
||||
server_loop2(authctxt);
|
||||
#if defined(GSSAPI)
|
||||
if (options.gss_cleanup_creds)
|
||||
ssh_gssapi_cleanup_creds(NULL);
|
||||
#endif
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: session.h,v 1.19 2002/06/30 21:59:45 deraadt Exp $ */
|
||||
/* $OpenBSD: session.h,v 1.20 2003/08/22 10:56:09 markus Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
|
||||
@ -68,4 +68,7 @@ Session *session_new(void);
|
||||
Session *session_by_tty(char *);
|
||||
void session_close(Session *);
|
||||
void do_setusercontext(struct passwd *);
|
||||
void child_set_env(char ***envp, u_int *envsizep, const char *name,
|
||||
const char *value);
|
||||
|
||||
#endif
|
||||
|
@ -35,7 +35,7 @@
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: ssh-add.c,v 1.66 2003/03/05 22:33:43 markus Exp $");
|
||||
RCSID("$OpenBSD: ssh-add.c,v 1.68 2003/06/16 10:22:45 markus Exp $");
|
||||
|
||||
#include <openssl/evp.h>
|
||||
|
||||
@ -164,7 +164,8 @@ add_file(AuthenticationConnection *ac, const char *filename)
|
||||
if (private != NULL)
|
||||
break;
|
||||
clear_pass();
|
||||
strlcpy(msg, "Bad passphrase, try again: ", sizeof msg);
|
||||
snprintf(msg, sizeof msg,
|
||||
"Bad passphrase, try again for %.200s: ", comment);
|
||||
}
|
||||
}
|
||||
|
||||
@ -201,7 +202,7 @@ update_card(AuthenticationConnection *ac, int add, const char *id)
|
||||
if (pin == NULL)
|
||||
return -1;
|
||||
|
||||
if (ssh_update_card(ac, add, id, pin)) {
|
||||
if (ssh_update_card(ac, add, id, pin, lifetime, confirm)) {
|
||||
fprintf(stderr, "Card %s: %s\n",
|
||||
add ? "added" : "removed", id);
|
||||
ret = 0;
|
||||
@ -318,7 +319,7 @@ main(int argc, char **argv)
|
||||
char *sc_reader_id = NULL;
|
||||
int i, ch, deleting = 0, ret = 0;
|
||||
|
||||
__progname = get_progname(argv[0]);
|
||||
__progname = ssh_get_progname(argv[0]);
|
||||
init_rng();
|
||||
seed_rng();
|
||||
|
||||
|
@ -35,7 +35,7 @@
|
||||
|
||||
#include "includes.h"
|
||||
#include "openbsd-compat/sys-queue.h"
|
||||
RCSID("$OpenBSD: ssh-agent.c,v 1.108 2003/03/13 11:44:50 markus Exp $");
|
||||
RCSID("$OpenBSD: ssh-agent.c,v 1.112 2003/09/18 08:49:45 markus Exp $");
|
||||
RCSID("$FreeBSD$");
|
||||
|
||||
#include <openssl/evp.h>
|
||||
@ -262,7 +262,7 @@ process_authentication_challenge1(SocketEntry *e)
|
||||
/* The response is MD5 of decrypted challenge plus session id. */
|
||||
len = BN_num_bytes(challenge);
|
||||
if (len <= 0 || len > 32) {
|
||||
log("process_authentication_challenge: bad challenge length %d", len);
|
||||
logit("process_authentication_challenge: bad challenge length %d", len);
|
||||
goto failure;
|
||||
}
|
||||
memset(buf, 0, 32);
|
||||
@ -351,7 +351,7 @@ process_remove_identity(SocketEntry *e, int version)
|
||||
buffer_get_bignum(&e->request, key->rsa->n);
|
||||
|
||||
if (bits != key_size(key))
|
||||
log("Warning: identity keysize mismatch: actual %u, announced %u",
|
||||
logit("Warning: identity keysize mismatch: actual %u, announced %u",
|
||||
key_size(key), bits);
|
||||
break;
|
||||
case 2:
|
||||
@ -581,13 +581,29 @@ static void
|
||||
process_add_smartcard_key (SocketEntry *e)
|
||||
{
|
||||
char *sc_reader_id = NULL, *pin;
|
||||
int i, version, success = 0;
|
||||
int i, version, success = 0, death = 0, confirm = 0;
|
||||
Key **keys, *k;
|
||||
Identity *id;
|
||||
Idtab *tab;
|
||||
|
||||
sc_reader_id = buffer_get_string(&e->request, NULL);
|
||||
pin = buffer_get_string(&e->request, NULL);
|
||||
|
||||
while (buffer_len(&e->request)) {
|
||||
switch (buffer_get_char(&e->request)) {
|
||||
case SSH_AGENT_CONSTRAIN_LIFETIME:
|
||||
death = time(NULL) + buffer_get_int(&e->request);
|
||||
break;
|
||||
case SSH_AGENT_CONSTRAIN_CONFIRM:
|
||||
confirm = 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (lifetime && !death)
|
||||
death = time(NULL) + lifetime;
|
||||
|
||||
keys = sc_get_keys(sc_reader_id, pin);
|
||||
xfree(sc_reader_id);
|
||||
xfree(pin);
|
||||
@ -603,9 +619,9 @@ process_add_smartcard_key (SocketEntry *e)
|
||||
if (lookup_identity(k, version) == NULL) {
|
||||
id = xmalloc(sizeof(Identity));
|
||||
id->key = k;
|
||||
id->comment = xstrdup("smartcard key");
|
||||
id->death = 0;
|
||||
id->confirm = 0;
|
||||
id->comment = sc_get_key_label(k);
|
||||
id->death = death;
|
||||
id->confirm = confirm;
|
||||
TAILQ_INSERT_TAIL(&tab->idlist, id, next);
|
||||
tab->nentries++;
|
||||
success = 1;
|
||||
@ -749,6 +765,7 @@ process_message(SocketEntry *e)
|
||||
break;
|
||||
#ifdef SMARTCARD
|
||||
case SSH_AGENTC_ADD_SMARTCARD_KEY:
|
||||
case SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED:
|
||||
process_add_smartcard_key(e);
|
||||
break;
|
||||
case SSH_AGENTC_REMOVE_SMARTCARD_KEY:
|
||||
@ -964,7 +981,7 @@ check_parent_exists(int sig)
|
||||
/* printf("Parent has died - Authentication agent exiting.\n"); */
|
||||
cleanup_handler(sig); /* safe */
|
||||
}
|
||||
signal(SIGALRM, check_parent_exists);
|
||||
mysignal(SIGALRM, check_parent_exists);
|
||||
alarm(10);
|
||||
errno = save_errno;
|
||||
}
|
||||
@ -1010,7 +1027,7 @@ main(int ac, char **av)
|
||||
|
||||
SSLeay_add_all_algorithms();
|
||||
|
||||
__progname = get_progname(av[0]);
|
||||
__progname = ssh_get_progname(av[0]);
|
||||
init_rng();
|
||||
seed_rng();
|
||||
|
||||
@ -1197,7 +1214,7 @@ main(int ac, char **av)
|
||||
fatal_add_cleanup(cleanup_socket, NULL);
|
||||
new_socket(AUTH_SOCKET, sock);
|
||||
if (ac > 0) {
|
||||
signal(SIGALRM, check_parent_exists);
|
||||
mysignal(SIGALRM, check_parent_exists);
|
||||
alarm(10);
|
||||
}
|
||||
idtab_init();
|
||||
|
@ -7,7 +7,7 @@
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: ssh-keyscan.c,v 1.41 2003/02/16 17:09:57 markus Exp $");
|
||||
RCSID("$OpenBSD: ssh-keyscan.c,v 1.44 2003/06/28 16:23:06 deraadt Exp $");
|
||||
|
||||
#include "openbsd-compat/sys-queue.h"
|
||||
|
||||
@ -31,11 +31,7 @@ RCSID("$OpenBSD: ssh-keyscan.c,v 1.41 2003/02/16 17:09:57 markus Exp $");
|
||||
|
||||
/* Flag indicating whether IPv4 or IPv6. This can be set on the command line.
|
||||
Default value is AF_UNSPEC means both IPv4 and IPv6. */
|
||||
#ifdef IPV4_DEFAULT
|
||||
int IPv4or6 = AF_INET;
|
||||
#else
|
||||
int IPv4or6 = AF_UNSPEC;
|
||||
#endif
|
||||
|
||||
int ssh_port = SSH_DEFAULT_PORT;
|
||||
|
||||
@ -397,7 +393,7 @@ tcpconnect(char *host)
|
||||
if ((gaierr = getaddrinfo(host, strport, &hints, &aitop)) != 0)
|
||||
fatal("getaddrinfo %s: %s", host, gai_strerror(gaierr));
|
||||
for (ai = aitop; ai; ai = ai->ai_next) {
|
||||
s = socket(ai->ai_family, SOCK_STREAM, 0);
|
||||
s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
|
||||
if (s < 0) {
|
||||
error("socket: %s", strerror(errno));
|
||||
continue;
|
||||
@ -545,7 +541,7 @@ congreet(int s)
|
||||
n = snprintf(buf, sizeof buf, "SSH-%d.%d-OpenSSH-keyscan\r\n",
|
||||
c->c_keytype == KT_RSA1? PROTOCOL_MAJOR_1 : PROTOCOL_MAJOR_2,
|
||||
c->c_keytype == KT_RSA1? PROTOCOL_MINOR_1 : PROTOCOL_MINOR_2);
|
||||
if (atomicio(write, s, buf, n) != n) {
|
||||
if (atomicio(vwrite, s, buf, n) != n) {
|
||||
error("write (%s): %s", c->c_name, strerror(errno));
|
||||
confree(s);
|
||||
return;
|
||||
@ -685,7 +681,7 @@ fatal(const char *fmt,...)
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
fprintf(stderr, "usage: %s [-v46] [-p port] [-T timeout] [-f file]\n"
|
||||
fprintf(stderr, "usage: %s [-v46] [-p port] [-T timeout] [-t type] [-f file]\n"
|
||||
"\t\t [host | addrlist namelist] [...]\n",
|
||||
__progname);
|
||||
exit(1);
|
||||
@ -701,7 +697,7 @@ main(int argc, char **argv)
|
||||
extern int optind;
|
||||
extern char *optarg;
|
||||
|
||||
__progname = get_progname(argv[0]);
|
||||
__progname = ssh_get_progname(argv[0]);
|
||||
init_rng();
|
||||
seed_rng();
|
||||
TAILQ_INIT(&tq);
|
||||
|
@ -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.168 2003/03/28 10:11:43 jmc Exp $
|
||||
.\" $OpenBSD: ssh.1,v 1.175 2003/07/22 13:35:22 markus Exp $
|
||||
.\" $FreeBSD$
|
||||
.Dd September 25, 1999
|
||||
.Dt SSH 1
|
||||
@ -50,7 +50,7 @@
|
||||
.Pp
|
||||
.Nm ssh
|
||||
.Bk -words
|
||||
.Op Fl afgknqstvxACNTX1246
|
||||
.Op Fl afgknqstvxACNTVX1246
|
||||
.Op Fl b Ar bind_address
|
||||
.Op Fl c Ar cipher_spec
|
||||
.Op Fl e Ar escape_char
|
||||
@ -302,6 +302,9 @@ Background ssh at logout when waiting for forwarded connection / X11 sessions
|
||||
to terminate
|
||||
.It Cm ~?
|
||||
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)
|
||||
.It Cm ~C
|
||||
Open command line (only useful for adding port forwardings using the
|
||||
.Fl L
|
||||
@ -487,13 +490,13 @@ It is possible to have multiple
|
||||
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
|
||||
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 and AFS tokens.
|
||||
Disables forwarding of Kerberos tickets.
|
||||
This may also be specified on a per-host basis in the configuration file.
|
||||
.It Fl l Ar login_name
|
||||
Specifies the user to log in as on the remote machine.
|
||||
@ -541,9 +544,10 @@ per-host basis in the configuration file.
|
||||
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.
|
||||
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
|
||||
@ -565,8 +569,10 @@ This is helpful in
|
||||
debugging connection, authentication, and configuration problems.
|
||||
Multiple
|
||||
.Fl v
|
||||
options increases the verbosity.
|
||||
Maximum is 3.
|
||||
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
|
||||
@ -645,9 +651,9 @@ 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 protocol is supported, and
|
||||
Currently the SOCKS4 and SOCKS5 protocols are supported, and
|
||||
.Nm
|
||||
will act as a SOCKS4 server.
|
||||
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
|
||||
@ -961,15 +967,6 @@ above.
|
||||
.Nm
|
||||
exits with the exit status of the remote command or with 255
|
||||
if an error occurred.
|
||||
.Sh AUTHORS
|
||||
OpenSSH is a derivative of the original and free
|
||||
ssh 1.2.12 release by Tatu Ylonen.
|
||||
Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos,
|
||||
Theo de Raadt and Dug Song
|
||||
removed many bugs, re-added newer features and
|
||||
created OpenSSH.
|
||||
Markus Friedl contributed the support for SSH
|
||||
protocol versions 1.5 and 2.0.
|
||||
.Sh SEE ALSO
|
||||
.Xr rsh 1 ,
|
||||
.Xr scp 1 ,
|
||||
@ -992,3 +989,12 @@ protocol versions 1.5 and 2.0.
|
||||
.%D January 2002
|
||||
.%O work in progress material
|
||||
.Re
|
||||
.Sh AUTHORS
|
||||
OpenSSH is a derivative of the original and free
|
||||
ssh 1.2.12 release by Tatu Ylonen.
|
||||
Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos,
|
||||
Theo de Raadt and Dug Song
|
||||
removed many bugs, re-added newer features and
|
||||
created OpenSSH.
|
||||
Markus Friedl contributed the support for SSH
|
||||
protocol versions 1.5 and 2.0.
|
||||
|
@ -40,7 +40,7 @@
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: ssh.c,v 1.190 2003/02/06 09:27:29 markus Exp $");
|
||||
RCSID("$OpenBSD: ssh.c,v 1.201 2003/09/01 18:15:50 markus Exp $");
|
||||
RCSID("$FreeBSD$");
|
||||
|
||||
#include <openssl/evp.h>
|
||||
@ -80,14 +80,6 @@ extern char *__progname;
|
||||
char *__progname;
|
||||
#endif
|
||||
|
||||
/* Flag indicating whether IPv4 or IPv6. This can be set on the command line.
|
||||
Default value is AF_UNSPEC means both IPv4 and IPv6. */
|
||||
#ifdef IPV4_DEFAULT
|
||||
int IPv4or6 = AF_INET;
|
||||
#else
|
||||
int IPv4or6 = AF_UNSPEC;
|
||||
#endif
|
||||
|
||||
/* Flag indicating whether debug mode is on. This can be set on the command line. */
|
||||
int debug_flag = 0;
|
||||
|
||||
@ -163,9 +155,6 @@ usage(void)
|
||||
_PATH_SSH_USER_CONFFILE);
|
||||
fprintf(stderr, " -A Enable authentication agent forwarding.\n");
|
||||
fprintf(stderr, " -a Disable authentication agent forwarding (default).\n");
|
||||
#ifdef AFS
|
||||
fprintf(stderr, " -k Disable Kerberos ticket and AFS token forwarding.\n");
|
||||
#endif /* AFS */
|
||||
fprintf(stderr, " -X Enable X11 connection forwarding.\n");
|
||||
fprintf(stderr, " -x Disable X11 connection forwarding (default).\n");
|
||||
fprintf(stderr, " -i file Identity for public key authentication "
|
||||
@ -223,7 +212,7 @@ main(int ac, char **av)
|
||||
extern int optind, optreset;
|
||||
extern char *optarg;
|
||||
|
||||
__progname = get_progname(av[0]);
|
||||
__progname = ssh_get_progname(av[0]);
|
||||
init_rng();
|
||||
|
||||
/*
|
||||
@ -254,7 +243,7 @@ main(int ac, char **av)
|
||||
/* Get user data. */
|
||||
pw = getpwuid(original_real_uid);
|
||||
if (!pw) {
|
||||
log("unknown user %d", original_real_uid);
|
||||
logit("You don't exist, go away!");
|
||||
exit(1);
|
||||
}
|
||||
/* Take a copy of the returned structure. */
|
||||
@ -285,10 +274,10 @@ main(int ac, char **av)
|
||||
options.protocol = SSH_PROTO_2;
|
||||
break;
|
||||
case '4':
|
||||
IPv4or6 = AF_INET;
|
||||
options.address_family = AF_INET;
|
||||
break;
|
||||
case '6':
|
||||
IPv4or6 = AF_INET6;
|
||||
options.address_family = AF_INET6;
|
||||
break;
|
||||
case 'n':
|
||||
stdin_null_flag = 1;
|
||||
@ -315,12 +304,9 @@ main(int ac, char **av)
|
||||
case 'A':
|
||||
options.forward_agent = 1;
|
||||
break;
|
||||
#ifdef AFS
|
||||
case 'k':
|
||||
options.kerberos_tgt_passing = 0;
|
||||
options.afs_token_passing = 0;
|
||||
/* ignored for backward compatibility */
|
||||
break;
|
||||
#endif
|
||||
case 'i':
|
||||
if (stat(optarg, &st) < 0) {
|
||||
fprintf(stderr, "Warning: Identity file %s "
|
||||
@ -347,22 +333,22 @@ main(int ac, char **av)
|
||||
tty_flag = 1;
|
||||
break;
|
||||
case 'v':
|
||||
if (0 == debug_flag) {
|
||||
if (debug_flag == 0) {
|
||||
debug_flag = 1;
|
||||
options.log_level = SYSLOG_LEVEL_DEBUG1;
|
||||
} else if (options.log_level < SYSLOG_LEVEL_DEBUG3) {
|
||||
options.log_level++;
|
||||
} else {
|
||||
if (options.log_level < SYSLOG_LEVEL_DEBUG3)
|
||||
options.log_level++;
|
||||
break;
|
||||
} else
|
||||
fatal("Too high debugging level.");
|
||||
}
|
||||
/* fallthrough */
|
||||
case 'V':
|
||||
fprintf(stderr,
|
||||
"%s, SSH protocols %d.%d/%d.%d, OpenSSL 0x%8.8lx\n",
|
||||
"%s, SSH protocols %d.%d/%d.%d, %s\n",
|
||||
SSH_VERSION,
|
||||
PROTOCOL_MAJOR_1, PROTOCOL_MINOR_1,
|
||||
PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2,
|
||||
SSLeay());
|
||||
SSLeay_version(SSLEAY_VERSION));
|
||||
if (opt == 'V')
|
||||
exit(0);
|
||||
break;
|
||||
@ -428,9 +414,9 @@ main(int ac, char **av)
|
||||
|
||||
case 'L':
|
||||
case 'R':
|
||||
if (sscanf(optarg, "%5[0-9]:%255[^:]:%5[0-9]",
|
||||
if (sscanf(optarg, "%5[0123456789]:%255[^:]:%5[0123456789]",
|
||||
sfwd_port, buf, sfwd_host_port) != 3 &&
|
||||
sscanf(optarg, "%5[0-9]/%255[^/]/%5[0-9]",
|
||||
sscanf(optarg, "%5[0123456789]/%255[^/]/%5[0123456789]",
|
||||
sfwd_port, buf, sfwd_host_port) != 3) {
|
||||
fprintf(stderr,
|
||||
"Bad forwarding specification '%s'\n",
|
||||
@ -459,7 +445,7 @@ main(int ac, char **av)
|
||||
optarg);
|
||||
exit(1);
|
||||
}
|
||||
add_local_forward(&options, fwd_port, "socks4", 0);
|
||||
add_local_forward(&options, fwd_port, "socks", 0);
|
||||
break;
|
||||
|
||||
case 'C':
|
||||
@ -519,7 +505,6 @@ main(int ac, char **av)
|
||||
|
||||
SSLeay_add_all_algorithms();
|
||||
ERR_load_crypto_strings();
|
||||
channel_set_af(IPv4or6);
|
||||
|
||||
/* Initialize the command to execute on remote host. */
|
||||
buffer_init(&command);
|
||||
@ -560,7 +545,7 @@ main(int ac, char **av)
|
||||
/* Do not allocate a tty if stdin is not a tty. */
|
||||
if (!isatty(fileno(stdin)) && !force_tty_flag) {
|
||||
if (tty_flag)
|
||||
log("Pseudo-terminal will not be allocated because stdin is not a terminal.");
|
||||
logit("Pseudo-terminal will not be allocated because stdin is not a terminal.");
|
||||
tty_flag = 0;
|
||||
}
|
||||
|
||||
@ -591,6 +576,8 @@ main(int ac, char **av)
|
||||
/* Fill configuration defaults. */
|
||||
fill_default_options(&options);
|
||||
|
||||
channel_set_af(options.address_family);
|
||||
|
||||
/* reinit */
|
||||
log_init(av[0], options.log_level, SYSLOG_FACILITY_USER, 1);
|
||||
|
||||
@ -608,7 +595,7 @@ main(int ac, char **av)
|
||||
struct addrinfo *ai = NULL;
|
||||
int errgai;
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = IPv4or6;
|
||||
hints.ai_family = options.address_family;
|
||||
hints.ai_flags = AI_CANONNAME;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
errgai = getaddrinfo(host, NULL, &hints, &ai);
|
||||
@ -619,25 +606,20 @@ main(int ac, char **av)
|
||||
}
|
||||
}
|
||||
|
||||
/* force lowercase for hostkey matching */
|
||||
if (options.host_key_alias != NULL) {
|
||||
for (p = options.host_key_alias; *p; p++)
|
||||
if (isupper(*p))
|
||||
*p = tolower(*p);
|
||||
}
|
||||
|
||||
if (options.proxy_command != NULL &&
|
||||
strcmp(options.proxy_command, "none") == 0)
|
||||
options.proxy_command = NULL;
|
||||
|
||||
/* Disable rhosts authentication if not running as root. */
|
||||
#ifdef HAVE_CYGWIN
|
||||
/* Ignore uid if running under Windows */
|
||||
if (!options.use_privileged_port) {
|
||||
#else
|
||||
if (original_effective_uid != 0 || !options.use_privileged_port) {
|
||||
#endif
|
||||
debug("Rhosts Authentication disabled, "
|
||||
"originating port will not be trusted.");
|
||||
options.rhosts_authentication = 0;
|
||||
}
|
||||
/* Open a connection to the remote host. */
|
||||
|
||||
if (ssh_connect(host, &hostaddr, options.port, IPv4or6,
|
||||
options.connection_attempts,
|
||||
if (ssh_connect(host, &hostaddr, options.port,
|
||||
options.address_family, options.connection_attempts,
|
||||
#ifdef HAVE_CYGWIN
|
||||
options.use_privileged_port,
|
||||
#else
|
||||
@ -811,7 +793,7 @@ x11_get_proto(char **_proto, char **_data)
|
||||
if (!got_data) {
|
||||
u_int32_t rand = 0;
|
||||
|
||||
log("Warning: No xauth data; using fake authentication data for X11 forwarding.");
|
||||
logit("Warning: No xauth data; using fake authentication data for X11 forwarding.");
|
||||
strlcpy(proto, "MIT-MAGIC-COOKIE-1", sizeof proto);
|
||||
for (i = 0; i < 16; i++) {
|
||||
if (i % 4 == 0)
|
||||
@ -891,7 +873,7 @@ ssh_session(void)
|
||||
if (type == SSH_SMSG_SUCCESS)
|
||||
packet_start_compression(options.compression_level);
|
||||
else if (type == SSH_SMSG_FAILURE)
|
||||
log("Warning: Remote host refused compression.");
|
||||
logit("Warning: Remote host refused compression.");
|
||||
else
|
||||
packet_disconnect("Protocol error waiting for compression response.");
|
||||
}
|
||||
@ -930,7 +912,7 @@ ssh_session(void)
|
||||
interactive = 1;
|
||||
have_tty = 1;
|
||||
} else if (type == SSH_SMSG_FAILURE)
|
||||
log("Warning: Remote host failed or refused to allocate a pseudo tty.");
|
||||
logit("Warning: Remote host failed or refused to allocate a pseudo tty.");
|
||||
else
|
||||
packet_disconnect("Protocol error waiting for pty request response.");
|
||||
}
|
||||
@ -948,7 +930,7 @@ ssh_session(void)
|
||||
if (type == SSH_SMSG_SUCCESS) {
|
||||
interactive = 1;
|
||||
} else if (type == SSH_SMSG_FAILURE) {
|
||||
log("Warning: Remote host denied X11 forwarding.");
|
||||
logit("Warning: Remote host denied X11 forwarding.");
|
||||
} else {
|
||||
packet_disconnect("Protocol error waiting for X11 forwarding");
|
||||
}
|
||||
@ -967,7 +949,7 @@ ssh_session(void)
|
||||
type = packet_read();
|
||||
packet_check_eom();
|
||||
if (type != SSH_SMSG_SUCCESS)
|
||||
log("Warning: Remote host denied authentication agent forwarding.");
|
||||
logit("Warning: Remote host denied authentication agent forwarding.");
|
||||
}
|
||||
|
||||
/* Initiate port forwardings. */
|
||||
@ -1035,7 +1017,7 @@ client_global_request_reply(int type, u_int32_t seq, void *ctxt)
|
||||
options.remote_forwards[i].host,
|
||||
options.remote_forwards[i].host_port);
|
||||
if (type == SSH2_MSG_REQUEST_FAILURE)
|
||||
log("Warning: remote port forwarding failed for listen port %d",
|
||||
logit("Warning: remote port forwarding failed for listen port %d",
|
||||
options.remote_forwards[i].port);
|
||||
}
|
||||
|
||||
@ -1150,7 +1132,7 @@ ssh_session2_open(void)
|
||||
c = channel_new(
|
||||
"session", SSH_CHANNEL_OPENING, in, out, err,
|
||||
window, packetmax, CHAN_EXTENDED_WRITE,
|
||||
xstrdup("client-session"), /*nonblock*/0);
|
||||
"client-session", /*nonblock*/0);
|
||||
|
||||
debug3("ssh_session2_open: channel_new: %d", c->self);
|
||||
|
||||
@ -1202,7 +1184,7 @@ load_public_identity_files(void)
|
||||
sizeof(Key *) * (SSH_MAX_IDENTITY_FILES - 1));
|
||||
options.num_identity_files++;
|
||||
options.identity_keys[0] = keys[i];
|
||||
options.identity_files[0] = xstrdup("smartcard key");;
|
||||
options.identity_files[0] = sc_get_key_label(keys[i]);
|
||||
}
|
||||
if (options.num_identity_files > SSH_MAX_IDENTITY_FILES)
|
||||
options.num_identity_files = SSH_MAX_IDENTITY_FILES;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: ssh.h,v 1.71 2002/06/22 02:00:29 stevesk Exp $ */
|
||||
/* $OpenBSD: ssh.h,v 1.74 2003/09/01 13:52:18 markus Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@ -20,7 +20,6 @@
|
||||
#include <stdarg.h> /* For va_list */
|
||||
#include <syslog.h> /* For LOG_AUTH and friends */
|
||||
#include <sys/socket.h> /* For struct sockaddr_storage */
|
||||
#include "openbsd-compat/fake-socket.h" /* For struct sockaddr_storage */
|
||||
#ifdef HAVE_SYS_SELECT_H
|
||||
# include <sys/select.h>
|
||||
#endif
|
||||
@ -89,9 +88,6 @@
|
||||
*/
|
||||
#define SSH_SESSION_KEY_LENGTH 32
|
||||
|
||||
/* Name of Kerberos service for SSH to use. */
|
||||
#define KRB4_SERVICE_NAME "rcmd"
|
||||
|
||||
/* Used to identify ``EscapeChar none'' */
|
||||
#define SSH_ESCAPECHAR_NONE -2
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $OpenBSD: ssh_config,v 1.16 2002/07/03 14:21:05 markus Exp $
|
||||
# $OpenBSD: ssh_config,v 1.19 2003/08/13 08:46:31 markus Exp $
|
||||
# $FreeBSD$
|
||||
|
||||
# This is the ssh client system-wide configuration file. See
|
||||
@ -19,13 +19,14 @@
|
||||
# Host *
|
||||
# ForwardAgent no
|
||||
# ForwardX11 no
|
||||
# RhostsAuthentication no
|
||||
# RhostsRSAAuthentication no
|
||||
# RSAAuthentication yes
|
||||
# PasswordAuthentication yes
|
||||
# HostbasedAuthentication no
|
||||
# BatchMode no
|
||||
# CheckHostIP no
|
||||
# AddressFamily any
|
||||
# ConnectTimeout 0
|
||||
# StrictHostKeyChecking ask
|
||||
# IdentityFile ~/.ssh/identity
|
||||
# IdentityFile ~/.ssh/id_rsa
|
||||
@ -35,4 +36,4 @@
|
||||
# Cipher 3des
|
||||
# Ciphers aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour,aes192-cbc,aes256-cbc
|
||||
# EscapeChar ~
|
||||
# VersionAddendum FreeBSD-20030924
|
||||
# VersionAddendum FreeBSD-20040106
|
||||
|
@ -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.7 2003/03/28 10:11:43 jmc Exp $
|
||||
.\" $OpenBSD: ssh_config.5,v 1.20 2003/09/02 18:50:06 jmc Exp $
|
||||
.\" $FreeBSD$
|
||||
.Dd September 25, 1999
|
||||
.Dt SSH_CONFIG 5
|
||||
@ -105,7 +105,7 @@ keyword) to be only for those hosts that match one of the patterns
|
||||
given after the keyword.
|
||||
.Ql \&*
|
||||
and
|
||||
.Ql ?
|
||||
.Ql \&?
|
||||
can be used as wildcards in the
|
||||
patterns.
|
||||
A single
|
||||
@ -116,13 +116,14 @@ The host is the
|
||||
.Ar hostname
|
||||
argument given on the command line (i.e., the name is not converted to
|
||||
a canonicalized host name before matching).
|
||||
.It Cm AFSTokenPassing
|
||||
Specifies whether to pass AFS tokens to remote host.
|
||||
The argument to this keyword must be
|
||||
.Dq yes
|
||||
or
|
||||
.Dq no .
|
||||
This option applies to protocol version 1 only.
|
||||
.It Cm AddressFamily
|
||||
Specifies which address family to use when connecting.
|
||||
Valid arguments are
|
||||
.Dq any ,
|
||||
.Dq inet
|
||||
(Use IPv4 only) or
|
||||
.Dq inet6
|
||||
(Use IPv6 only.)
|
||||
.It Cm BatchMode
|
||||
If set to
|
||||
.Dq yes ,
|
||||
@ -228,18 +229,41 @@ Specifies the number of tries (one per second) to make before exiting.
|
||||
The argument must be an integer.
|
||||
This may be useful in scripts if the connection sometimes fails.
|
||||
The default is 1.
|
||||
.It Cm ConnectTimeout
|
||||
Specifies the timeout (in seconds) used when connecting to the ssh
|
||||
server, instead of using the default system TCP timeout.
|
||||
This value is used only when the target is down or really unreachable,
|
||||
not when it refuses the connection.
|
||||
.It Cm DynamicForward
|
||||
Specifies that a TCP/IP port on the local machine be forwarded
|
||||
over the secure channel, and the application
|
||||
protocol is then used to determine where to connect to from the
|
||||
remote machine.
|
||||
The argument must be a port number.
|
||||
Currently the SOCKS4 protocol is supported, and
|
||||
Currently the SOCKS4 and SOCKS5 protocols are supported, and
|
||||
.Nm ssh
|
||||
will act as a SOCKS4 server.
|
||||
will act as a SOCKS server.
|
||||
Multiple forwardings may be specified, and
|
||||
additional forwardings can be given on the command line.
|
||||
Only the superuser can forward privileged ports.
|
||||
.It Cm EnableSSHKeysign
|
||||
Setting this option to
|
||||
.Dq yes
|
||||
in the global client configuration file
|
||||
.Pa /etc/ssh/ssh_config
|
||||
enables the use of the helper program
|
||||
.Xr ssh-keysign 8
|
||||
during
|
||||
.Cm HostbasedAuthentication .
|
||||
The argument must be
|
||||
.Dq yes
|
||||
or
|
||||
.Dq no .
|
||||
The default is
|
||||
.Dq no .
|
||||
See
|
||||
.Xr ssh-keysign 8
|
||||
for more information.
|
||||
.It Cm EscapeChar
|
||||
Sets the escape character (default:
|
||||
.Ql ~ ) .
|
||||
@ -308,6 +332,18 @@ The default is
|
||||
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.
|
||||
The default is
|
||||
.Dq yes .
|
||||
Note that this option applies to protocol version 2 only.
|
||||
.It Cm GSSAPIDelegateCredentials
|
||||
Forward (delegate) credentials to the server.
|
||||
The default is
|
||||
.Dq no .
|
||||
Note that this option applies to protocol version 2 only.
|
||||
.It Cm HostbasedAuthentication
|
||||
Specifies whether to try rhosts based authentication with public key
|
||||
authentication.
|
||||
@ -340,7 +376,8 @@ Numeric IP addresses are also permitted (both on the command line and in
|
||||
specifications).
|
||||
.It Cm IdentityFile
|
||||
Specifies a file from which the user's RSA or DSA authentication identity
|
||||
is read. The default is
|
||||
is read.
|
||||
The default is
|
||||
.Pa $HOME/.ssh/identity
|
||||
for protocol version 1, and
|
||||
.Pa $HOME/.ssh/id_rsa
|
||||
@ -371,19 +408,6 @@ 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 KerberosAuthentication
|
||||
Specifies whether Kerberos authentication will be used.
|
||||
The argument to this keyword must be
|
||||
.Dq yes
|
||||
or
|
||||
.Dq no .
|
||||
.It Cm KerberosTgtPassing
|
||||
Specifies whether a Kerberos TGT will be forwarded to the server.
|
||||
This will only work if the Kerberos server is actually an AFS kaserver.
|
||||
The argument to this keyword must be
|
||||
.Dq yes
|
||||
or
|
||||
.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.
|
||||
@ -437,7 +461,8 @@ Specifies the port number to connect on the remote host.
|
||||
Default is 22.
|
||||
.It Cm PreferredAuthentications
|
||||
Specifies the order in which the client should try protocol 2
|
||||
authentication methods. This allows a client to prefer one method (e.g.
|
||||
authentication methods.
|
||||
This allows a client to prefer one method (e.g.
|
||||
.Cm keyboard-interactive )
|
||||
over another method (e.g.
|
||||
.Cm password )
|
||||
@ -505,26 +530,6 @@ IPv6 addresses can be specified with an alternative syntax:
|
||||
Multiple forwardings may be specified, and additional
|
||||
forwardings can be given on the command line.
|
||||
Only the superuser can forward privileged ports.
|
||||
.It Cm RhostsAuthentication
|
||||
Specifies whether to try rhosts based authentication.
|
||||
Note that this
|
||||
declaration only affects the client side and has no effect whatsoever
|
||||
on security.
|
||||
Most servers do not permit RhostsAuthentication because it
|
||||
is not secure (see
|
||||
.Cm RhostsRSAAuthentication ) .
|
||||
The argument to this keyword must be
|
||||
.Dq yes
|
||||
or
|
||||
.Dq no .
|
||||
The default is
|
||||
.Dq no .
|
||||
This option applies to protocol version 1 only and requires
|
||||
.Nm ssh
|
||||
to be setuid root and
|
||||
.Cm UsePrivilegedPort
|
||||
to be set to
|
||||
.Dq yes .
|
||||
.It Cm RhostsRSAAuthentication
|
||||
Specifies whether to try rhosts based authentication with RSA host
|
||||
authentication.
|
||||
@ -550,12 +555,12 @@ The default is
|
||||
.Dq yes .
|
||||
Note that this option applies to protocol version 1 only.
|
||||
.It Cm SmartcardDevice
|
||||
Specifies which smartcard device to use. The argument to this keyword is
|
||||
the device
|
||||
Specifies which smartcard device to use.
|
||||
The argument to this keyword is the device
|
||||
.Nm ssh
|
||||
should use to communicate with a smartcard used for storing the user's
|
||||
private RSA key. By default, no device is specified and smartcard support
|
||||
is not activated.
|
||||
private RSA key.
|
||||
By default, no device is specified and smartcard support is not activated.
|
||||
.It Cm StrictHostKeyChecking
|
||||
If this flag is set to
|
||||
.Dq yes ,
|
||||
@ -605,11 +610,9 @@ If set to
|
||||
must be setuid root.
|
||||
Note that this option must be set to
|
||||
.Dq yes
|
||||
if
|
||||
.Cm RhostsAuthentication
|
||||
and
|
||||
for
|
||||
.Cm RhostsRSAAuthentication
|
||||
authentications are needed with older servers.
|
||||
with older servers.
|
||||
.It Cm User
|
||||
Specifies the user to log in as.
|
||||
This can be useful when a different user name is used on different machines.
|
||||
@ -619,11 +622,17 @@ having to remember to give the user name on the command line.
|
||||
Specifies a file to use for the user
|
||||
host key database instead of
|
||||
.Pa $HOME/.ssh/known_hosts .
|
||||
.It Cm VerifyHostKeyDNS
|
||||
Specifies whether to verify the remote key using DNS and SSHFP resource
|
||||
records.
|
||||
The default is
|
||||
.Dq no .
|
||||
Note that this option applies to protocol version 2 only.
|
||||
.It Cm VersionAddendum
|
||||
Specifies a string to append to the regular version string to identify
|
||||
OS- or site-specific modifications.
|
||||
The default is
|
||||
.Dq FreeBSD-20030924 .
|
||||
.Dq FreeBSD-20040106 .
|
||||
.It Cm XAuthLocation
|
||||
Specifies the full pathname of the
|
||||
.Xr xauth 1
|
||||
@ -649,6 +658,8 @@ values that are not specified in the user's configuration file, and
|
||||
for those users who do not have a configuration file.
|
||||
This file must be world-readable.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr ssh 1
|
||||
.Sh AUTHORS
|
||||
OpenSSH is a derivative of the original and free
|
||||
ssh 1.2.12 release by Tatu Ylonen.
|
||||
@ -658,5 +669,3 @@ removed many bugs, re-added newer features and
|
||||
created OpenSSH.
|
||||
Markus Friedl contributed the support for SSH
|
||||
protocol versions 1.5 and 2.0.
|
||||
.Sh SEE ALSO
|
||||
.Xr ssh 1
|
||||
|
@ -13,7 +13,7 @@
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: sshconnect.c,v 1.137 2002/11/21 23:03:51 deraadt Exp $");
|
||||
RCSID("$OpenBSD: sshconnect.c,v 1.148 2003/09/18 07:52:54 markus Exp $");
|
||||
|
||||
#include <openssl/bn.h>
|
||||
|
||||
@ -33,9 +33,17 @@ RCSID("$OpenBSD: sshconnect.c,v 1.137 2002/11/21 23:03:51 deraadt 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
|
||||
|
||||
/* import */
|
||||
extern Options options;
|
||||
extern char *__progname;
|
||||
@ -163,7 +171,7 @@ ssh_proxy_connect(const char *host, u_short port, const char *proxy_command)
|
||||
* Creates a (possibly privileged) socket for use as the ssh connection.
|
||||
*/
|
||||
static int
|
||||
ssh_create_socket(int privileged, int family)
|
||||
ssh_create_socket(int privileged, struct addrinfo *ai)
|
||||
{
|
||||
int sock, gaierr;
|
||||
struct addrinfo hints, *res;
|
||||
@ -175,15 +183,16 @@ ssh_create_socket(int privileged, int family)
|
||||
if (privileged) {
|
||||
int p = IPPORT_RESERVED - 1;
|
||||
PRIV_START;
|
||||
sock = rresvport_af(&p, family);
|
||||
sock = rresvport_af(&p, ai->ai_family);
|
||||
PRIV_END;
|
||||
if (sock < 0)
|
||||
error("rresvport: af=%d %.100s", family, strerror(errno));
|
||||
error("rresvport: af=%d %.100s", ai->ai_family,
|
||||
strerror(errno));
|
||||
else
|
||||
debug("Allocated local port %d.", p);
|
||||
return sock;
|
||||
}
|
||||
sock = socket(family, SOCK_STREAM, 0);
|
||||
sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
|
||||
if (sock < 0)
|
||||
error("socket: %.100s", strerror(errno));
|
||||
|
||||
@ -192,8 +201,9 @@ ssh_create_socket(int privileged, int family)
|
||||
return sock;
|
||||
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = family;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
hints.ai_family = ai->ai_family;
|
||||
hints.ai_socktype = ai->ai_socktype;
|
||||
hints.ai_protocol = ai->ai_protocol;
|
||||
hints.ai_flags = AI_PASSIVE;
|
||||
gaierr = getaddrinfo(options.bind_address, "0", &hints, &res);
|
||||
if (gaierr) {
|
||||
@ -212,6 +222,74 @@ ssh_create_socket(int privileged, int family)
|
||||
return sock;
|
||||
}
|
||||
|
||||
static int
|
||||
timeout_connect(int sockfd, const struct sockaddr *serv_addr,
|
||||
socklen_t addrlen, int timeout)
|
||||
{
|
||||
fd_set *fdset;
|
||||
struct timeval tv;
|
||||
socklen_t optlen;
|
||||
int fdsetsz, optval, rc, result = -1;
|
||||
|
||||
if (timeout <= 0)
|
||||
return (connect(sockfd, serv_addr, addrlen));
|
||||
|
||||
if (fcntl(sockfd, F_SETFL, O_NONBLOCK) < 0)
|
||||
return (-1);
|
||||
|
||||
rc = connect(sockfd, serv_addr, addrlen);
|
||||
if (rc == 0)
|
||||
return (0);
|
||||
if (errno != EINPROGRESS)
|
||||
return (-1);
|
||||
|
||||
fdsetsz = howmany(sockfd + 1, NFDBITS) * sizeof(fd_mask);
|
||||
fdset = (fd_set *)xmalloc(fdsetsz);
|
||||
|
||||
memset(fdset, 0, fdsetsz);
|
||||
FD_SET(sockfd, fdset);
|
||||
tv.tv_sec = timeout;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
for(;;) {
|
||||
rc = select(sockfd + 1, NULL, fdset, NULL, &tv);
|
||||
if (rc != -1 || errno != EINTR)
|
||||
break;
|
||||
}
|
||||
|
||||
switch(rc) {
|
||||
case 0:
|
||||
/* Timed out */
|
||||
errno = ETIMEDOUT;
|
||||
break;
|
||||
case -1:
|
||||
/* Select error */
|
||||
debug("select: %s", strerror(errno));
|
||||
break;
|
||||
case 1:
|
||||
/* Completed or failed */
|
||||
optval = 0;
|
||||
optlen = sizeof(optval);
|
||||
if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &optval,
|
||||
&optlen) == -1) {
|
||||
debug("getsockopt: %s", strerror(errno));
|
||||
break;
|
||||
}
|
||||
if (optval != 0) {
|
||||
errno = optval;
|
||||
break;
|
||||
}
|
||||
result = 0;
|
||||
break;
|
||||
default:
|
||||
/* Should not occur */
|
||||
fatal("Bogus return (%d) from select()", rc);
|
||||
}
|
||||
|
||||
xfree(fdset);
|
||||
return (result);
|
||||
}
|
||||
|
||||
/*
|
||||
* Opens a TCP/IP connection to the remote server on the given host.
|
||||
* The address of the remote host will be returned in hostaddr.
|
||||
@ -295,12 +373,13 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr,
|
||||
host, ntop, strport);
|
||||
|
||||
/* Create a socket for connecting. */
|
||||
sock = ssh_create_socket(needpriv, ai->ai_family);
|
||||
sock = ssh_create_socket(needpriv, ai);
|
||||
if (sock < 0)
|
||||
/* Any error is already output */
|
||||
continue;
|
||||
|
||||
if (connect(sock, ai->ai_addr, ai->ai_addrlen) >= 0) {
|
||||
if (timeout_connect(sock, ai->ai_addr, ai->ai_addrlen,
|
||||
options.connection_timeout) >= 0) {
|
||||
/* Successful connection. */
|
||||
memcpy(hostaddr, ai->ai_addr, ai->ai_addrlen);
|
||||
break;
|
||||
@ -332,7 +411,7 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr,
|
||||
|
||||
/* Return failure if we didn't get a successful connection. */
|
||||
if (attempt >= connection_attempts) {
|
||||
log("ssh: connect to host %s port %s: %s",
|
||||
logit("ssh: connect to host %s port %s: %s",
|
||||
host, strport, strerror(errno));
|
||||
return full_failure ? ECONNABORTED : ECONNREFUSED;
|
||||
}
|
||||
@ -421,7 +500,7 @@ ssh_exchange_identification(void)
|
||||
enable_compat13();
|
||||
minor1 = 3;
|
||||
if (options.forward_agent) {
|
||||
log("Agent forwarding disabled for protocol 1.3");
|
||||
logit("Agent forwarding disabled for protocol 1.3");
|
||||
options.forward_agent = 0;
|
||||
}
|
||||
}
|
||||
@ -445,7 +524,7 @@ ssh_exchange_identification(void)
|
||||
compat20 ? PROTOCOL_MAJOR_2 : PROTOCOL_MAJOR_1,
|
||||
compat20 ? PROTOCOL_MINOR_2 : minor1,
|
||||
SSH_VERSION);
|
||||
if (atomicio(write, connection_out, buf, strlen(buf)) != strlen(buf))
|
||||
if (atomicio(vwrite, connection_out, buf, strlen(buf)) != strlen(buf))
|
||||
fatal("write: %.100s", strerror(errno));
|
||||
client_version_string = xstrdup(buf);
|
||||
chop(client_version_string);
|
||||
@ -496,7 +575,7 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
|
||||
int salen;
|
||||
char ntop[NI_MAXHOST];
|
||||
char msg[1024];
|
||||
int len, host_line, ip_line, has_keys;
|
||||
int len, host_line, ip_line;
|
||||
const char *host_file = NULL, *ip_file = NULL;
|
||||
|
||||
/*
|
||||
@ -612,16 +691,16 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
|
||||
debug("Found key in %s:%d", host_file, host_line);
|
||||
if (options.check_host_ip && ip_status == HOST_NEW) {
|
||||
if (readonly)
|
||||
log("%s host key for IP address "
|
||||
logit("%s host key for IP address "
|
||||
"'%.128s' not in list of known hosts.",
|
||||
type, ip);
|
||||
else if (!add_host_to_hostfile(user_hostfile, ip,
|
||||
host_key))
|
||||
log("Failed to add the %s host key for IP "
|
||||
logit("Failed to add the %s host key for IP "
|
||||
"address '%.128s' to the list of known "
|
||||
"hosts (%.30s).", type, ip, user_hostfile);
|
||||
else
|
||||
log("Warning: Permanently added the %s host "
|
||||
logit("Warning: Permanently added the %s host "
|
||||
"key for IP address '%.128s' to the list "
|
||||
"of known hosts.", type, ip);
|
||||
}
|
||||
@ -640,19 +719,36 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
|
||||
"have requested strict checking.", type, host);
|
||||
goto fail;
|
||||
} else if (options.strict_host_key_checking == 2) {
|
||||
has_keys = show_other_keys(host, host_key);
|
||||
char msg1[1024], msg2[1024];
|
||||
|
||||
if (show_other_keys(host, host_key))
|
||||
snprintf(msg1, sizeof(msg1),
|
||||
"\nbut keys of different type are already"
|
||||
" known for this host.");
|
||||
else
|
||||
snprintf(msg1, sizeof(msg1), ".");
|
||||
/* 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)
|
||||
snprintf(msg2, sizeof(msg2),
|
||||
"Matching host key fingerprint"
|
||||
" found in DNS.\n");
|
||||
else
|
||||
snprintf(msg2, sizeof(msg2),
|
||||
"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"
|
||||
"%s key fingerprint is %s.\n"
|
||||
"%s key fingerprint is %s.\n%s"
|
||||
"Are you sure you want to continue connecting "
|
||||
"(yes/no)? ",
|
||||
host, ip,
|
||||
has_keys ? ",\nbut keys of different type are already "
|
||||
"known for this host." : ".",
|
||||
type, fp);
|
||||
host, ip, msg1, type, fp, msg2);
|
||||
xfree(fp);
|
||||
if (!confirm(msg))
|
||||
goto fail;
|
||||
@ -668,10 +764,10 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
|
||||
* local known_hosts file.
|
||||
*/
|
||||
if (!add_host_to_hostfile(user_hostfile, hostp, host_key))
|
||||
log("Failed to add the host to the list of known "
|
||||
logit("Failed to add the host to the list of known "
|
||||
"hosts (%.500s).", user_hostfile);
|
||||
else
|
||||
log("Warning: Permanently added '%.200s' (%s) to the "
|
||||
logit("Warning: Permanently added '%.200s' (%s) to the "
|
||||
"list of known hosts.", hostp, type);
|
||||
break;
|
||||
case HOST_CHANGED:
|
||||
@ -722,7 +818,7 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
|
||||
|
||||
/*
|
||||
* If strict host key checking has not been requested, allow
|
||||
* the connection but without password authentication or
|
||||
* the connection but without MITM-able authentication or
|
||||
* agent forwarding.
|
||||
*/
|
||||
if (options.password_authentication) {
|
||||
@ -730,6 +826,17 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
|
||||
"man-in-the-middle attacks.");
|
||||
options.password_authentication = 0;
|
||||
}
|
||||
if (options.kbd_interactive_authentication) {
|
||||
error("Keyboard-interactive authentication is disabled"
|
||||
" to avoid man-in-the-middle attacks.");
|
||||
options.kbd_interactive_authentication = 0;
|
||||
options.challenge_response_authentication = 0;
|
||||
}
|
||||
if (options.challenge_response_authentication) {
|
||||
error("Challenge/response authentication is disabled"
|
||||
" to avoid man-in-the-middle attacks.");
|
||||
options.challenge_response_authentication = 0;
|
||||
}
|
||||
if (options.forward_agent) {
|
||||
error("Agent forwarding is disabled to avoid "
|
||||
"man-in-the-middle attacks.");
|
||||
@ -774,7 +881,7 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
|
||||
host_file, host_line);
|
||||
}
|
||||
if (options.strict_host_key_checking == 1) {
|
||||
log(msg);
|
||||
logit("%s", msg);
|
||||
error("Exiting, you have requested strict checking.");
|
||||
goto fail;
|
||||
} else if (options.strict_host_key_checking == 2) {
|
||||
@ -783,7 +890,7 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
|
||||
if (!confirm(msg))
|
||||
goto fail;
|
||||
} else {
|
||||
log(msg);
|
||||
logit("%s", msg);
|
||||
}
|
||||
}
|
||||
|
||||
@ -795,11 +902,33 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* returns 0 if key verifies or -1 if key does NOT verify */
|
||||
int
|
||||
verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key)
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
#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;
|
||||
}
|
||||
}
|
||||
#endif /* DNS */
|
||||
|
||||
/* return ok if the key can be found in an old keyfile */
|
||||
if (stat(options.system_hostfile2, &st) == 0 ||
|
||||
stat(options.user_hostfile2, &st) == 0) {
|
||||
@ -881,7 +1010,7 @@ show_key_from_file(const char *file, const char *host, int keytype)
|
||||
if ((ret = lookup_key_in_hostfile_by_type(file, host,
|
||||
keytype, found, &line))) {
|
||||
fp = key_fingerprint(found, SSH_FP_MD5, SSH_FP_HEX);
|
||||
log("WARNING: %s key found for host %s\n"
|
||||
logit("WARNING: %s key found for host %s\n"
|
||||
"in %s:%d\n"
|
||||
"%s key fingerprint %s.",
|
||||
key_type(found), host, file, line,
|
||||
|
@ -13,25 +13,11 @@
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: sshconnect1.c,v 1.52 2002/08/08 13:50:23 aaron Exp $");
|
||||
RCSID("$OpenBSD: sshconnect1.c,v 1.56 2003/08/28 12:54:34 markus Exp $");
|
||||
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/md5.h>
|
||||
|
||||
#ifdef KRB4
|
||||
#include <krb.h>
|
||||
#endif
|
||||
#ifdef KRB5
|
||||
#include <krb5.h>
|
||||
#ifndef HEIMDAL
|
||||
#define krb5_get_err_text(context,code) error_message(code)
|
||||
#endif /* !HEIMDAL */
|
||||
#endif
|
||||
#ifdef AFS
|
||||
#include <kafs.h>
|
||||
#include "radix.h"
|
||||
#endif
|
||||
|
||||
#include "ssh.h"
|
||||
#include "ssh1.h"
|
||||
#include "xmalloc.h"
|
||||
@ -122,7 +108,7 @@ try_agent_authentication(void)
|
||||
* although it advertised it supports this. Just
|
||||
* return a wrong value.
|
||||
*/
|
||||
log("Authentication agent failed to decrypt challenge.");
|
||||
logit("Authentication agent failed to decrypt challenge.");
|
||||
memset(response, 0, sizeof(response));
|
||||
}
|
||||
key_free(key);
|
||||
@ -380,478 +366,6 @@ try_rhosts_rsa_authentication(const char *local_user, Key * host_key)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef KRB4
|
||||
static int
|
||||
try_krb4_authentication(void)
|
||||
{
|
||||
KTEXT_ST auth; /* Kerberos data */
|
||||
char *reply;
|
||||
char inst[INST_SZ];
|
||||
char *realm;
|
||||
CREDENTIALS cred;
|
||||
int r, type;
|
||||
socklen_t slen;
|
||||
Key_schedule schedule;
|
||||
u_long checksum, cksum;
|
||||
MSG_DAT msg_data;
|
||||
struct sockaddr_in local, foreign;
|
||||
struct stat st;
|
||||
|
||||
/* Don't do anything if we don't have any tickets. */
|
||||
if (stat(tkt_string(), &st) < 0)
|
||||
return 0;
|
||||
|
||||
strlcpy(inst, (char *)krb_get_phost(get_canonical_hostname(1)),
|
||||
INST_SZ);
|
||||
|
||||
realm = (char *)krb_realmofhost(get_canonical_hostname(1));
|
||||
if (!realm) {
|
||||
debug("Kerberos v4: no realm for %s", get_canonical_hostname(1));
|
||||
return 0;
|
||||
}
|
||||
/* This can really be anything. */
|
||||
checksum = (u_long)getpid();
|
||||
|
||||
r = krb_mk_req(&auth, KRB4_SERVICE_NAME, inst, realm, checksum);
|
||||
if (r != KSUCCESS) {
|
||||
debug("Kerberos v4 krb_mk_req failed: %s", krb_err_txt[r]);
|
||||
return 0;
|
||||
}
|
||||
/* Get session key to decrypt the server's reply with. */
|
||||
r = krb_get_cred(KRB4_SERVICE_NAME, inst, realm, &cred);
|
||||
if (r != KSUCCESS) {
|
||||
debug("get_cred failed: %s", krb_err_txt[r]);
|
||||
return 0;
|
||||
}
|
||||
des_key_sched((des_cblock *) cred.session, schedule);
|
||||
|
||||
/* Send authentication info to server. */
|
||||
packet_start(SSH_CMSG_AUTH_KERBEROS);
|
||||
packet_put_string((char *) auth.dat, auth.length);
|
||||
packet_send();
|
||||
packet_write_wait();
|
||||
|
||||
/* Zero the buffer. */
|
||||
(void) memset(auth.dat, 0, MAX_KTXT_LEN);
|
||||
|
||||
slen = sizeof(local);
|
||||
memset(&local, 0, sizeof(local));
|
||||
if (getsockname(packet_get_connection_in(),
|
||||
(struct sockaddr *)&local, &slen) < 0)
|
||||
debug("getsockname failed: %s", strerror(errno));
|
||||
|
||||
slen = sizeof(foreign);
|
||||
memset(&foreign, 0, sizeof(foreign));
|
||||
if (getpeername(packet_get_connection_in(),
|
||||
(struct sockaddr *)&foreign, &slen) < 0) {
|
||||
debug("getpeername failed: %s", strerror(errno));
|
||||
fatal_cleanup();
|
||||
}
|
||||
/* Get server reply. */
|
||||
type = packet_read();
|
||||
switch (type) {
|
||||
case SSH_SMSG_FAILURE:
|
||||
/* Should really be SSH_SMSG_AUTH_KERBEROS_FAILURE */
|
||||
debug("Kerberos v4 authentication failed.");
|
||||
return 0;
|
||||
break;
|
||||
|
||||
case SSH_SMSG_AUTH_KERBEROS_RESPONSE:
|
||||
/* SSH_SMSG_AUTH_KERBEROS_SUCCESS */
|
||||
debug("Kerberos v4 authentication accepted.");
|
||||
|
||||
/* Get server's response. */
|
||||
reply = packet_get_string((u_int *) &auth.length);
|
||||
if (auth.length >= MAX_KTXT_LEN)
|
||||
fatal("Kerberos v4: Malformed response from server");
|
||||
memcpy(auth.dat, reply, auth.length);
|
||||
xfree(reply);
|
||||
|
||||
packet_check_eom();
|
||||
|
||||
/*
|
||||
* If his response isn't properly encrypted with the session
|
||||
* key, and the decrypted checksum fails to match, he's
|
||||
* bogus. Bail out.
|
||||
*/
|
||||
r = krb_rd_priv(auth.dat, auth.length, schedule, &cred.session,
|
||||
&foreign, &local, &msg_data);
|
||||
if (r != KSUCCESS) {
|
||||
debug("Kerberos v4 krb_rd_priv failed: %s",
|
||||
krb_err_txt[r]);
|
||||
packet_disconnect("Kerberos v4 challenge failed!");
|
||||
}
|
||||
/* Fetch the (incremented) checksum that we supplied in the request. */
|
||||
memcpy((char *)&cksum, (char *)msg_data.app_data,
|
||||
sizeof(cksum));
|
||||
cksum = ntohl(cksum);
|
||||
|
||||
/* If it matches, we're golden. */
|
||||
if (cksum == checksum + 1) {
|
||||
debug("Kerberos v4 challenge successful.");
|
||||
return 1;
|
||||
} else
|
||||
packet_disconnect("Kerberos v4 challenge failed!");
|
||||
break;
|
||||
|
||||
default:
|
||||
packet_disconnect("Protocol error on Kerberos v4 response: %d", type);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* KRB4 */
|
||||
|
||||
#ifdef KRB5
|
||||
static int
|
||||
try_krb5_authentication(krb5_context *context, krb5_auth_context *auth_context)
|
||||
{
|
||||
krb5_error_code problem;
|
||||
const char *tkfile;
|
||||
struct stat buf;
|
||||
krb5_ccache ccache = NULL;
|
||||
const char *remotehost;
|
||||
krb5_data ap;
|
||||
int type;
|
||||
krb5_ap_rep_enc_part *reply = NULL;
|
||||
int ret;
|
||||
|
||||
memset(&ap, 0, sizeof(ap));
|
||||
|
||||
problem = krb5_init_context(context);
|
||||
if (problem) {
|
||||
debug("Kerberos v5: krb5_init_context failed");
|
||||
ret = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
problem = krb5_auth_con_init(*context, auth_context);
|
||||
if (problem) {
|
||||
debug("Kerberos v5: krb5_auth_con_init failed");
|
||||
ret = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
#ifndef HEIMDAL
|
||||
problem = krb5_auth_con_setflags(*context, *auth_context,
|
||||
KRB5_AUTH_CONTEXT_RET_TIME);
|
||||
if (problem) {
|
||||
debug("Keberos v5: krb5_auth_con_setflags failed");
|
||||
ret = 0;
|
||||
goto out;
|
||||
}
|
||||
#endif
|
||||
|
||||
tkfile = krb5_cc_default_name(*context);
|
||||
if (strncmp(tkfile, "FILE:", 5) == 0)
|
||||
tkfile += 5;
|
||||
|
||||
if (stat(tkfile, &buf) == 0 && getuid() != buf.st_uid) {
|
||||
debug("Kerberos v5: could not get default ccache (permission denied).");
|
||||
ret = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
problem = krb5_cc_default(*context, &ccache);
|
||||
if (problem) {
|
||||
debug("Kerberos v5: krb5_cc_default failed: %s",
|
||||
krb5_get_err_text(*context, problem));
|
||||
ret = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
remotehost = get_canonical_hostname(1);
|
||||
|
||||
problem = krb5_mk_req(*context, auth_context, AP_OPTS_MUTUAL_REQUIRED,
|
||||
"host", remotehost, NULL, ccache, &ap);
|
||||
if (problem) {
|
||||
debug("Kerberos v5: krb5_mk_req failed: %s",
|
||||
krb5_get_err_text(*context, problem));
|
||||
ret = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
packet_start(SSH_CMSG_AUTH_KERBEROS);
|
||||
packet_put_string((char *) ap.data, ap.length);
|
||||
packet_send();
|
||||
packet_write_wait();
|
||||
|
||||
xfree(ap.data);
|
||||
ap.length = 0;
|
||||
|
||||
type = packet_read();
|
||||
switch (type) {
|
||||
case SSH_SMSG_FAILURE:
|
||||
/* Should really be SSH_SMSG_AUTH_KERBEROS_FAILURE */
|
||||
debug("Kerberos v5 authentication failed.");
|
||||
ret = 0;
|
||||
break;
|
||||
|
||||
case SSH_SMSG_AUTH_KERBEROS_RESPONSE:
|
||||
/* SSH_SMSG_AUTH_KERBEROS_SUCCESS */
|
||||
debug("Kerberos v5 authentication accepted.");
|
||||
|
||||
/* Get server's response. */
|
||||
ap.data = packet_get_string((unsigned int *) &ap.length);
|
||||
packet_check_eom();
|
||||
/* XXX je to dobre? */
|
||||
|
||||
problem = krb5_rd_rep(*context, *auth_context, &ap, &reply);
|
||||
if (problem) {
|
||||
ret = 0;
|
||||
}
|
||||
ret = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
packet_disconnect("Protocol error on Kerberos v5 response: %d",
|
||||
type);
|
||||
ret = 0;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
out:
|
||||
if (ccache != NULL)
|
||||
krb5_cc_close(*context, ccache);
|
||||
if (reply != NULL)
|
||||
krb5_free_ap_rep_enc_part(*context, reply);
|
||||
if (ap.length > 0)
|
||||
#ifdef HEIMDAL
|
||||
krb5_data_free(&ap);
|
||||
#else
|
||||
krb5_free_data_contents(*context, &ap);
|
||||
#endif
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static void
|
||||
send_krb5_tgt(krb5_context context, krb5_auth_context auth_context)
|
||||
{
|
||||
int fd, type;
|
||||
krb5_error_code problem;
|
||||
krb5_data outbuf;
|
||||
krb5_ccache ccache = NULL;
|
||||
krb5_creds creds;
|
||||
#ifdef HEIMDAL
|
||||
krb5_kdc_flags flags;
|
||||
#else
|
||||
int forwardable;
|
||||
#endif
|
||||
const char *remotehost;
|
||||
|
||||
memset(&creds, 0, sizeof(creds));
|
||||
memset(&outbuf, 0, sizeof(outbuf));
|
||||
|
||||
fd = packet_get_connection_in();
|
||||
|
||||
#ifdef HEIMDAL
|
||||
problem = krb5_auth_con_setaddrs_from_fd(context, auth_context, &fd);
|
||||
#else
|
||||
problem = krb5_auth_con_genaddrs(context, auth_context, fd,
|
||||
KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR |
|
||||
KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR);
|
||||
#endif
|
||||
if (problem)
|
||||
goto out;
|
||||
|
||||
problem = krb5_cc_default(context, &ccache);
|
||||
if (problem)
|
||||
goto out;
|
||||
|
||||
problem = krb5_cc_get_principal(context, ccache, &creds.client);
|
||||
if (problem)
|
||||
goto out;
|
||||
|
||||
remotehost = get_canonical_hostname(1);
|
||||
|
||||
#ifdef HEIMDAL
|
||||
problem = krb5_build_principal(context, &creds.server,
|
||||
strlen(creds.client->realm), creds.client->realm,
|
||||
"krbtgt", creds.client->realm, NULL);
|
||||
#else
|
||||
problem = krb5_build_principal(context, &creds.server,
|
||||
creds.client->realm.length, creds.client->realm.data,
|
||||
"host", remotehost, NULL);
|
||||
#endif
|
||||
if (problem)
|
||||
goto out;
|
||||
|
||||
creds.times.endtime = 0;
|
||||
|
||||
#ifdef HEIMDAL
|
||||
flags.i = 0;
|
||||
flags.b.forwarded = 1;
|
||||
flags.b.forwardable = krb5_config_get_bool(context, NULL,
|
||||
"libdefaults", "forwardable", NULL);
|
||||
problem = krb5_get_forwarded_creds(context, auth_context,
|
||||
ccache, flags.i, remotehost, &creds, &outbuf);
|
||||
#else
|
||||
forwardable = 1;
|
||||
problem = krb5_fwd_tgt_creds(context, auth_context, remotehost,
|
||||
creds.client, creds.server, ccache, forwardable, &outbuf);
|
||||
#endif
|
||||
|
||||
if (problem)
|
||||
goto out;
|
||||
|
||||
packet_start(SSH_CMSG_HAVE_KERBEROS_TGT);
|
||||
packet_put_string((char *)outbuf.data, outbuf.length);
|
||||
packet_send();
|
||||
packet_write_wait();
|
||||
|
||||
type = packet_read();
|
||||
|
||||
if (type == SSH_SMSG_SUCCESS) {
|
||||
char *pname;
|
||||
|
||||
krb5_unparse_name(context, creds.client, &pname);
|
||||
debug("Kerberos v5 TGT forwarded (%s).", pname);
|
||||
xfree(pname);
|
||||
} else
|
||||
debug("Kerberos v5 TGT forwarding failed.");
|
||||
|
||||
return;
|
||||
|
||||
out:
|
||||
if (problem)
|
||||
debug("Kerberos v5 TGT forwarding failed: %s",
|
||||
krb5_get_err_text(context, problem));
|
||||
if (creds.client)
|
||||
krb5_free_principal(context, creds.client);
|
||||
if (creds.server)
|
||||
krb5_free_principal(context, creds.server);
|
||||
if (ccache)
|
||||
krb5_cc_close(context, ccache);
|
||||
if (outbuf.data)
|
||||
xfree(outbuf.data);
|
||||
}
|
||||
#endif /* KRB5 */
|
||||
|
||||
#ifdef AFS
|
||||
static void
|
||||
send_krb4_tgt(void)
|
||||
{
|
||||
CREDENTIALS *creds;
|
||||
struct stat st;
|
||||
char buffer[4096], pname[ANAME_SZ], pinst[INST_SZ], prealm[REALM_SZ];
|
||||
int problem, type;
|
||||
|
||||
/* Don't do anything if we don't have any tickets. */
|
||||
if (stat(tkt_string(), &st) < 0)
|
||||
return;
|
||||
|
||||
creds = xmalloc(sizeof(*creds));
|
||||
|
||||
problem = krb_get_tf_fullname(TKT_FILE, pname, pinst, prealm);
|
||||
if (problem)
|
||||
goto out;
|
||||
|
||||
problem = krb_get_cred("krbtgt", prealm, prealm, creds);
|
||||
if (problem)
|
||||
goto out;
|
||||
|
||||
if (time(0) > krb_life_to_time(creds->issue_date, creds->lifetime)) {
|
||||
problem = RD_AP_EXP;
|
||||
goto out;
|
||||
}
|
||||
creds_to_radix(creds, (u_char *)buffer, sizeof(buffer));
|
||||
|
||||
packet_start(SSH_CMSG_HAVE_KERBEROS_TGT);
|
||||
packet_put_cstring(buffer);
|
||||
packet_send();
|
||||
packet_write_wait();
|
||||
|
||||
type = packet_read();
|
||||
|
||||
if (type == SSH_SMSG_SUCCESS)
|
||||
debug("Kerberos v4 TGT forwarded (%s%s%s@%s).",
|
||||
creds->pname, creds->pinst[0] ? "." : "",
|
||||
creds->pinst, creds->realm);
|
||||
else
|
||||
debug("Kerberos v4 TGT rejected.");
|
||||
|
||||
xfree(creds);
|
||||
return;
|
||||
|
||||
out:
|
||||
debug("Kerberos v4 TGT passing failed: %s", krb_err_txt[problem]);
|
||||
xfree(creds);
|
||||
}
|
||||
|
||||
static void
|
||||
send_afs_tokens(void)
|
||||
{
|
||||
CREDENTIALS creds;
|
||||
struct ViceIoctl parms;
|
||||
struct ClearToken ct;
|
||||
int i, type, len;
|
||||
char buf[2048], *p, *server_cell;
|
||||
char buffer[8192];
|
||||
|
||||
/* Move over ktc_GetToken, here's something leaner. */
|
||||
for (i = 0; i < 100; i++) { /* just in case */
|
||||
parms.in = (char *) &i;
|
||||
parms.in_size = sizeof(i);
|
||||
parms.out = buf;
|
||||
parms.out_size = sizeof(buf);
|
||||
if (k_pioctl(0, VIOCGETTOK, &parms, 0) != 0)
|
||||
break;
|
||||
p = buf;
|
||||
|
||||
/* Get secret token. */
|
||||
memcpy(&creds.ticket_st.length, p, sizeof(u_int));
|
||||
if (creds.ticket_st.length > MAX_KTXT_LEN)
|
||||
break;
|
||||
p += sizeof(u_int);
|
||||
memcpy(creds.ticket_st.dat, p, creds.ticket_st.length);
|
||||
p += creds.ticket_st.length;
|
||||
|
||||
/* Get clear token. */
|
||||
memcpy(&len, p, sizeof(len));
|
||||
if (len != sizeof(struct ClearToken))
|
||||
break;
|
||||
p += sizeof(len);
|
||||
memcpy(&ct, p, len);
|
||||
p += len;
|
||||
p += sizeof(len); /* primary flag */
|
||||
server_cell = p;
|
||||
|
||||
/* Flesh out our credentials. */
|
||||
strlcpy(creds.service, "afs", sizeof(creds.service));
|
||||
creds.instance[0] = '\0';
|
||||
strlcpy(creds.realm, server_cell, REALM_SZ);
|
||||
memcpy(creds.session, ct.HandShakeKey, DES_KEY_SZ);
|
||||
creds.issue_date = ct.BeginTimestamp;
|
||||
creds.lifetime = krb_time_to_life(creds.issue_date,
|
||||
ct.EndTimestamp);
|
||||
creds.kvno = ct.AuthHandle;
|
||||
snprintf(creds.pname, sizeof(creds.pname), "AFS ID %d", ct.ViceId);
|
||||
creds.pinst[0] = '\0';
|
||||
|
||||
/* Encode token, ship it off. */
|
||||
if (creds_to_radix(&creds, (u_char *)buffer,
|
||||
sizeof(buffer)) <= 0)
|
||||
break;
|
||||
packet_start(SSH_CMSG_HAVE_AFS_TOKEN);
|
||||
packet_put_cstring(buffer);
|
||||
packet_send();
|
||||
packet_write_wait();
|
||||
|
||||
/* Roger, Roger. Clearance, Clarence. What's your vector,
|
||||
Victor? */
|
||||
type = packet_read();
|
||||
|
||||
if (type == SSH_SMSG_FAILURE)
|
||||
debug("AFS token for cell %s rejected.", server_cell);
|
||||
else if (type != SSH_SMSG_SUCCESS)
|
||||
packet_disconnect("Protocol error on AFS token response: %d", type);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* AFS */
|
||||
|
||||
/*
|
||||
* Tries to authenticate with any string-based challenge/response system.
|
||||
* Note that the client code is not tied to s/key or TIS.
|
||||
@ -890,7 +404,7 @@ try_challenge_response_authentication(void)
|
||||
if (i != 0)
|
||||
error("Permission denied, please try again.");
|
||||
if (options.cipher == SSH_CIPHER_NONE)
|
||||
log("WARNING: Encryption is disabled! "
|
||||
logit("WARNING: Encryption is disabled! "
|
||||
"Response will be transmitted in clear text.");
|
||||
response = read_passphrase(prompt, 0);
|
||||
if (strcmp(response, "") == 0) {
|
||||
@ -925,7 +439,7 @@ try_password_authentication(char *prompt)
|
||||
|
||||
debug("Doing password authentication.");
|
||||
if (options.cipher == SSH_CIPHER_NONE)
|
||||
log("WARNING: Encryption is disabled! Password will be transmitted in clear text.");
|
||||
logit("WARNING: Encryption is disabled! Password will be transmitted in clear text.");
|
||||
for (i = 0; i < options.number_of_password_prompts; i++) {
|
||||
if (i != 0)
|
||||
error("Permission denied, please try again.");
|
||||
@ -981,9 +495,9 @@ ssh_kex(char *host, struct sockaddr *hostaddr)
|
||||
|
||||
rbits = BN_num_bits(server_key->rsa->n);
|
||||
if (bits != rbits) {
|
||||
log("Warning: Server lies about size of server public key: "
|
||||
logit("Warning: Server lies about size of server public key: "
|
||||
"actual size is %d bits vs. announced %d.", rbits, bits);
|
||||
log("Warning: This may be due to an old implementation of ssh.");
|
||||
logit("Warning: This may be due to an old implementation of ssh.");
|
||||
}
|
||||
/* Get the host key. */
|
||||
host_key = key_new(KEY_RSA1);
|
||||
@ -993,9 +507,9 @@ ssh_kex(char *host, struct sockaddr *hostaddr)
|
||||
|
||||
rbits = BN_num_bits(host_key->rsa->n);
|
||||
if (bits != rbits) {
|
||||
log("Warning: Server lies about size of server host key: "
|
||||
logit("Warning: Server lies about size of server host key: "
|
||||
"actual size is %d bits vs. announced %d.", rbits, bits);
|
||||
log("Warning: This may be due to an old implementation of ssh.");
|
||||
logit("Warning: This may be due to an old implementation of ssh.");
|
||||
}
|
||||
|
||||
/* Get protocol flags. */
|
||||
@ -1086,7 +600,7 @@ ssh_kex(char *host, struct sockaddr *hostaddr)
|
||||
options.cipher = ssh_cipher_default;
|
||||
} else if (options.cipher == SSH_CIPHER_ILLEGAL ||
|
||||
!(cipher_mask_ssh1(1) & (1 << options.cipher))) {
|
||||
log("No valid SSH1 cipher, using %.100s instead.",
|
||||
logit("No valid SSH1 cipher, using %.100s instead.",
|
||||
cipher_name(ssh_cipher_default));
|
||||
options.cipher = ssh_cipher_default;
|
||||
}
|
||||
@ -1140,10 +654,6 @@ void
|
||||
ssh_userauth1(const char *local_user, const char *server_user, char *host,
|
||||
Sensitive *sensitive)
|
||||
{
|
||||
#ifdef KRB5
|
||||
krb5_context context = NULL;
|
||||
krb5_auth_context auth_context = NULL;
|
||||
#endif
|
||||
int i, type;
|
||||
|
||||
if (supported_authentications == 0)
|
||||
@ -1168,56 +678,6 @@ ssh_userauth1(const char *local_user, const char *server_user, char *host,
|
||||
if (type != SSH_SMSG_FAILURE)
|
||||
packet_disconnect("Protocol error: got %d in response to SSH_CMSG_USER", type);
|
||||
|
||||
#ifdef KRB5
|
||||
if ((supported_authentications & (1 << SSH_AUTH_KERBEROS)) &&
|
||||
options.kerberos_authentication) {
|
||||
debug("Trying Kerberos v5 authentication.");
|
||||
|
||||
if (try_krb5_authentication(&context, &auth_context)) {
|
||||
type = packet_read();
|
||||
if (type == SSH_SMSG_SUCCESS)
|
||||
goto success;
|
||||
if (type != SSH_SMSG_FAILURE)
|
||||
packet_disconnect("Protocol error: got %d in response to Kerberos v5 auth", type);
|
||||
}
|
||||
}
|
||||
#endif /* KRB5 */
|
||||
|
||||
#ifdef KRB4
|
||||
if ((supported_authentications & (1 << SSH_AUTH_KERBEROS)) &&
|
||||
options.kerberos_authentication) {
|
||||
debug("Trying Kerberos v4 authentication.");
|
||||
|
||||
if (try_krb4_authentication()) {
|
||||
type = packet_read();
|
||||
if (type == SSH_SMSG_SUCCESS)
|
||||
goto success;
|
||||
if (type != SSH_SMSG_FAILURE)
|
||||
packet_disconnect("Protocol error: got %d in response to Kerberos v4 auth", type);
|
||||
}
|
||||
}
|
||||
#endif /* KRB4 */
|
||||
|
||||
/*
|
||||
* Use rhosts authentication if running in privileged socket and we
|
||||
* do not wish to remain anonymous.
|
||||
*/
|
||||
if ((supported_authentications & (1 << SSH_AUTH_RHOSTS)) &&
|
||||
options.rhosts_authentication) {
|
||||
debug("Trying rhosts authentication.");
|
||||
packet_start(SSH_CMSG_AUTH_RHOSTS);
|
||||
packet_put_cstring(local_user);
|
||||
packet_send();
|
||||
packet_write_wait();
|
||||
|
||||
/* The server should respond with success or failure. */
|
||||
type = packet_read();
|
||||
if (type == SSH_SMSG_SUCCESS)
|
||||
goto success;
|
||||
if (type != SSH_SMSG_FAILURE)
|
||||
packet_disconnect("Protocol error: got %d in response to rhosts auth",
|
||||
type);
|
||||
}
|
||||
/*
|
||||
* Try .rhosts or /etc/hosts.equiv authentication with RSA host
|
||||
* authentication.
|
||||
@ -1271,36 +731,5 @@ ssh_userauth1(const char *local_user, const char *server_user, char *host,
|
||||
/* NOTREACHED */
|
||||
|
||||
success:
|
||||
#ifdef KRB5
|
||||
/* Try Kerberos v5 TGT passing. */
|
||||
if ((supported_authentications & (1 << SSH_PASS_KERBEROS_TGT)) &&
|
||||
options.kerberos_tgt_passing && context && auth_context) {
|
||||
if (options.cipher == SSH_CIPHER_NONE)
|
||||
log("WARNING: Encryption is disabled! Ticket will be transmitted in the clear!");
|
||||
send_krb5_tgt(context, auth_context);
|
||||
}
|
||||
if (auth_context)
|
||||
krb5_auth_con_free(context, auth_context);
|
||||
if (context)
|
||||
krb5_free_context(context);
|
||||
#endif
|
||||
|
||||
#ifdef AFS
|
||||
/* Try Kerberos v4 TGT passing if the server supports it. */
|
||||
if ((supported_authentications & (1 << SSH_PASS_KERBEROS_TGT)) &&
|
||||
options.kerberos_tgt_passing) {
|
||||
if (options.cipher == SSH_CIPHER_NONE)
|
||||
log("WARNING: Encryption is disabled! Ticket will be transmitted in the clear!");
|
||||
send_krb4_tgt();
|
||||
}
|
||||
/* Try AFS token passing if the server supports it. */
|
||||
if ((supported_authentications & (1 << SSH_PASS_AFS_TOKEN)) &&
|
||||
options.afs_token_passing && k_hasafs()) {
|
||||
if (options.cipher == SSH_CIPHER_NONE)
|
||||
log("WARNING: Encryption is disabled! Token will be transmitted in the clear!");
|
||||
send_afs_tokens();
|
||||
}
|
||||
#endif /* AFS */
|
||||
|
||||
return; /* need statement after label */
|
||||
}
|
||||
|
@ -23,7 +23,9 @@
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: sshconnect2.c,v 1.114 2003/04/01 10:22:21 markus Exp $");
|
||||
RCSID("$OpenBSD: sshconnect2.c,v 1.124 2003/08/25 10:33:33 djm Exp $");
|
||||
|
||||
#include "openbsd-compat/sys-queue.h"
|
||||
|
||||
#include "ssh.h"
|
||||
#include "ssh2.h"
|
||||
@ -48,6 +50,10 @@ RCSID("$OpenBSD: sshconnect2.c,v 1.114 2003/04/01 10:22:21 markus Exp $");
|
||||
#include "msg.h"
|
||||
#include "pathnames.h"
|
||||
|
||||
#ifdef GSSAPI
|
||||
#include "ssh-gss.h"
|
||||
#endif
|
||||
|
||||
/* import */
|
||||
extern char *client_version_string;
|
||||
extern char *server_version_string;
|
||||
@ -58,7 +64,7 @@ extern Options options;
|
||||
*/
|
||||
|
||||
u_char *session_id2 = NULL;
|
||||
int session_id2_len = 0;
|
||||
u_int session_id2_len = 0;
|
||||
|
||||
char *xxx_host;
|
||||
struct sockaddr *xxx_hostaddr;
|
||||
@ -82,7 +88,7 @@ ssh_kex2(char *host, struct sockaddr *hostaddr)
|
||||
xxx_hostaddr = hostaddr;
|
||||
|
||||
if (options.ciphers == (char *)-1) {
|
||||
log("No valid ciphers for protocol version 2 given, using defaults.");
|
||||
logit("No valid ciphers for protocol version 2 given, using defaults.");
|
||||
options.ciphers = NULL;
|
||||
}
|
||||
if (options.ciphers != NULL) {
|
||||
@ -108,6 +114,9 @@ ssh_kex2(char *host, struct sockaddr *hostaddr)
|
||||
myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] =
|
||||
options.hostkeyalgorithms;
|
||||
|
||||
if (options.rekey_limit)
|
||||
packet_set_rekey_limit(options.rekey_limit);
|
||||
|
||||
/* start key exchange */
|
||||
kex = kex_setup(myproposal);
|
||||
kex->kex[KEX_DH_GRP1_SHA1] = kexdh_client;
|
||||
@ -138,10 +147,18 @@ ssh_kex2(char *host, struct sockaddr *hostaddr)
|
||||
|
||||
typedef struct Authctxt Authctxt;
|
||||
typedef struct Authmethod Authmethod;
|
||||
typedef struct identity Identity;
|
||||
typedef struct idlist Idlist;
|
||||
|
||||
typedef int sign_cb_fn(
|
||||
Authctxt *authctxt, Key *key,
|
||||
u_char **sigp, u_int *lenp, u_char *data, u_int datalen);
|
||||
struct identity {
|
||||
TAILQ_ENTRY(identity) next;
|
||||
AuthenticationConnection *ac; /* set if agent supports key */
|
||||
Key *key; /* public/private key */
|
||||
char *filename; /* comment for agent-only keys */
|
||||
int tried;
|
||||
int isprivate; /* key points to the private key */
|
||||
};
|
||||
TAILQ_HEAD(idlist, identity);
|
||||
|
||||
struct Authctxt {
|
||||
const char *server_user;
|
||||
@ -152,14 +169,14 @@ struct Authctxt {
|
||||
int success;
|
||||
char *authlist;
|
||||
/* pubkey */
|
||||
Key *last_key;
|
||||
sign_cb_fn *last_key_sign;
|
||||
int last_key_hint;
|
||||
Idlist keys;
|
||||
AuthenticationConnection *agent;
|
||||
/* hostbased */
|
||||
Sensitive *sensitive;
|
||||
/* kbd-interactive */
|
||||
int info_req_seen;
|
||||
/* generic */
|
||||
void *methoddata;
|
||||
};
|
||||
struct Authmethod {
|
||||
char *name; /* string to compare against server's list */
|
||||
@ -181,17 +198,35 @@ int userauth_pubkey(Authctxt *);
|
||||
int userauth_passwd(Authctxt *);
|
||||
int userauth_kbdint(Authctxt *);
|
||||
int userauth_hostbased(Authctxt *);
|
||||
int userauth_kerberos(Authctxt *);
|
||||
|
||||
#ifdef GSSAPI
|
||||
int userauth_gssapi(Authctxt *authctxt);
|
||||
void input_gssapi_response(int type, u_int32_t, void *);
|
||||
void input_gssapi_token(int type, u_int32_t, void *);
|
||||
void input_gssapi_hash(int type, u_int32_t, void *);
|
||||
void input_gssapi_error(int, u_int32_t, void *);
|
||||
void input_gssapi_errtok(int, u_int32_t, void *);
|
||||
#endif
|
||||
|
||||
void userauth(Authctxt *, char *);
|
||||
|
||||
static int sign_and_send_pubkey(Authctxt *, Key *, sign_cb_fn *);
|
||||
static void clear_auth_state(Authctxt *);
|
||||
static int sign_and_send_pubkey(Authctxt *, Identity *);
|
||||
static void pubkey_prepare(Authctxt *);
|
||||
static void pubkey_cleanup(Authctxt *);
|
||||
static Key *load_identity_file(char *);
|
||||
|
||||
static Authmethod *authmethod_get(char *authlist);
|
||||
static Authmethod *authmethod_lookup(const char *name);
|
||||
static char *authmethods_get(void);
|
||||
|
||||
Authmethod authmethods[] = {
|
||||
#ifdef GSSAPI
|
||||
{"gssapi",
|
||||
userauth_gssapi,
|
||||
&options.gss_authentication,
|
||||
NULL},
|
||||
#endif
|
||||
{"hostbased",
|
||||
userauth_hostbased,
|
||||
&options.hostbased_authentication,
|
||||
@ -248,7 +283,7 @@ ssh_userauth2(const char *local_user, const char *server_user, char *host,
|
||||
|
||||
/* setup authentication context */
|
||||
memset(&authctxt, 0, sizeof(authctxt));
|
||||
authctxt.agent = ssh_get_authentication_connection();
|
||||
pubkey_prepare(&authctxt);
|
||||
authctxt.server_user = server_user;
|
||||
authctxt.local_user = local_user;
|
||||
authctxt.host = host;
|
||||
@ -256,6 +291,7 @@ ssh_userauth2(const char *local_user, const char *server_user, char *host,
|
||||
authctxt.success = 0;
|
||||
authctxt.method = authmethod_lookup("none");
|
||||
authctxt.authlist = NULL;
|
||||
authctxt.methoddata = NULL;
|
||||
authctxt.sensitive = sensitive;
|
||||
authctxt.info_req_seen = 0;
|
||||
if (authctxt.method == NULL)
|
||||
@ -270,14 +306,19 @@ ssh_userauth2(const char *local_user, const char *server_user, char *host,
|
||||
dispatch_set(SSH2_MSG_USERAUTH_BANNER, &input_userauth_banner);
|
||||
dispatch_run(DISPATCH_BLOCK, &authctxt.success, &authctxt); /* loop until success */
|
||||
|
||||
if (authctxt.agent != NULL)
|
||||
ssh_close_authentication_connection(authctxt.agent);
|
||||
pubkey_cleanup(&authctxt);
|
||||
dispatch_range(SSH2_MSG_USERAUTH_MIN, SSH2_MSG_USERAUTH_MAX, NULL);
|
||||
|
||||
debug("Authentication succeeded (%s).", authctxt.method->name);
|
||||
}
|
||||
|
||||
void
|
||||
userauth(Authctxt *authctxt, char *authlist)
|
||||
{
|
||||
if (authctxt->methoddata) {
|
||||
xfree(authctxt->methoddata);
|
||||
authctxt->methoddata = NULL;
|
||||
}
|
||||
if (authlist == NULL) {
|
||||
authlist = authctxt->authlist;
|
||||
} else {
|
||||
@ -290,6 +331,12 @@ userauth(Authctxt *authctxt, char *authlist)
|
||||
if (method == NULL)
|
||||
fatal("Permission denied (%s).", authlist);
|
||||
authctxt->method = method;
|
||||
|
||||
/* reset the per method handler */
|
||||
dispatch_range(SSH2_MSG_USERAUTH_PER_METHOD_MIN,
|
||||
SSH2_MSG_USERAUTH_PER_METHOD_MAX, NULL);
|
||||
|
||||
/* and try new method */
|
||||
if (method->userauth(authctxt) != 0) {
|
||||
debug2("we sent a %s packet, wait for reply", method->name);
|
||||
break;
|
||||
@ -314,7 +361,7 @@ input_userauth_banner(int type, u_int32_t seq, void *ctxt)
|
||||
debug3("input_userauth_banner");
|
||||
msg = packet_get_string(NULL);
|
||||
lang = packet_get_string(NULL);
|
||||
fprintf(stderr, "%s", msg);
|
||||
logit("%s", msg);
|
||||
xfree(msg);
|
||||
xfree(lang);
|
||||
}
|
||||
@ -327,7 +374,8 @@ input_userauth_success(int type, u_int32_t seq, void *ctxt)
|
||||
fatal("input_userauth_success: no authentication context");
|
||||
if (authctxt->authlist)
|
||||
xfree(authctxt->authlist);
|
||||
clear_auth_state(authctxt);
|
||||
if (authctxt->methoddata)
|
||||
xfree(authctxt->methoddata);
|
||||
authctxt->success = 1; /* break out */
|
||||
}
|
||||
|
||||
@ -346,10 +394,9 @@ input_userauth_failure(int type, u_int32_t seq, void *ctxt)
|
||||
packet_check_eom();
|
||||
|
||||
if (partial != 0)
|
||||
log("Authenticated with partial success.");
|
||||
logit("Authenticated with partial success.");
|
||||
debug("Authentications that can continue: %s", authlist);
|
||||
|
||||
clear_auth_state(authctxt);
|
||||
userauth(authctxt, authlist);
|
||||
}
|
||||
void
|
||||
@ -357,6 +404,7 @@ input_userauth_pk_ok(int type, u_int32_t seq, void *ctxt)
|
||||
{
|
||||
Authctxt *authctxt = ctxt;
|
||||
Key *key = NULL;
|
||||
Identity *id = NULL;
|
||||
Buffer b;
|
||||
int pktype, sent = 0;
|
||||
u_int alen, blen;
|
||||
@ -379,55 +427,267 @@ input_userauth_pk_ok(int type, u_int32_t seq, void *ctxt)
|
||||
}
|
||||
packet_check_eom();
|
||||
|
||||
debug("Server accepts key: pkalg %s blen %u lastkey %p hint %d",
|
||||
pkalg, blen, authctxt->last_key, authctxt->last_key_hint);
|
||||
debug("Server accepts key: pkalg %s blen %u", pkalg, blen);
|
||||
|
||||
do {
|
||||
if (authctxt->last_key == NULL ||
|
||||
authctxt->last_key_sign == NULL) {
|
||||
debug("no last key or no sign cb");
|
||||
break;
|
||||
}
|
||||
if ((pktype = key_type_from_name(pkalg)) == KEY_UNSPEC) {
|
||||
debug("unknown pkalg %s", pkalg);
|
||||
break;
|
||||
}
|
||||
if ((key = key_from_blob(pkblob, blen)) == NULL) {
|
||||
debug("no key from blob. pkalg %s", pkalg);
|
||||
break;
|
||||
}
|
||||
if (key->type != pktype) {
|
||||
error("input_userauth_pk_ok: type mismatch "
|
||||
"for decoded key (received %d, expected %d)",
|
||||
key->type, pktype);
|
||||
break;
|
||||
}
|
||||
fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
|
||||
debug2("input_userauth_pk_ok: fp %s", fp);
|
||||
xfree(fp);
|
||||
if (!key_equal(key, authctxt->last_key)) {
|
||||
debug("key != last_key");
|
||||
break;
|
||||
}
|
||||
sent = sign_and_send_pubkey(authctxt, key,
|
||||
authctxt->last_key_sign);
|
||||
} while (0);
|
||||
if ((pktype = key_type_from_name(pkalg)) == KEY_UNSPEC) {
|
||||
debug("unknown pkalg %s", pkalg);
|
||||
goto done;
|
||||
}
|
||||
if ((key = key_from_blob(pkblob, blen)) == NULL) {
|
||||
debug("no key from blob. pkalg %s", pkalg);
|
||||
goto done;
|
||||
}
|
||||
if (key->type != pktype) {
|
||||
error("input_userauth_pk_ok: type mismatch "
|
||||
"for decoded key (received %d, expected %d)",
|
||||
key->type, pktype);
|
||||
goto done;
|
||||
}
|
||||
fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
|
||||
debug2("input_userauth_pk_ok: fp %s", fp);
|
||||
xfree(fp);
|
||||
|
||||
TAILQ_FOREACH(id, &authctxt->keys, next) {
|
||||
if (key_equal(key, id->key)) {
|
||||
sent = sign_and_send_pubkey(authctxt, id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
done:
|
||||
if (key != NULL)
|
||||
key_free(key);
|
||||
xfree(pkalg);
|
||||
xfree(pkblob);
|
||||
|
||||
/* unregister */
|
||||
clear_auth_state(authctxt);
|
||||
dispatch_set(SSH2_MSG_USERAUTH_PK_OK, NULL);
|
||||
|
||||
/* try another method if we did not send a packet */
|
||||
if (sent == 0)
|
||||
userauth(authctxt, NULL);
|
||||
|
||||
}
|
||||
|
||||
#ifdef GSSAPI
|
||||
int
|
||||
userauth_gssapi(Authctxt *authctxt)
|
||||
{
|
||||
Gssctxt *gssctxt = NULL;
|
||||
static gss_OID_set supported = NULL;
|
||||
static int mech = 0;
|
||||
OM_uint32 min;
|
||||
int ok = 0;
|
||||
|
||||
/* Try one GSSAPI method at a time, rather than sending them all at
|
||||
* once. */
|
||||
|
||||
if (supported == NULL)
|
||||
gss_indicate_mechs(&min, &supported);
|
||||
|
||||
/* Check to see if the mechanism is usable before we offer it */
|
||||
while (mech<supported->count && !ok) {
|
||||
if (gssctxt)
|
||||
ssh_gssapi_delete_ctx(&gssctxt);
|
||||
ssh_gssapi_build_ctx(&gssctxt);
|
||||
ssh_gssapi_set_oid(gssctxt, &supported->elements[mech]);
|
||||
|
||||
/* My DER encoding requires length<128 */
|
||||
if (supported->elements[mech].length < 128 &&
|
||||
!GSS_ERROR(ssh_gssapi_import_name(gssctxt,
|
||||
authctxt->host))) {
|
||||
ok = 1; /* Mechanism works */
|
||||
} else {
|
||||
mech++;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ok) return 0;
|
||||
|
||||
authctxt->methoddata=(void *)gssctxt;
|
||||
|
||||
packet_start(SSH2_MSG_USERAUTH_REQUEST);
|
||||
packet_put_cstring(authctxt->server_user);
|
||||
packet_put_cstring(authctxt->service);
|
||||
packet_put_cstring(authctxt->method->name);
|
||||
|
||||
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_send();
|
||||
|
||||
dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_RESPONSE, &input_gssapi_response);
|
||||
dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, &input_gssapi_token);
|
||||
dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERROR, &input_gssapi_error);
|
||||
dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, &input_gssapi_errtok);
|
||||
|
||||
mech++; /* Move along to next candidate */
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
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");
|
||||
gssctxt = authctxt->methoddata;
|
||||
|
||||
/* 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");
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
/* 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;
|
||||
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);
|
||||
|
||||
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
|
||||
input_gssapi_errtok(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;
|
||||
u_int len;
|
||||
|
||||
if (authctxt == NULL)
|
||||
fatal("input_gssapi_response: no authentication context");
|
||||
gssctxt = authctxt->methoddata;
|
||||
|
||||
recv_tok.value = packet_get_string(&len);
|
||||
recv_tok.length = len;
|
||||
|
||||
packet_check_eom();
|
||||
|
||||
/* Stick it into GSSAPI and see what it says */
|
||||
status = ssh_gssapi_init_ctx(gssctxt, options.gss_deleg_creds,
|
||||
&recv_tok, &send_tok, NULL);
|
||||
|
||||
xfree(recv_tok.value);
|
||||
gss_release_buffer(&ms, &send_tok);
|
||||
|
||||
/* Server will be returning a failed packet after this one */
|
||||
}
|
||||
|
||||
void
|
||||
input_gssapi_error(int type, u_int32_t plen, void *ctxt)
|
||||
{
|
||||
OM_uint32 maj, min;
|
||||
char *msg;
|
||||
char *lang;
|
||||
|
||||
maj=packet_get_int();
|
||||
min=packet_get_int();
|
||||
msg=packet_get_string(NULL);
|
||||
lang=packet_get_string(NULL);
|
||||
|
||||
packet_check_eom();
|
||||
|
||||
debug("Server GSSAPI Error:\n%s\n", msg);
|
||||
xfree(msg);
|
||||
xfree(lang);
|
||||
}
|
||||
#endif /* GSSAPI */
|
||||
|
||||
int
|
||||
userauth_none(Authctxt *authctxt)
|
||||
{
|
||||
@ -491,7 +751,7 @@ input_userauth_passwd_changereq(int type, u_int32_t seqnr, void *ctxt)
|
||||
info = packet_get_string(NULL);
|
||||
lang = packet_get_string(NULL);
|
||||
if (strlen(info) > 0)
|
||||
log("%s", info);
|
||||
logit("%s", info);
|
||||
xfree(info);
|
||||
xfree(lang);
|
||||
packet_start(SSH2_MSG_USERAUTH_REQUEST);
|
||||
@ -523,7 +783,7 @@ input_userauth_passwd_changereq(int type, u_int32_t seqnr, void *ctxt)
|
||||
if (strcmp(password, retype) != 0) {
|
||||
memset(password, 0, strlen(password));
|
||||
xfree(password);
|
||||
log("Mismatch; try again, EOF to quit.");
|
||||
logit("Mismatch; try again, EOF to quit.");
|
||||
password = NULL;
|
||||
}
|
||||
memset(retype, 0, strlen(retype));
|
||||
@ -539,34 +799,44 @@ input_userauth_passwd_changereq(int type, u_int32_t seqnr, void *ctxt)
|
||||
&input_userauth_passwd_changereq);
|
||||
}
|
||||
|
||||
static void
|
||||
clear_auth_state(Authctxt *authctxt)
|
||||
static int
|
||||
identity_sign(Identity *id, u_char **sigp, u_int *lenp,
|
||||
u_char *data, u_int datalen)
|
||||
{
|
||||
/* XXX clear authentication state */
|
||||
dispatch_set(SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ, NULL);
|
||||
Key *prv;
|
||||
int ret;
|
||||
|
||||
if (authctxt->last_key != NULL && authctxt->last_key_hint == -1) {
|
||||
debug3("clear_auth_state: key_free %p", authctxt->last_key);
|
||||
key_free(authctxt->last_key);
|
||||
}
|
||||
authctxt->last_key = NULL;
|
||||
authctxt->last_key_hint = -2;
|
||||
authctxt->last_key_sign = NULL;
|
||||
/* the agent supports this key */
|
||||
if (id->ac)
|
||||
return (ssh_agent_sign(id->ac, id->key, sigp, lenp,
|
||||
data, datalen));
|
||||
/*
|
||||
* we have already loaded the private key or
|
||||
* the private key is stored in external hardware
|
||||
*/
|
||||
if (id->isprivate || (id->key->flags & KEY_FLAG_EXT))
|
||||
return (key_sign(id->key, sigp, lenp, data, datalen));
|
||||
/* load the private key from the file */
|
||||
if ((prv = load_identity_file(id->filename)) == NULL)
|
||||
return (-1);
|
||||
ret = key_sign(prv, sigp, lenp, data, datalen);
|
||||
key_free(prv);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static int
|
||||
sign_and_send_pubkey(Authctxt *authctxt, Key *k, sign_cb_fn *sign_callback)
|
||||
sign_and_send_pubkey(Authctxt *authctxt, Identity *id)
|
||||
{
|
||||
Buffer b;
|
||||
u_char *blob, *signature;
|
||||
u_int bloblen, slen;
|
||||
int skip = 0;
|
||||
u_int skip = 0;
|
||||
int ret = -1;
|
||||
int have_sig = 1;
|
||||
|
||||
debug3("sign_and_send_pubkey");
|
||||
|
||||
if (key_to_blob(k, &blob, &bloblen) == 0) {
|
||||
if (key_to_blob(id->key, &blob, &bloblen) == 0) {
|
||||
/* we cannot handle this key */
|
||||
debug3("sign_and_send_pubkey: cannot handle key");
|
||||
return 0;
|
||||
@ -591,12 +861,12 @@ sign_and_send_pubkey(Authctxt *authctxt, Key *k, sign_cb_fn *sign_callback)
|
||||
} else {
|
||||
buffer_put_cstring(&b, authctxt->method->name);
|
||||
buffer_put_char(&b, have_sig);
|
||||
buffer_put_cstring(&b, key_ssh_name(k));
|
||||
buffer_put_cstring(&b, key_ssh_name(id->key));
|
||||
}
|
||||
buffer_put_string(&b, blob, bloblen);
|
||||
|
||||
/* generate signature */
|
||||
ret = (*sign_callback)(authctxt, k, &signature, &slen,
|
||||
ret = identity_sign(id, &signature, &slen,
|
||||
buffer_ptr(&b), buffer_len(&b));
|
||||
if (ret == -1) {
|
||||
xfree(blob);
|
||||
@ -616,7 +886,7 @@ sign_and_send_pubkey(Authctxt *authctxt, Key *k, sign_cb_fn *sign_callback)
|
||||
buffer_put_cstring(&b, authctxt->method->name);
|
||||
buffer_put_char(&b, have_sig);
|
||||
if (!(datafellows & SSH_BUG_PKAUTH))
|
||||
buffer_put_cstring(&b, key_ssh_name(k));
|
||||
buffer_put_cstring(&b, key_ssh_name(id->key));
|
||||
buffer_put_string(&b, blob, bloblen);
|
||||
}
|
||||
xfree(blob);
|
||||
@ -640,23 +910,19 @@ sign_and_send_pubkey(Authctxt *authctxt, Key *k, sign_cb_fn *sign_callback)
|
||||
}
|
||||
|
||||
static int
|
||||
send_pubkey_test(Authctxt *authctxt, Key *k, sign_cb_fn *sign_callback,
|
||||
int hint)
|
||||
send_pubkey_test(Authctxt *authctxt, Identity *id)
|
||||
{
|
||||
u_char *blob;
|
||||
u_int bloblen, have_sig = 0;
|
||||
|
||||
debug3("send_pubkey_test");
|
||||
|
||||
if (key_to_blob(k, &blob, &bloblen) == 0) {
|
||||
if (key_to_blob(id->key, &blob, &bloblen) == 0) {
|
||||
/* we cannot handle this key */
|
||||
debug3("send_pubkey_test: cannot handle key");
|
||||
return 0;
|
||||
}
|
||||
/* register callback for USERAUTH_PK_OK message */
|
||||
authctxt->last_key_sign = sign_callback;
|
||||
authctxt->last_key_hint = hint;
|
||||
authctxt->last_key = k;
|
||||
dispatch_set(SSH2_MSG_USERAUTH_PK_OK, &input_userauth_pk_ok);
|
||||
|
||||
packet_start(SSH2_MSG_USERAUTH_REQUEST);
|
||||
@ -665,7 +931,7 @@ send_pubkey_test(Authctxt *authctxt, Key *k, sign_cb_fn *sign_callback,
|
||||
packet_put_cstring(authctxt->method->name);
|
||||
packet_put_char(have_sig);
|
||||
if (!(datafellows & SSH_BUG_PKAUTH))
|
||||
packet_put_cstring(key_ssh_name(k));
|
||||
packet_put_cstring(key_ssh_name(id->key));
|
||||
packet_put_string(blob, bloblen);
|
||||
xfree(blob);
|
||||
packet_send();
|
||||
@ -710,103 +976,134 @@ load_identity_file(char *filename)
|
||||
return private;
|
||||
}
|
||||
|
||||
static int
|
||||
identity_sign_cb(Authctxt *authctxt, Key *key, u_char **sigp, u_int *lenp,
|
||||
u_char *data, u_int datalen)
|
||||
/*
|
||||
* try keys in the following order:
|
||||
* 1. agent keys that are found in the config file
|
||||
* 2. other agent keys
|
||||
* 3. keys that are only listed in the config file
|
||||
*/
|
||||
static void
|
||||
pubkey_prepare(Authctxt *authctxt)
|
||||
{
|
||||
Key *private;
|
||||
int idx, ret;
|
||||
|
||||
idx = authctxt->last_key_hint;
|
||||
if (idx < 0)
|
||||
return -1;
|
||||
|
||||
/* private key is stored in external hardware */
|
||||
if (options.identity_keys[idx]->flags & KEY_FLAG_EXT)
|
||||
return key_sign(options.identity_keys[idx], sigp, lenp, data, datalen);
|
||||
|
||||
private = load_identity_file(options.identity_files[idx]);
|
||||
if (private == NULL)
|
||||
return -1;
|
||||
ret = key_sign(private, sigp, lenp, data, datalen);
|
||||
key_free(private);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
agent_sign_cb(Authctxt *authctxt, Key *key, u_char **sigp, u_int *lenp,
|
||||
u_char *data, u_int datalen)
|
||||
{
|
||||
return ssh_agent_sign(authctxt->agent, key, sigp, lenp, data, datalen);
|
||||
}
|
||||
|
||||
static int
|
||||
key_sign_cb(Authctxt *authctxt, Key *key, u_char **sigp, u_int *lenp,
|
||||
u_char *data, u_int datalen)
|
||||
{
|
||||
return key_sign(key, sigp, lenp, data, datalen);
|
||||
}
|
||||
|
||||
static int
|
||||
userauth_pubkey_agent(Authctxt *authctxt)
|
||||
{
|
||||
static int called = 0;
|
||||
int ret = 0;
|
||||
Identity *id;
|
||||
Idlist agent, files, *preferred;
|
||||
Key *key;
|
||||
AuthenticationConnection *ac;
|
||||
char *comment;
|
||||
Key *k;
|
||||
int i, found;
|
||||
|
||||
if (called == 0) {
|
||||
if (ssh_get_num_identities(authctxt->agent, 2) == 0)
|
||||
debug2("userauth_pubkey_agent: no keys at all");
|
||||
called = 1;
|
||||
TAILQ_INIT(&agent); /* keys from the agent */
|
||||
TAILQ_INIT(&files); /* keys from the config file */
|
||||
preferred = &authctxt->keys;
|
||||
TAILQ_INIT(preferred); /* preferred order of keys */
|
||||
|
||||
/* list of keys stored in the filesystem */
|
||||
for (i = 0; i < options.num_identity_files; i++) {
|
||||
key = options.identity_keys[i];
|
||||
if (key && key->type == KEY_RSA1)
|
||||
continue;
|
||||
options.identity_keys[i] = NULL;
|
||||
id = xmalloc(sizeof(*id));
|
||||
memset(id, 0, sizeof(*id));
|
||||
id->key = key;
|
||||
id->filename = xstrdup(options.identity_files[i]);
|
||||
TAILQ_INSERT_TAIL(&files, id, next);
|
||||
}
|
||||
k = ssh_get_next_identity(authctxt->agent, &comment, 2);
|
||||
if (k == NULL) {
|
||||
debug2("userauth_pubkey_agent: no more keys");
|
||||
} else {
|
||||
debug("Offering agent key: %s", comment);
|
||||
xfree(comment);
|
||||
ret = send_pubkey_test(authctxt, k, agent_sign_cb, -1);
|
||||
if (ret == 0)
|
||||
key_free(k);
|
||||
/* list of keys supported by the agent */
|
||||
if ((ac = ssh_get_authentication_connection())) {
|
||||
for (key = ssh_get_first_identity(ac, &comment, 2);
|
||||
key != NULL;
|
||||
key = ssh_get_next_identity(ac, &comment, 2)) {
|
||||
found = 0;
|
||||
TAILQ_FOREACH(id, &files, next) {
|
||||
/* agent keys from the config file are preferred */
|
||||
if (key_equal(key, id->key)) {
|
||||
key_free(key);
|
||||
xfree(comment);
|
||||
TAILQ_REMOVE(&files, id, next);
|
||||
TAILQ_INSERT_TAIL(preferred, id, next);
|
||||
id->ac = ac;
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
id = xmalloc(sizeof(*id));
|
||||
memset(id, 0, sizeof(*id));
|
||||
id->key = key;
|
||||
id->filename = comment;
|
||||
id->ac = ac;
|
||||
TAILQ_INSERT_TAIL(&agent, id, next);
|
||||
}
|
||||
}
|
||||
/* append remaining agent keys */
|
||||
for (id = TAILQ_FIRST(&agent); id; id = TAILQ_FIRST(&agent)) {
|
||||
TAILQ_REMOVE(&agent, id, next);
|
||||
TAILQ_INSERT_TAIL(preferred, id, next);
|
||||
}
|
||||
authctxt->agent = ac;
|
||||
}
|
||||
/* append remaining keys from the config file */
|
||||
for (id = TAILQ_FIRST(&files); id; id = TAILQ_FIRST(&files)) {
|
||||
TAILQ_REMOVE(&files, id, next);
|
||||
TAILQ_INSERT_TAIL(preferred, id, next);
|
||||
}
|
||||
TAILQ_FOREACH(id, preferred, next) {
|
||||
debug2("key: %s (%p)", id->filename, id->key);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
pubkey_cleanup(Authctxt *authctxt)
|
||||
{
|
||||
Identity *id;
|
||||
|
||||
if (authctxt->agent != NULL)
|
||||
ssh_close_authentication_connection(authctxt->agent);
|
||||
for (id = TAILQ_FIRST(&authctxt->keys); id;
|
||||
id = TAILQ_FIRST(&authctxt->keys)) {
|
||||
TAILQ_REMOVE(&authctxt->keys, id, next);
|
||||
if (id->key)
|
||||
key_free(id->key);
|
||||
if (id->filename)
|
||||
xfree(id->filename);
|
||||
xfree(id);
|
||||
}
|
||||
if (ret == 0)
|
||||
debug2("userauth_pubkey_agent: no message sent");
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
userauth_pubkey(Authctxt *authctxt)
|
||||
{
|
||||
static int idx = 0;
|
||||
Identity *id;
|
||||
int sent = 0;
|
||||
Key *key;
|
||||
char *filename;
|
||||
|
||||
if (authctxt->agent != NULL) {
|
||||
do {
|
||||
sent = userauth_pubkey_agent(authctxt);
|
||||
} while (!sent && authctxt->agent->howmany > 0);
|
||||
}
|
||||
while (!sent && idx < options.num_identity_files) {
|
||||
key = options.identity_keys[idx];
|
||||
filename = options.identity_files[idx];
|
||||
if (key == NULL) {
|
||||
debug("Trying private key: %s", filename);
|
||||
key = load_identity_file(filename);
|
||||
if (key != NULL) {
|
||||
sent = sign_and_send_pubkey(authctxt, key,
|
||||
key_sign_cb);
|
||||
key_free(key);
|
||||
while ((id = TAILQ_FIRST(&authctxt->keys))) {
|
||||
if (id->tried++)
|
||||
return (0);
|
||||
TAILQ_REMOVE(&authctxt->keys, id, next);
|
||||
TAILQ_INSERT_TAIL(&authctxt->keys, id, next);
|
||||
/*
|
||||
* send a test message if we have the public key. for
|
||||
* encrypted keys we cannot do this and have to load the
|
||||
* private key instead
|
||||
*/
|
||||
if (id->key && id->key->type != KEY_RSA1) {
|
||||
debug("Offering public key: %s", id->filename);
|
||||
sent = send_pubkey_test(authctxt, id);
|
||||
} else if (id->key == NULL) {
|
||||
debug("Trying private key: %s", id->filename);
|
||||
id->key = load_identity_file(id->filename);
|
||||
if (id->key != NULL) {
|
||||
id->isprivate = 1;
|
||||
sent = sign_and_send_pubkey(authctxt, id);
|
||||
key_free(id->key);
|
||||
id->key = NULL;
|
||||
}
|
||||
} else if (key->type != KEY_RSA1) {
|
||||
debug("Offering public key: %s", filename);
|
||||
sent = send_pubkey_test(authctxt, key,
|
||||
identity_sign_cb, idx);
|
||||
}
|
||||
idx++;
|
||||
if (sent)
|
||||
return (sent);
|
||||
}
|
||||
return sent;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -862,9 +1159,9 @@ input_userauth_info_req(int type, u_int32_t seq, void *ctxt)
|
||||
inst = packet_get_string(NULL);
|
||||
lang = packet_get_string(NULL);
|
||||
if (strlen(name) > 0)
|
||||
log("%s", name);
|
||||
logit("%s", name);
|
||||
if (strlen(inst) > 0)
|
||||
log("%s", inst);
|
||||
logit("%s", inst);
|
||||
xfree(name);
|
||||
xfree(inst);
|
||||
xfree(lang);
|
||||
|
@ -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.194 2003/01/31 21:54:40 jmc Exp $
|
||||
.\" $OpenBSD: sshd.8,v 1.199 2003/08/13 08:46:31 markus Exp $
|
||||
.\" $FreeBSD$
|
||||
.Dd September 25, 1999
|
||||
.Dt SSHD 8
|
||||
@ -115,6 +115,29 @@ authentication combined with RSA host
|
||||
authentication, RSA challenge-response authentication, or password
|
||||
based authentication.
|
||||
.Pp
|
||||
Regardless of the authentication type, the account is checked to
|
||||
ensure that it is accessible. An account is not accessible if it is
|
||||
locked, listed in
|
||||
.Cm DenyUsers
|
||||
or its group is listed in
|
||||
.Cm DenyGroups
|
||||
\&. The definition of a locked account is system dependant. Some platforms
|
||||
have their own account database (eg AIX) and some modify the passwd field (
|
||||
.Ql \&*LK\&*
|
||||
on Solaris,
|
||||
.Ql \&*
|
||||
on HP-UX, containing
|
||||
.Ql Nologin
|
||||
on Tru64 and a leading
|
||||
.Ql \&!!
|
||||
on Linux). If there is a requirement to disable password authentication
|
||||
for the account while allowing still public-key, then the passwd field
|
||||
should be set to something other than these values (eg
|
||||
.Ql NP
|
||||
or
|
||||
.Ql \&*NP\&*
|
||||
).
|
||||
.Pp
|
||||
Rhosts authentication is normally disabled
|
||||
because it is fundamentally insecure, but can be enabled in the server
|
||||
configuration file if desired.
|
||||
@ -291,7 +314,6 @@ may also be used to prevent
|
||||
from making DNS requests unless the authentication
|
||||
mechanism or configuration requires it.
|
||||
Authentication mechanisms that may require DNS include
|
||||
.Cm RhostsAuthentication ,
|
||||
.Cm RhostsRSAAuthentication ,
|
||||
.Cm HostbasedAuthentication
|
||||
and using a
|
||||
@ -430,13 +452,13 @@ that option keywords are case-insensitive):
|
||||
Specifies that in addition to public key authentication, the canonical name
|
||||
of the remote host must be present in the comma-separated list of
|
||||
patterns
|
||||
.Pf ( Ql *
|
||||
.Pf ( Ql \&*
|
||||
and
|
||||
.Ql ?
|
||||
.Ql \&?
|
||||
serve as wildcards).
|
||||
The list may also contain
|
||||
patterns negated by prefixing them with
|
||||
.Ql ! ;
|
||||
.Ql \&! ;
|
||||
if the canonical host name matches a negated pattern, the key is not accepted.
|
||||
The purpose
|
||||
of this option is to optionally increase security: public key authentication
|
||||
@ -498,9 +520,9 @@ IPv6 addresses can be specified with an alternative syntax:
|
||||
.Ar host/port .
|
||||
Multiple
|
||||
.Cm permitopen
|
||||
options may be applied separated by commas. No pattern matching is
|
||||
performed on the specified hostnames, they must be literal domains or
|
||||
addresses.
|
||||
options may be applied separated by commas.
|
||||
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
|
||||
@ -525,12 +547,16 @@ Each line in these files contains the following fields: hostnames,
|
||||
bits, exponent, modulus, comment.
|
||||
The fields are separated by spaces.
|
||||
.Pp
|
||||
Hostnames is a comma-separated list of patterns ('*' and '?' act as
|
||||
Hostnames is a comma-separated list of patterns
|
||||
.Pf ( Ql \&*
|
||||
and
|
||||
.Ql \&?
|
||||
act as
|
||||
wildcards); each pattern in turn is matched against the canonical host
|
||||
name (when authenticating a client) or against the user-supplied
|
||||
name (when authenticating a server).
|
||||
A pattern may also be preceded by
|
||||
.Ql !
|
||||
.Ql \&!
|
||||
to indicate negation: if the host name matches a negated
|
||||
pattern, it is not accepted (by that line) even if it matched another
|
||||
pattern on the line.
|
||||
@ -768,17 +794,6 @@ This can be used to specify
|
||||
machine-specific login-time initializations globally.
|
||||
This file should be writable only by root, and should be world-readable.
|
||||
.El
|
||||
.Sh AUTHORS
|
||||
OpenSSH is a derivative of the original and free
|
||||
ssh 1.2.12 release by Tatu Ylonen.
|
||||
Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos,
|
||||
Theo de Raadt and Dug Song
|
||||
removed many bugs, re-added newer features and
|
||||
created OpenSSH.
|
||||
Markus Friedl contributed the support for SSH
|
||||
protocol versions 1.5 and 2.0.
|
||||
Niels Provos and Markus Friedl contributed support
|
||||
for privilege separation.
|
||||
.Sh SEE ALSO
|
||||
.Xr scp 1 ,
|
||||
.Xr sftp 1 ,
|
||||
@ -810,3 +825,14 @@ for privilege separation.
|
||||
.%D January 2002
|
||||
.%O work in progress material
|
||||
.Re
|
||||
.Sh AUTHORS
|
||||
OpenSSH is a derivative of the original and free
|
||||
ssh 1.2.12 release by Tatu Ylonen.
|
||||
Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos,
|
||||
Theo de Raadt and Dug Song
|
||||
removed many bugs, re-added newer features and
|
||||
created OpenSSH.
|
||||
Markus Friedl contributed the support for SSH
|
||||
protocol versions 1.5 and 2.0.
|
||||
Niels Provos and Markus Friedl contributed support
|
||||
for privilege separation.
|
||||
|
@ -42,7 +42,7 @@
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: sshd.c,v 1.263 2003/02/16 17:09:57 markus Exp $");
|
||||
RCSID("$OpenBSD: sshd.c,v 1.276 2003/08/28 12:54:34 markus Exp $");
|
||||
RCSID("$FreeBSD$");
|
||||
|
||||
#include <openssl/dh.h>
|
||||
@ -117,11 +117,7 @@ char *config_file_name = _PATH_SERVER_CONFIG_FILE;
|
||||
* Flag indicating whether IPv4 or IPv6. This can be set on the command line.
|
||||
* Default value is AF_UNSPEC means both IPv4 and IPv6.
|
||||
*/
|
||||
#ifdef IPV4_DEFAULT
|
||||
int IPv4or6 = AF_INET;
|
||||
#else
|
||||
int IPv4or6 = AF_UNSPEC;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Debug mode flag. This can be set on the command line. If debug
|
||||
@ -197,7 +193,7 @@ u_char session_id[16];
|
||||
|
||||
/* same for ssh2 */
|
||||
u_char *session_id2 = NULL;
|
||||
int session_id2_len = 0;
|
||||
u_int session_id2_len = 0;
|
||||
|
||||
/* record remote hostname or ip */
|
||||
u_int utmp_len = MAXHOSTNAMELEN;
|
||||
@ -210,6 +206,9 @@ int startup_pipe; /* in child */
|
||||
int use_privsep;
|
||||
struct monitor *pmonitor;
|
||||
|
||||
/* message to be displayed after login */
|
||||
Buffer loginmsg;
|
||||
|
||||
/* Prototypes for various functions defined later in this file. */
|
||||
void destroy_sensitive_data(void);
|
||||
void demote_sensitive_data(void);
|
||||
@ -263,11 +262,11 @@ sighup_handler(int sig)
|
||||
static void
|
||||
sighup_restart(void)
|
||||
{
|
||||
log("Received SIGHUP; restarting.");
|
||||
logit("Received SIGHUP; restarting.");
|
||||
close_listen_socks();
|
||||
close_startup_pipes();
|
||||
execv(saved_argv[0], saved_argv);
|
||||
log("RESTART FAILED: av[0]='%.100s', error: %.100s.", saved_argv[0],
|
||||
logit("RESTART FAILED: av[0]='%.100s', error: %.100s.", saved_argv[0],
|
||||
strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
@ -376,39 +375,37 @@ sshd_exchange_identification(int sock_in, int sock_out)
|
||||
snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n", major, minor, SSH_VERSION);
|
||||
server_version_string = xstrdup(buf);
|
||||
|
||||
if (client_version_string == NULL) {
|
||||
/* Send our protocol version identification. */
|
||||
if (atomicio(write, sock_out, server_version_string,
|
||||
strlen(server_version_string))
|
||||
!= strlen(server_version_string)) {
|
||||
log("Could not write ident string to %s", get_remote_ipaddr());
|
||||
/* Send our protocol version identification. */
|
||||
if (atomicio(vwrite, sock_out, server_version_string,
|
||||
strlen(server_version_string))
|
||||
!= strlen(server_version_string)) {
|
||||
logit("Could not write ident string to %s", get_remote_ipaddr());
|
||||
fatal_cleanup();
|
||||
}
|
||||
|
||||
/* Read other sides version identification. */
|
||||
memset(buf, 0, sizeof(buf));
|
||||
for (i = 0; i < sizeof(buf) - 1; i++) {
|
||||
if (atomicio(read, sock_in, &buf[i], 1) != 1) {
|
||||
logit("Did not receive identification string from %s",
|
||||
get_remote_ipaddr());
|
||||
fatal_cleanup();
|
||||
}
|
||||
|
||||
/* Read other sides version identification. */
|
||||
memset(buf, 0, sizeof(buf));
|
||||
for (i = 0; i < sizeof(buf) - 1; i++) {
|
||||
if (atomicio(read, sock_in, &buf[i], 1) != 1) {
|
||||
log("Did not receive identification string from %s",
|
||||
get_remote_ipaddr());
|
||||
fatal_cleanup();
|
||||
}
|
||||
if (buf[i] == '\r') {
|
||||
buf[i] = 0;
|
||||
/* Kludge for F-Secure Macintosh < 1.0.2 */
|
||||
if (i == 12 &&
|
||||
strncmp(buf, "SSH-1.5-W1.0", 12) == 0)
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
if (buf[i] == '\n') {
|
||||
buf[i] = 0;
|
||||
if (buf[i] == '\r') {
|
||||
buf[i] = 0;
|
||||
/* Kludge for F-Secure Macintosh < 1.0.2 */
|
||||
if (i == 12 &&
|
||||
strncmp(buf, "SSH-1.5-W1.0", 12) == 0)
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (buf[i] == '\n') {
|
||||
buf[i] = 0;
|
||||
break;
|
||||
}
|
||||
buf[sizeof(buf) - 1] = 0;
|
||||
client_version_string = xstrdup(buf);
|
||||
}
|
||||
buf[sizeof(buf) - 1] = 0;
|
||||
client_version_string = xstrdup(buf);
|
||||
|
||||
/*
|
||||
* Check that the versions match. In future this might accept
|
||||
@ -417,10 +414,10 @@ sshd_exchange_identification(int sock_in, int sock_out)
|
||||
if (sscanf(client_version_string, "SSH-%d.%d-%[^\n]\n",
|
||||
&remote_major, &remote_minor, remote_version) != 3) {
|
||||
s = "Protocol mismatch.\n";
|
||||
(void) atomicio(write, sock_out, s, strlen(s));
|
||||
(void) atomicio(vwrite, sock_out, s, strlen(s));
|
||||
close(sock_in);
|
||||
close(sock_out);
|
||||
log("Bad protocol version identification '%.100s' from %s",
|
||||
logit("Bad protocol version identification '%.100s' from %s",
|
||||
client_version_string, get_remote_ipaddr());
|
||||
fatal_cleanup();
|
||||
}
|
||||
@ -430,13 +427,13 @@ sshd_exchange_identification(int sock_in, int sock_out)
|
||||
compat_datafellows(remote_version);
|
||||
|
||||
if (datafellows & SSH_BUG_PROBE) {
|
||||
log("probed from %s with %s. Don't panic.",
|
||||
logit("probed from %s with %s. Don't panic.",
|
||||
get_remote_ipaddr(), client_version_string);
|
||||
fatal_cleanup();
|
||||
}
|
||||
|
||||
if (datafellows & SSH_BUG_SCANNER) {
|
||||
log("scanned from %s with %s. Don't panic.",
|
||||
logit("scanned from %s with %s. Don't panic.",
|
||||
get_remote_ipaddr(), client_version_string);
|
||||
fatal_cleanup();
|
||||
}
|
||||
@ -478,10 +475,10 @@ sshd_exchange_identification(int sock_in, int sock_out)
|
||||
|
||||
if (mismatch) {
|
||||
s = "Protocol major versions differ.\n";
|
||||
(void) atomicio(write, sock_out, s, strlen(s));
|
||||
(void) atomicio(vwrite, sock_out, s, strlen(s));
|
||||
close(sock_in);
|
||||
close(sock_out);
|
||||
log("Protocol major versions differ for %s: %.200s vs. %.200s",
|
||||
logit("Protocol major versions differ for %s: %.200s vs. %.200s",
|
||||
get_remote_ipaddr(),
|
||||
server_version_string, client_version_string);
|
||||
fatal_cleanup();
|
||||
@ -573,8 +570,6 @@ privsep_preauth_child(void)
|
||||
do_setusercontext(pw);
|
||||
#else
|
||||
gidset[0] = pw->pw_gid;
|
||||
if (setgid(pw->pw_gid) < 0)
|
||||
fatal("setgid failed for %u", pw->pw_gid );
|
||||
if (setgroups(1, gidset) < 0)
|
||||
fatal("setgroups: %.100s", strerror(errno));
|
||||
permanently_set_uid(pw);
|
||||
@ -829,27 +824,27 @@ main(int ac, char **av)
|
||||
#ifdef HAVE_SECUREWARE
|
||||
(void)set_auth_parameters(ac, av);
|
||||
#endif
|
||||
__progname = get_progname(av[0]);
|
||||
__progname = ssh_get_progname(av[0]);
|
||||
init_rng();
|
||||
|
||||
/* Save argv. Duplicate so setproctitle emulation doesn't clobber it */
|
||||
saved_argc = ac;
|
||||
saved_argv = av;
|
||||
saved_argv = xmalloc(sizeof(*saved_argv) * (ac + 1));
|
||||
for (i = 0; i < ac; i++)
|
||||
saved_argv[i] = xstrdup(av[i]);
|
||||
saved_argv[ac] = NULL;
|
||||
saved_argv[i] = NULL;
|
||||
|
||||
#ifndef HAVE_SETPROCTITLE
|
||||
/* Prepare for later setproctitle emulation */
|
||||
compat_init_setproctitle(ac, av);
|
||||
av = saved_argv;
|
||||
#endif
|
||||
|
||||
/* Initialize configuration options to their default values. */
|
||||
initialize_server_options(&options);
|
||||
|
||||
/* Parse command-line arguments. */
|
||||
while ((opt = getopt(ac, av, "f:p:b:k:h:g:V:u:o:dDeiqtQ46")) != -1) {
|
||||
while ((opt = getopt(ac, av, "f:p:b:k:h:g:u:o:dDeiqtQ46")) != -1) {
|
||||
switch (opt) {
|
||||
case '4':
|
||||
IPv4or6 = AF_INET;
|
||||
@ -861,15 +856,11 @@ main(int ac, char **av)
|
||||
config_file_name = optarg;
|
||||
break;
|
||||
case 'd':
|
||||
if (0 == debug_flag) {
|
||||
if (debug_flag == 0) {
|
||||
debug_flag = 1;
|
||||
options.log_level = SYSLOG_LEVEL_DEBUG1;
|
||||
} else if (options.log_level < SYSLOG_LEVEL_DEBUG3) {
|
||||
} else if (options.log_level < SYSLOG_LEVEL_DEBUG3)
|
||||
options.log_level++;
|
||||
} else {
|
||||
fprintf(stderr, "Too high debugging level.\n");
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
case 'D':
|
||||
no_daemon_flag = 1;
|
||||
@ -920,11 +911,6 @@ main(int ac, char **av)
|
||||
}
|
||||
options.host_key_files[options.num_host_key_files++] = optarg;
|
||||
break;
|
||||
case 'V':
|
||||
client_version_string = optarg;
|
||||
/* only makes sense with inetd_flag, i.e. no listen() */
|
||||
inetd_flag = 1;
|
||||
break;
|
||||
case 't':
|
||||
test_flag = 1;
|
||||
break;
|
||||
@ -1016,15 +1002,15 @@ main(int ac, char **av)
|
||||
key_type(key));
|
||||
}
|
||||
if ((options.protocol & SSH_PROTO_1) && !sensitive_data.have_ssh1_key) {
|
||||
log("Disabling protocol version 1. Could not load host key");
|
||||
logit("Disabling protocol version 1. Could not load host key");
|
||||
options.protocol &= ~SSH_PROTO_1;
|
||||
}
|
||||
if ((options.protocol & SSH_PROTO_2) && !sensitive_data.have_ssh2_key) {
|
||||
log("Disabling protocol version 2. Could not load host key");
|
||||
logit("Disabling protocol version 2. Could not load host key");
|
||||
options.protocol &= ~SSH_PROTO_2;
|
||||
}
|
||||
if (!(options.protocol & (SSH_PROTO_1|SSH_PROTO_2))) {
|
||||
log("sshd: no hostkeys available -- exiting.");
|
||||
logit("sshd: no hostkeys available -- exiting.");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@ -1159,7 +1145,8 @@ main(int ac, char **av)
|
||||
continue;
|
||||
}
|
||||
/* Create socket for listening. */
|
||||
listen_sock = socket(ai->ai_family, SOCK_STREAM, 0);
|
||||
listen_sock = socket(ai->ai_family, ai->ai_socktype,
|
||||
ai->ai_protocol);
|
||||
if (listen_sock < 0) {
|
||||
/* kernel may not support ipv6 */
|
||||
verbose("socket: %.100s", strerror(errno));
|
||||
@ -1192,7 +1179,7 @@ main(int ac, char **av)
|
||||
num_listen_socks++;
|
||||
|
||||
/* Start listening on the port. */
|
||||
log("Server listening on %s port %s.", ntop, strport);
|
||||
logit("Server listening on %s port %s.", ntop, strport);
|
||||
if (listen(listen_sock, 5) < 0)
|
||||
fatal("listen: %.100s", strerror(errno));
|
||||
|
||||
@ -1227,7 +1214,10 @@ main(int ac, char **av)
|
||||
* overwrite any old pid in the file.
|
||||
*/
|
||||
f = fopen(options.pid_file, "wb");
|
||||
if (f) {
|
||||
if (f == NULL) {
|
||||
error("Couldn't create pid file \"%s\": %s",
|
||||
options.pid_file, strerror(errno));
|
||||
} else {
|
||||
fprintf(f, "%ld\n", (long) getpid());
|
||||
fclose(f);
|
||||
}
|
||||
@ -1268,7 +1258,7 @@ main(int ac, char **av)
|
||||
if (ret < 0 && errno != EINTR)
|
||||
error("select: %.100s", strerror(errno));
|
||||
if (received_sigterm) {
|
||||
log("Received signal %d; terminating.",
|
||||
logit("Received signal %d; terminating.",
|
||||
(int) received_sigterm);
|
||||
close_listen_socks();
|
||||
unlink(options.pid_file);
|
||||
@ -1406,11 +1396,11 @@ main(int ac, char **av)
|
||||
* setlogin() affects the entire process group. We don't
|
||||
* want the child to be able to affect the parent.
|
||||
*/
|
||||
#if !defined(STREAMS_PUSH_ACQUIRES_CTTY)
|
||||
#if !defined(SSHD_ACQUIRES_CTTY)
|
||||
/*
|
||||
* If setsid is called on Solaris, sshd will acquire the controlling
|
||||
* terminal while pushing STREAMS modules. This will prevent the
|
||||
* shell from acquiring it later.
|
||||
* If setsid is called, on some platforms sshd will later acquire a
|
||||
* controlling terminal which will result in "could not set
|
||||
* controlling tty" errors.
|
||||
*/
|
||||
if (!debug_flag && !inetd_flag && setsid() < 0)
|
||||
error("setsid: %.100s", strerror(errno));
|
||||
@ -1488,37 +1478,12 @@ main(int ac, char **av)
|
||||
alarm(options.login_grace_time);
|
||||
|
||||
sshd_exchange_identification(sock_in, sock_out);
|
||||
/*
|
||||
* Check that the connection comes from a privileged port.
|
||||
* Rhosts-Authentication only makes sense from privileged
|
||||
* programs. Of course, if the intruder has root access on his local
|
||||
* machine, he can connect from any port. So do not use these
|
||||
* authentication methods from machines that you do not trust.
|
||||
*/
|
||||
if (options.rhosts_authentication &&
|
||||
(remote_port >= IPPORT_RESERVED ||
|
||||
remote_port < IPPORT_RESERVED / 2)) {
|
||||
debug("Rhosts Authentication disabled, "
|
||||
"originating port %d not trusted.", remote_port);
|
||||
options.rhosts_authentication = 0;
|
||||
}
|
||||
#if defined(KRB4) && !defined(KRB5)
|
||||
if (!packet_connection_is_ipv4() &&
|
||||
options.kerberos_authentication) {
|
||||
debug("Kerberos Authentication disabled, only available for IPv4.");
|
||||
options.kerberos_authentication = 0;
|
||||
}
|
||||
#endif /* KRB4 && !KRB5 */
|
||||
#ifdef AFS
|
||||
/* If machine has AFS, set process authentication group. */
|
||||
if (k_hasafs()) {
|
||||
k_setpag();
|
||||
k_unlog();
|
||||
}
|
||||
#endif /* AFS */
|
||||
|
||||
packet_set_nonblocking();
|
||||
|
||||
/* prepare buffers to collect authentication messages */
|
||||
buffer_init(&loginmsg);
|
||||
|
||||
if (use_privsep)
|
||||
if ((authctxt = privsep_preauth()) != NULL)
|
||||
goto authenticated;
|
||||
@ -1560,7 +1525,8 @@ main(int ac, char **av)
|
||||
verbose("Closing connection to %.100s", remote_ip);
|
||||
|
||||
#ifdef USE_PAM
|
||||
finish_pam();
|
||||
if (options.use_pam)
|
||||
finish_pam();
|
||||
#endif /* USE_PAM */
|
||||
|
||||
packet_close();
|
||||
@ -1672,24 +1638,10 @@ do_ssh1_kex(void)
|
||||
|
||||
/* Declare supported authentication types. */
|
||||
auth_mask = 0;
|
||||
if (options.rhosts_authentication)
|
||||
auth_mask |= 1 << SSH_AUTH_RHOSTS;
|
||||
if (options.rhosts_rsa_authentication)
|
||||
auth_mask |= 1 << SSH_AUTH_RHOSTS_RSA;
|
||||
if (options.rsa_authentication)
|
||||
auth_mask |= 1 << SSH_AUTH_RSA;
|
||||
#if defined(KRB4) || defined(KRB5)
|
||||
if (options.kerberos_authentication)
|
||||
auth_mask |= 1 << SSH_AUTH_KERBEROS;
|
||||
#endif
|
||||
#if defined(AFS) || defined(KRB5)
|
||||
if (options.kerberos_tgt_passing)
|
||||
auth_mask |= 1 << SSH_PASS_KERBEROS_TGT;
|
||||
#endif
|
||||
#ifdef AFS
|
||||
if (options.afs_token_passing)
|
||||
auth_mask |= 1 << SSH_PASS_AFS_TOKEN;
|
||||
#endif
|
||||
if (options.challenge_response_authentication == 1)
|
||||
auth_mask |= 1 << SSH_AUTH_TIS;
|
||||
if (options.password_authentication)
|
||||
@ -1767,7 +1719,7 @@ do_ssh1_kex(void)
|
||||
u_char *buf = xmalloc(bytes);
|
||||
MD5_CTX md;
|
||||
|
||||
log("do_connection: generating a fake encryption key");
|
||||
logit("do_connection: generating a fake encryption key");
|
||||
BN_bn2bin(session_key_int, buf);
|
||||
MD5_Init(&md);
|
||||
MD5_Update(&md, buf, bytes);
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $OpenBSD: sshd_config,v 1.59 2002/09/25 11:17:16 markus Exp $
|
||||
# $OpenBSD: sshd_config,v 1.65 2003/08/28 12:54:34 markus Exp $
|
||||
# $FreeBSD$
|
||||
|
||||
# This is the sshd server system-wide configuration file. See
|
||||
@ -14,7 +14,7 @@
|
||||
# Note that some of FreeBSD's defaults differ from OpenBSD's, and
|
||||
# FreeBSD has a few additional options.
|
||||
|
||||
#VersionAddendum FreeBSD-20030924
|
||||
#VersionAddendum FreeBSD-20040106
|
||||
|
||||
#Port 22
|
||||
#Protocol 2,1
|
||||
@ -27,7 +27,7 @@
|
||||
#HostKey /etc/ssh/ssh_host_dsa_key
|
||||
|
||||
# Lifetime and size of ephemeral version 1 server key
|
||||
#KeyRegenerationInterval 3600
|
||||
#KeyRegenerationInterval 1h
|
||||
#ServerKeyBits 768
|
||||
|
||||
# Logging
|
||||
@ -37,7 +37,7 @@
|
||||
|
||||
# Authentication:
|
||||
|
||||
#LoginGraceTime 120
|
||||
#LoginGraceTime 2m
|
||||
#PermitRootLogin no
|
||||
#StrictModes yes
|
||||
|
||||
@ -45,10 +45,6 @@
|
||||
#PubkeyAuthentication yes
|
||||
#AuthorizedKeysFile .ssh/authorized_keys
|
||||
|
||||
# rhosts authentication should not be used
|
||||
#RhostsAuthentication no
|
||||
# Don't read the user's ~/.rhosts and ~/.shosts files
|
||||
#IgnoreRhosts yes
|
||||
# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
|
||||
#RhostsRSAAuthentication no
|
||||
# similar for protocol version 2
|
||||
@ -56,6 +52,8 @@
|
||||
# Change to yes if you don't trust ~/.ssh/known_hosts for
|
||||
# RhostsRSAAuthentication and HostbasedAuthentication
|
||||
#IgnoreUserKnownHosts no
|
||||
# Don't read the user's ~/.rhosts and ~/.shosts files
|
||||
#IgnoreRhosts yes
|
||||
|
||||
# To disable tunneled clear text passwords, change to no here!
|
||||
#PasswordAuthentication yes
|
||||
@ -69,11 +67,17 @@
|
||||
#KerberosOrLocalPasswd yes
|
||||
#KerberosTicketCleanup yes
|
||||
|
||||
#AFSTokenPassing no
|
||||
# GSSAPI options
|
||||
#GSSAPIAuthentication no
|
||||
#GSSAPICleanupCreds yes
|
||||
|
||||
# Kerberos TGT Passing only works with the AFS kaserver
|
||||
#KerberosTgtPassing no
|
||||
# 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
|
||||
|
||||
#AllowTcpForwarding yes
|
||||
#GatewayPorts no
|
||||
#X11Forwarding yes
|
||||
#X11DisplayOffset 10
|
||||
#X11UseLocalhost yes
|
||||
@ -84,11 +88,14 @@
|
||||
#UsePrivilegeSeparation yes
|
||||
#PermitUserEnvironment no
|
||||
#Compression yes
|
||||
|
||||
#ClientAliveInterval 0
|
||||
#ClientAliveCountMax 3
|
||||
#UseDNS yes
|
||||
#PidFile /var/run/sshd.pid
|
||||
#MaxStartups 10
|
||||
|
||||
# no default banner path
|
||||
#Banner /some/path
|
||||
#VerifyReverseMapping no
|
||||
|
||||
# override default of no subsystems
|
||||
Subsystem sftp /usr/libexec/sftp-server
|
||||
|
@ -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.15 2003/03/28 10:11:43 jmc Exp $
|
||||
.\" $OpenBSD: sshd_config.5,v 1.25 2003/09/01 09:50:04 markus Exp $
|
||||
.\" $FreeBSD$
|
||||
.Dd September 25, 1999
|
||||
.Dt SSHD_CONFIG 5
|
||||
@ -62,10 +62,6 @@ The possible
|
||||
keywords and their meanings are as follows (note that
|
||||
keywords are case-insensitive and arguments are case-sensitive):
|
||||
.Bl -tag -width Ds
|
||||
.It Cm AFSTokenPassing
|
||||
Specifies whether an AFS token may be forwarded to the server.
|
||||
Default is
|
||||
.Dq no .
|
||||
.It Cm AllowGroups
|
||||
This keyword can be followed by a list of group name patterns, separated
|
||||
by spaces.
|
||||
@ -73,7 +69,7 @@ If specified, login is allowed only for users whose primary
|
||||
group or supplementary group list matches one of the patterns.
|
||||
.Ql \&*
|
||||
and
|
||||
.Ql ?
|
||||
.Ql \&?
|
||||
can be used as
|
||||
wildcards in the patterns.
|
||||
Only group names are valid; a numerical group ID is not recognized.
|
||||
@ -94,7 +90,7 @@ If specified, login is allowed only for user names that
|
||||
match one of the patterns.
|
||||
.Ql \&*
|
||||
and
|
||||
.Ql ?
|
||||
.Ql \&?
|
||||
can be used as
|
||||
wildcards in the patterns.
|
||||
Only user names are valid; a numerical user ID is not recognized.
|
||||
@ -108,7 +104,8 @@ Specifies the file that contains the public keys that can be used
|
||||
for user authentication.
|
||||
.Cm AuthorizedKeysFile
|
||||
may contain tokens of the form %T which are substituted during connection
|
||||
set-up. The following tokens are defined: %% is replaced by a literal '%',
|
||||
set-up.
|
||||
The following tokens are defined: %% is replaced by a literal '%',
|
||||
%h is replaced by the home directory of the user being authenticated and
|
||||
%u is replaced by the username of that user.
|
||||
After expansion,
|
||||
@ -146,7 +143,7 @@ The default is
|
||||
.Pp
|
||||
.Bd -literal
|
||||
``aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour,
|
||||
aes192-cbc,aes256-cbc''
|
||||
aes192-cbc,aes256-cbc,aes128-ctr,aes192-ctr,aes256-ctr''
|
||||
.Ed
|
||||
.It Cm ClientAliveInterval
|
||||
Sets a timeout interval in seconds after which if no data has been received
|
||||
@ -161,20 +158,24 @@ This option applies to protocol version 2 only.
|
||||
Sets the number of client alive messages (see above) which may be
|
||||
sent without
|
||||
.Nm sshd
|
||||
receiving any messages back from the client. If this threshold is
|
||||
reached while client alive messages are being sent,
|
||||
receiving any messages back from the client.
|
||||
If this threshold is reached while client alive messages are being sent,
|
||||
.Nm sshd
|
||||
will disconnect the client, terminating the session. It is important
|
||||
to note that the use of client alive messages is very different from
|
||||
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
|
||||
(below). The client alive messages are sent through the
|
||||
encrypted channel and therefore will not be spoofable. The TCP keepalive
|
||||
option enabled by
|
||||
(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
|
||||
is spoofable. The client alive mechanism is valuable when the client or
|
||||
is spoofable.
|
||||
The client 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
|
||||
The default value is 3.
|
||||
If
|
||||
.Cm ClientAliveInterval
|
||||
(above) is set to 15, and
|
||||
.Cm ClientAliveCountMax
|
||||
@ -195,7 +196,7 @@ Login is disallowed for users whose primary group or supplementary
|
||||
group list matches one of the patterns.
|
||||
.Ql \&*
|
||||
and
|
||||
.Ql ?
|
||||
.Ql \&?
|
||||
can be used as
|
||||
wildcards in the patterns.
|
||||
Only group names are valid; a numerical group ID is not recognized.
|
||||
@ -207,7 +208,7 @@ by spaces.
|
||||
Login is disallowed for user names that match one of the patterns.
|
||||
.Ql \&*
|
||||
and
|
||||
.Ql ?
|
||||
.Ql \&?
|
||||
can be used as wildcards in the patterns.
|
||||
Only user names are valid; a numerical user ID is not recognized.
|
||||
By default, login is allowed for all users.
|
||||
@ -232,6 +233,17 @@ or
|
||||
.Dq no .
|
||||
The default is
|
||||
.Dq no .
|
||||
.It Cm GSSAPIAuthentication
|
||||
Specifies whether user authentication based on GSSAPI is allowed.
|
||||
The default is
|
||||
.Dq no .
|
||||
Note that this option applies to protocol version 2 only.
|
||||
.It Cm GSSAPICleanupCredentials
|
||||
Specifies whether to automatically destroy the user's credentials cache
|
||||
on logout.
|
||||
The default is
|
||||
.Dq yes .
|
||||
Note that this option applies to protocol version 2 only.
|
||||
.It Cm HostbasedAuthentication
|
||||
Specifies whether rhosts or /etc/hosts.equiv authentication together
|
||||
with successful public key client host authentication is allowed
|
||||
@ -265,7 +277,6 @@ Specifies that
|
||||
and
|
||||
.Pa .shosts
|
||||
files will not be used in
|
||||
.Cm RhostsAuthentication ,
|
||||
.Cm RhostsRSAAuthentication
|
||||
or
|
||||
.Cm HostbasedAuthentication .
|
||||
@ -309,11 +320,9 @@ This avoids infinitely hanging sessions.
|
||||
To disable keepalives, the value should be set to
|
||||
.Dq no .
|
||||
.It Cm KerberosAuthentication
|
||||
Specifies whether Kerberos authentication is allowed.
|
||||
This can be in the form of a Kerberos ticket, or if
|
||||
Specifies whether the password provided by the user for
|
||||
.Cm PasswordAuthentication
|
||||
is yes, the password provided by the user will be validated through
|
||||
the Kerberos KDC.
|
||||
will be validated through the Kerberos KDC.
|
||||
To use this option, the server needs a
|
||||
Kerberos servtab which allows the verification of the KDC's identity.
|
||||
Default is
|
||||
@ -325,11 +334,6 @@ such as
|
||||
.Pa /etc/passwd .
|
||||
Default is
|
||||
.Dq yes .
|
||||
.It Cm KerberosTgtPassing
|
||||
Specifies whether a Kerberos TGT may be forwarded to the server.
|
||||
Default is
|
||||
.Dq no ,
|
||||
as this only works when the Kerberos KDC is actually an AFS kaserver.
|
||||
.It Cm KerberosTicketCleanup
|
||||
Specifies whether to automatically destroy the user's ticket cache
|
||||
file on logout.
|
||||
@ -375,11 +379,12 @@ is not specified,
|
||||
.Nm sshd
|
||||
will listen on the address and all prior
|
||||
.Cm Port
|
||||
options specified. The default is to listen on all local
|
||||
addresses.
|
||||
options specified.
|
||||
The default is to listen on all local addresses.
|
||||
Multiple
|
||||
.Cm ListenAddress
|
||||
options are permitted. Additionally, any
|
||||
options are permitted.
|
||||
Additionally, any
|
||||
.Cm Port
|
||||
options must precede this option for non port qualified addresses.
|
||||
.It Cm LoginGraceTime
|
||||
@ -478,8 +483,8 @@ but only if the
|
||||
.Ar command
|
||||
option has been specified
|
||||
(which may be useful for taking remote backups even if root login is
|
||||
normally not allowed). All other authentication methods are disabled
|
||||
for root.
|
||||
normally not allowed).
|
||||
All other authentication methods are disabled for root.
|
||||
.Pp
|
||||
If this option is set to
|
||||
.Dq no
|
||||
@ -552,20 +557,6 @@ Specifies whether public key authentication is allowed.
|
||||
The default is
|
||||
.Dq yes .
|
||||
Note that this option applies to protocol version 2 only.
|
||||
.It Cm RhostsAuthentication
|
||||
Specifies whether authentication using rhosts or
|
||||
.Pa /etc/hosts.equiv
|
||||
files is sufficient.
|
||||
Normally, this method should not be permitted because it is insecure.
|
||||
.Cm RhostsRSAAuthentication
|
||||
should be used
|
||||
instead, because it performs RSA-based host authentication in addition
|
||||
to normal rhosts or
|
||||
.Pa /etc/hosts.equiv
|
||||
authentication.
|
||||
The default is
|
||||
.Dq no .
|
||||
This option applies to protocol version 1 only.
|
||||
.It Cm RhostsRSAAuthentication
|
||||
Specifies whether rhosts or
|
||||
.Pa /etc/hosts.equiv
|
||||
@ -608,6 +599,14 @@ 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 UseDNS
|
||||
Specifies whether
|
||||
.Nm sshd
|
||||
should lookup the remote host name and check that
|
||||
the resolved host name for the remote IP address maps back to the
|
||||
very same IP address.
|
||||
The default is
|
||||
.Dq yes .
|
||||
.It Cm UseLogin
|
||||
Specifies whether
|
||||
.Xr login 1
|
||||
@ -627,6 +626,13 @@ cookies.
|
||||
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
|
||||
.Cm PasswordAuthentication .
|
||||
If you enable
|
||||
.CM UsePAM
|
||||
then you will not be able to run sshd as a non-root user.
|
||||
.It Cm UsePrivilegeSeparation
|
||||
Specifies whether
|
||||
.Nm sshd
|
||||
@ -638,19 +644,11 @@ The goal of privilege separation is to prevent privilege
|
||||
escalation by containing any corruption within the unprivileged processes.
|
||||
The default is
|
||||
.Dq yes .
|
||||
.It Cm VerifyReverseMapping
|
||||
Specifies whether
|
||||
.Nm sshd
|
||||
should try to verify the remote host name and check that
|
||||
the resolved host name for the remote IP address maps back to the
|
||||
very same IP address.
|
||||
The default is
|
||||
.Dq no .
|
||||
.It Cm VersionAddendum
|
||||
Specifies a string to append to the regular version string to identify
|
||||
OS- or site-specific modifications.
|
||||
The default is
|
||||
.Dq FreeBSD-20030924 .
|
||||
.Dq FreeBSD-20040106 .
|
||||
.It Cm X11DisplayOffset
|
||||
Specifies the first display number available for
|
||||
.Nm sshd Ns 's
|
||||
@ -681,7 +679,7 @@ display server may be exposed to attack when the ssh client requests
|
||||
forwarding (see the warnings for
|
||||
.Cm ForwardX11
|
||||
in
|
||||
.Xr ssh_config 5 ).
|
||||
.Xr ssh_config 5 ) .
|
||||
A system administrator may have a stance in which they want to
|
||||
protect clients that may expose themselves to attack by unwittingly
|
||||
requesting X11 forwarding, which can warrant a
|
||||
@ -727,7 +725,6 @@ The default is
|
||||
.Pa /usr/X11R6/bin/xauth .
|
||||
.El
|
||||
.Ss Time Formats
|
||||
.Pp
|
||||
.Nm sshd
|
||||
command-line arguments and configuration file options that specify time
|
||||
may be expressed using a sequence of the form:
|
||||
@ -776,6 +773,8 @@ Contains configuration data for
|
||||
This file should be writable by root only, but it is recommended
|
||||
(though not necessary) that it be world-readable.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr sshd 8
|
||||
.Sh AUTHORS
|
||||
OpenSSH is a derivative of the original and free
|
||||
ssh 1.2.12 release by Tatu Ylonen.
|
||||
@ -787,5 +786,3 @@ Markus Friedl contributed the support for SSH
|
||||
protocol versions 1.5 and 2.0.
|
||||
Niels Provos and Markus Friedl contributed support
|
||||
for privilege separation.
|
||||
.Sh SEE ALSO
|
||||
.Xr sshd 8
|
||||
|
@ -39,7 +39,7 @@
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: sshlogin.c,v 1.5 2002/08/29 15:57:25 stevesk Exp $");
|
||||
RCSID("$OpenBSD: sshlogin.c,v 1.7 2003/06/12 07:57:38 markus Exp $");
|
||||
|
||||
#include "loginrec.h"
|
||||
|
||||
@ -60,8 +60,8 @@ get_last_login_time(uid_t uid, const char *logname,
|
||||
}
|
||||
|
||||
/*
|
||||
* Records that the user has logged in. I these parts of operating systems
|
||||
* were more standardized.
|
||||
* Records that the user has logged in. I wish these parts of operating
|
||||
* systems were more standardized.
|
||||
*/
|
||||
void
|
||||
record_login(pid_t pid, const char *ttyname, const char *user, uid_t uid,
|
||||
|
@ -12,7 +12,7 @@
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: sshpty.c,v 1.8 2003/02/03 08:56:16 markus Exp $");
|
||||
RCSID("$OpenBSD: sshpty.c,v 1.10 2003/06/12 07:57:38 markus Exp $");
|
||||
|
||||
#ifdef HAVE_UTIL_H
|
||||
# include <util.h>
|
||||
@ -101,12 +101,12 @@ pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, int namebuflen)
|
||||
error("/dev/ptmx: %.100s", strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
old_signal = mysignal(SIGCHLD, SIG_DFL);
|
||||
old_signal = signal(SIGCHLD, SIG_DFL);
|
||||
if (grantpt(ptm) < 0) {
|
||||
error("grantpt: %.100s", strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
mysignal(SIGCHLD, old_signal);
|
||||
signal(SIGCHLD, old_signal);
|
||||
if (unlockpt(ptm) < 0) {
|
||||
error("unlockpt: %.100s", strerror(errno));
|
||||
return 0;
|
||||
@ -226,7 +226,7 @@ pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, int namebuflen)
|
||||
}
|
||||
/* set tty modes to a sane state for broken clients */
|
||||
if (tcgetattr(*ptyfd, &tio) < 0)
|
||||
log("Getting tty modes for pty failed: %.100s", strerror(errno));
|
||||
logit("Getting tty modes for pty failed: %.100s", strerror(errno));
|
||||
else {
|
||||
tio.c_lflag |= (ECHO | ISIG | ICANON);
|
||||
tio.c_oflag |= (OPOST | ONLCR);
|
||||
@ -234,7 +234,7 @@ pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, int namebuflen)
|
||||
|
||||
/* Set the new modes for the terminal. */
|
||||
if (tcsetattr(*ptyfd, TCSANOW, &tio) < 0)
|
||||
log("Setting tty modes for pty failed: %.100s", strerror(errno));
|
||||
logit("Setting tty modes for pty failed: %.100s", strerror(errno));
|
||||
}
|
||||
|
||||
return 1;
|
||||
@ -258,7 +258,7 @@ pty_release(const char *ttyname)
|
||||
error("chmod %.100s 0666 failed: %.100s", ttyname, strerror(errno));
|
||||
}
|
||||
|
||||
/* Makes the tty the processes controlling tty and sets it to sane modes. */
|
||||
/* Makes the tty the process's controlling tty and sets it to sane modes. */
|
||||
|
||||
void
|
||||
pty_make_controlling_tty(int *ttyfd, const char *ttyname)
|
||||
@ -274,9 +274,9 @@ pty_make_controlling_tty(int *ttyfd, const char *ttyname)
|
||||
|
||||
fd = open(ttyname, O_RDWR|O_NOCTTY);
|
||||
if (fd != -1) {
|
||||
mysignal(SIGHUP, SIG_IGN);
|
||||
signal(SIGHUP, SIG_IGN);
|
||||
ioctl(fd, TCVHUP, (char *)NULL);
|
||||
mysignal(SIGHUP, SIG_DFL);
|
||||
signal(SIGHUP, SIG_DFL);
|
||||
setpgid(0, 0);
|
||||
close(fd);
|
||||
} else {
|
||||
@ -323,9 +323,9 @@ pty_make_controlling_tty(int *ttyfd, const char *ttyname)
|
||||
error("SETPGRP %s",strerror(errno));
|
||||
#endif /* HAVE_NEWS4 */
|
||||
#ifdef USE_VHANGUP
|
||||
old = mysignal(SIGHUP, SIG_IGN);
|
||||
old = signal(SIGHUP, SIG_IGN);
|
||||
vhangup();
|
||||
mysignal(SIGHUP, old);
|
||||
signal(SIGHUP, old);
|
||||
#endif /* USE_VHANGUP */
|
||||
fd = open(ttyname, O_RDWR);
|
||||
if (fd < 0) {
|
||||
@ -409,10 +409,10 @@ pty_setowner(struct passwd *pw, const char *ttyname)
|
||||
if (errno == EROFS &&
|
||||
(st.st_mode & (S_IRGRP | S_IROTH)) == 0)
|
||||
debug("chmod(%.100s, 0%o) failed: %.100s",
|
||||
ttyname, mode, strerror(errno));
|
||||
ttyname, (u_int)mode, strerror(errno));
|
||||
else
|
||||
fatal("chmod(%.100s, 0%o) failed: %.100s",
|
||||
ttyname, mode, strerror(errno));
|
||||
ttyname, (u_int)mode, strerror(errno));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +1,12 @@
|
||||
/* $OpenBSD: version.h,v 1.37 2003/04/01 10:56:46 markus Exp $ */
|
||||
/* $OpenBSD: version.h,v 1.39 2003/09/16 21:02:40 markus Exp $ */
|
||||
/* $FreeBSD$ */
|
||||
|
||||
#ifndef SSH_VERSION
|
||||
|
||||
#define SSH_VERSION (ssh_version_get())
|
||||
#define SSH_VERSION_BASE "OpenSSH_3.6.1p1"
|
||||
#define SSH_VERSION_ADDENDUM "FreeBSD-20030924"
|
||||
#define SSH_VERSION_BASE "OpenSSH_3.7.1p2"
|
||||
#define SSH_VERSION_ADDENDUM "FreeBSD-20040106"
|
||||
|
||||
const char *ssh_version_get(void);
|
||||
void ssh_version_set_addendum(const char *add);
|
||||
#endif /* SSH_VERSION */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user