diff options
-rw-r--r-- | ChangeLog | 7 | ||||
-rw-r--r-- | auth.c | 5 | ||||
-rw-r--r-- | canohost.c | 3 | ||||
-rw-r--r-- | canohost.h | 2 | ||||
-rw-r--r-- | configure.ac | 5 | ||||
-rw-r--r-- | defines.h | 11 | ||||
-rw-r--r-- | loginrec.c | 104 |
7 files changed, 130 insertions, 7 deletions
@@ -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 | ||
13 | 20050201 | 18 | 20050201 |
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 $ |
@@ -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 | ||
22 | static void check_ip_options(int, char *); | 22 | static void check_ip_options(int, char *); |
23 | static 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 | ||
169 | static void | 168 | void |
170 | ipv64_normalise_mapped(struct sockaddr_storage *addr, socklen_t *len) | 169 | ipv64_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 | ||
24 | int get_remote_port(void); | 24 | int get_remote_port(void); |
25 | int get_local_port(void); | 25 | int get_local_port(void); |
26 | |||
27 | void 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.*) |
@@ -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 | ||
143 | RCSID("$Id: loginrec.c,v 1.62 2004/09/12 05:26:01 djm Exp $"); | 166 | RCSID("$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 | |||
1598 | void | ||
1599 | record_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 | |||
1664 | out: | ||
1665 | close(fd); | ||
1666 | } | ||
1667 | #endif /* USE_BTMP */ | ||