summaryrefslogtreecommitdiff
path: root/loginrec.c
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 /loginrec.c
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@
Diffstat (limited to 'loginrec.c')
-rw-r--r--loginrec.c104
1 files changed, 103 insertions, 1 deletions
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 */