summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDarren Tucker <dtucker@zip.com.au>2005-02-02 23:30:24 +1100
committerDarren Tucker <dtucker@zip.com.au>2005-02-02 23:30:24 +1100
commit2fba993080eba14e339d6a6666ee79580ee20f97 (patch)
tree0b7bc9ce53758047f3a844b0f9d5679ace5e94eb
parent9dc6c7dbec0716157e561036c480bca1bc3c7e47 (diff)
- (dtucker) [auth.c canohost.c canohost.h configure.ac defines.h loginrec.c]
Bug #974: Teach sshd to write failed login records to btmp for failed auth attempts (currently only for password, kbdint and C/R, only on Linux and HP-UX), based on code from login.c from util-linux. With ashok_kovai at hotmail.com, ok djm@
-rw-r--r--ChangeLog7
-rw-r--r--auth.c5
-rw-r--r--canohost.c3
-rw-r--r--canohost.h2
-rw-r--r--configure.ac5
-rw-r--r--defines.h11
-rw-r--r--loginrec.c104
7 files changed, 130 insertions, 7 deletions
diff --git a/ChangeLog b/ChangeLog
index d9670f361..07ae663d7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -9,6 +9,11 @@
9 the process. Since we also unset KRB5CCNAME at startup, if it's set after 9 the process. Since we also unset KRB5CCNAME at startup, if it's set after
10 authentication it must have been set by the platform's native auth system. 10 authentication it must have been set by the platform's native auth system.
11 This was already done for AIX; this enables it for the general case. 11 This was already done for AIX; this enables it for the general case.
12 - (dtucker) [auth.c canohost.c canohost.h configure.ac defines.h loginrec.c]
13 Bug #974: Teach sshd to write failed login records to btmp for failed auth
14 attempts (currently only for password, kbdint and C/R, only on Linux and
15 HP-UX), based on code from login.c from util-linux. With ashok_kovai at
16 hotmail.com, ok djm@
12 17
1320050201 1820050201
14 - (dtucker) [log.c] Bug #973: force log_init() to open syslog, since on some 19 - (dtucker) [log.c] Bug #973: force log_init() to open syslog, since on some
@@ -2063,4 +2068,4 @@
2063 - (djm) Trim deprecated options from INSTALL. Mention UsePAM 2068 - (djm) Trim deprecated options from INSTALL. Mention UsePAM
2064 - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu 2069 - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu
2065 2070
2066$Id: ChangeLog,v 1.3631 2005/02/02 07:30:33 dtucker Exp $ 2071$Id: ChangeLog,v 1.3632 2005/02/02 12:30:24 dtucker Exp $
diff --git a/auth.c b/auth.c
index dfc1be374..b6c00c12b 100644
--- a/auth.c
+++ b/auth.c
@@ -244,7 +244,10 @@ auth_log(Authctxt *authctxt, int authenticated, char *method, char *info)
244 info); 244 info);
245 245
246#ifdef CUSTOM_FAILED_LOGIN 246#ifdef CUSTOM_FAILED_LOGIN
247 if (authenticated == 0 && strcmp(method, "password") == 0) 247 if (authenticated == 0 && !authctxt->postponed &&
248 (strcmp(method, "password") == 0 ||
249 strncmp(method, "keyboard-interactive", 20) == 0) ||
250 strcmp(method, "challenge-response") == 0)
248 record_failed_login(authctxt->user, 251 record_failed_login(authctxt->user,
249 get_canonical_hostname(options.use_dns), "ssh"); 252 get_canonical_hostname(options.use_dns), "ssh");
250#endif 253#endif
diff --git a/canohost.c b/canohost.c
index 8ad684d6c..e5a6b6be3 100644
--- a/canohost.c
+++ b/canohost.c
@@ -20,7 +20,6 @@ RCSID("$OpenBSD: canohost.c,v 1.41 2004/07/21 11:51:29 djm Exp $");
20#include "canohost.h" 20#include "canohost.h"
21 21
22static void check_ip_options(int, char *); 22static void check_ip_options(int, char *);
23static void ipv64_normalise_mapped(struct sockaddr_storage *, socklen_t *);
24 23
25/* 24/*
26 * Return the canonical name of the host at the other end of the socket. The 25 * Return the canonical name of the host at the other end of the socket. The
@@ -166,7 +165,7 @@ check_ip_options(int sock, char *ipaddr)
166#endif /* IP_OPTIONS */ 165#endif /* IP_OPTIONS */
167} 166}
168 167
169static void 168void
170ipv64_normalise_mapped(struct sockaddr_storage *addr, socklen_t *len) 169ipv64_normalise_mapped(struct sockaddr_storage *addr, socklen_t *len)
171{ 170{
172 struct sockaddr_in6 *a6 = (struct sockaddr_in6 *)addr; 171 struct sockaddr_in6 *a6 = (struct sockaddr_in6 *)addr;
diff --git a/canohost.h b/canohost.h
index 4347b488a..df1f125e5 100644
--- a/canohost.h
+++ b/canohost.h
@@ -23,3 +23,5 @@ char *get_local_name(int);
23 23
24int get_remote_port(void); 24int get_remote_port(void);
25int get_local_port(void); 25int get_local_port(void);
26
27void ipv64_normalise_mapped(struct sockaddr_storage *, socklen_t *);
diff --git a/configure.ac b/configure.ac
index 94d6b1e78..86b26daf9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,4 +1,4 @@
1# $Id: configure.ac,v 1.236 2005/02/01 23:44:00 dtucker Exp $ 1# $Id: configure.ac,v 1.237 2005/02/02 12:30:25 dtucker Exp $
2# 2#
3# Copyright (c) 1999-2004 Damien Miller 3# Copyright (c) 1999-2004 Damien Miller
4# 4#
@@ -219,6 +219,7 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16))
219 AC_DEFINE(DISABLE_UTMP) 219 AC_DEFINE(DISABLE_UTMP)
220 AC_DEFINE(LOCKED_PASSWD_STRING, "*") 220 AC_DEFINE(LOCKED_PASSWD_STRING, "*")
221 AC_DEFINE(SPT_TYPE,SPT_PSTAT) 221 AC_DEFINE(SPT_TYPE,SPT_PSTAT)
222 AC_DEFINE(USE_BTMP, 1, [Use btmp to log bad logins])
222 check_for_hpux_broken_getaddrinfo=1 223 check_for_hpux_broken_getaddrinfo=1
223 check_for_conflicting_getspnam=1 224 check_for_conflicting_getspnam=1
224 LIBS="$LIBS -lsec" 225 LIBS="$LIBS -lsec"
@@ -256,6 +257,8 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16))
256 AC_DEFINE(LOCKED_PASSWD_PREFIX, "!") 257 AC_DEFINE(LOCKED_PASSWD_PREFIX, "!")
257 AC_DEFINE(SPT_TYPE,SPT_REUSEARGV) 258 AC_DEFINE(SPT_TYPE,SPT_REUSEARGV)
258 AC_DEFINE(LINK_OPNOTSUPP_ERRNO, EPERM) 259 AC_DEFINE(LINK_OPNOTSUPP_ERRNO, EPERM)
260 AC_DEFINE(_PATH_BTMP, "/var/log/btmp", [log for bad login attempts])
261 AC_DEFINE(USE_BTMP, 1, [Use btmp to log bad logins])
259 inet6_default_4in6=yes 262 inet6_default_4in6=yes
260 case `uname -r` in 263 case `uname -r` in
261 1.*|2.0.*) 264 1.*|2.0.*)
diff --git a/defines.h b/defines.h
index 8c1d9c409..4d59408ad 100644
--- a/defines.h
+++ b/defines.h
@@ -25,7 +25,7 @@
25#ifndef _DEFINES_H 25#ifndef _DEFINES_H
26#define _DEFINES_H 26#define _DEFINES_H
27 27
28/* $Id: defines.h,v 1.117 2004/06/22 03:27:16 dtucker Exp $ */ 28/* $Id: defines.h,v 1.118 2005/02/02 12:30:25 dtucker Exp $ */
29 29
30 30
31/* Constants */ 31/* Constants */
@@ -644,6 +644,15 @@ struct winsize {
644# define CUSTOM_SYS_AUTH_PASSWD 1 644# define CUSTOM_SYS_AUTH_PASSWD 1
645#endif 645#endif
646 646
647/* HP-UX 11.11 */
648#ifdef BTMP_FILE
649# define _PATH_BTMP BTMP_FILE
650#endif
651
652#if defined(USE_BTMP) && defined(_PATH_BTMP)
653# define CUSTOM_FAILED_LOGIN
654#endif
655
647/** end of login recorder definitions */ 656/** end of login recorder definitions */
648 657
649#endif /* _DEFINES_H */ 658#endif /* _DEFINES_H */
diff --git a/loginrec.c b/loginrec.c
index 25aa29f2f..e77318ba3 100644
--- a/loginrec.c
+++ b/loginrec.c
@@ -25,6 +25,27 @@
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28/*
29 * The btmp logging code is derived from login.c from util-linux and is under
30 * the the following license:
31 *
32 * Copyright (c) 1980, 1987, 1988 The Regents of the University of California.
33 * All rights reserved.
34 *
35 * Redistribution and use in source and binary forms are permitted
36 * provided that the above copyright notice and this paragraph are
37 * duplicated in all such forms and that any documentation,
38 * advertising materials, and other materials related to such
39 * distribution and use acknowledge that the software was developed
40 * by the University of California, Berkeley. The name of the
41 * University may not be used to endorse or promote products derived
42 * from this software without specific prior written permission.
43 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
44 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
45 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
46 */
47
48
28/** 49/**
29 ** loginrec.c: platform-independent login recording and lastlog retrieval 50 ** loginrec.c: platform-independent login recording and lastlog retrieval
30 **/ 51 **/
@@ -131,6 +152,8 @@
131#include "loginrec.h" 152#include "loginrec.h"
132#include "log.h" 153#include "log.h"
133#include "atomicio.h" 154#include "atomicio.h"
155#include "packet.h"
156#include "canohost.h"
134 157
135#ifdef HAVE_UTIL_H 158#ifdef HAVE_UTIL_H
136# include <util.h> 159# include <util.h>
@@ -140,7 +163,7 @@
140# include <libutil.h> 163# include <libutil.h>
141#endif 164#endif
142 165
143RCSID("$Id: loginrec.c,v 1.62 2004/09/12 05:26:01 djm Exp $"); 166RCSID("$Id: loginrec.c,v 1.63 2005/02/02 12:30:25 dtucker Exp $");
144 167
145/** 168/**
146 ** prototypes for helper functions in this file 169 ** prototypes for helper functions in this file
@@ -1563,3 +1586,82 @@ lastlog_get_entry(struct logininfo *li)
1563 return (0); 1586 return (0);
1564} 1587}
1565#endif /* USE_LASTLOG */ 1588#endif /* USE_LASTLOG */
1589
1590#ifdef USE_BTMP
1591 /*
1592 * Logs failed login attempts in _PATH_BTMP if that exists.
1593 * The most common login failure is to give password instead of username.
1594 * So the _PATH_BTMP file checked for the correct permission, so that
1595 * only root can read it.
1596 */
1597
1598void
1599record_failed_login(const char *username, const char *hostname,
1600 const char *ttyn)
1601{
1602 int fd;
1603 struct utmp ut;
1604 struct sockaddr_storage from;
1605 size_t fromlen = sizeof(from);
1606 struct sockaddr_in *a4;
1607 struct sockaddr_in6 *a6;
1608 time_t t;
1609 struct stat fst;
1610
1611 if (geteuid() != 0)
1612 return;
1613 if ((fd = open(_PATH_BTMP, O_WRONLY | O_APPEND)) < 0) {
1614 debug("Unable to open the btmp file %s: %s", _PATH_BTMP,
1615 strerror(errno));
1616 return;
1617 }
1618 if (fstat(fd, &fst) < 0) {
1619 logit("%s: fstat of %s failed: %s", __func__, _PATH_BTMP,
1620 strerror(errno));
1621 goto out;
1622 }
1623 if((fst.st_mode & (S_IRWXG | S_IRWXO)) || (fst.st_uid != 0)){
1624 logit("Excess permission or bad ownership on file %s",
1625 _PATH_BTMP);
1626 goto out;
1627 }
1628
1629 memset(&ut, 0, sizeof(ut));
1630 /* strncpy because we don't necessarily want nul termination */
1631 strncpy(ut.ut_user, username, sizeof(ut.ut_user));
1632 strlcpy(ut.ut_line, "ssh:notty", sizeof(ut.ut_line));
1633
1634 time(&t);
1635 ut.ut_time = t; /* ut_time is not always a time_t */
1636 ut.ut_type = LOGIN_PROCESS;
1637 ut.ut_pid = getpid();
1638
1639 /* strncpy because we don't necessarily want nul termination */
1640 strncpy(ut.ut_host, hostname, sizeof(ut.ut_host));
1641
1642 if (packet_connection_is_on_socket() &&
1643 getpeername(packet_get_connection_in(),
1644 (struct sockaddr *)&from, &fromlen) == 0) {
1645 ipv64_normalise_mapped(&from, &fromlen);
1646 if (from.ss_family == AF_INET) {
1647 a4 = (struct sockaddr_in *)&from;
1648 memcpy(&ut.ut_addr, &(a4->sin_addr),
1649 MIN_SIZEOF(ut.ut_addr, a4->sin_addr));
1650 }
1651#ifdef HAVE_ADDR_V6_IN_UTMP
1652 if (from.ss_family == AF_INET6) {
1653 a6 = (struct sockaddr_in6 *)&from;
1654 memcpy(&ut.ut_addr_v6, &(a6->sin6_addr),
1655 MIN_SIZEOF(ut.ut_addr_v6, a6->sin6_addr));
1656 }
1657#endif
1658 }
1659
1660 if (atomicio(vwrite, fd, &ut, sizeof(ut)) != sizeof(ut))
1661 error("Failed to write to %s: %s", _PATH_BTMP,
1662 strerror(errno));
1663
1664out:
1665 close(fd);
1666}
1667#endif /* USE_BTMP */