use construct_utmp to construct btmp records

Simpler and removes some code with the old-style BSD license.
This commit is contained in:
Damien Miller 2024-09-15 12:53:59 +10:00
parent 930cb02b61
commit 671c440786
No known key found for this signature in database

View File

@ -25,27 +25,6 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* The btmp logging code is derived from login.c from util-linux and is under
* the the following license:
*
* Copyright (c) 1980, 1987, 1988 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
/**
** loginrec.c: platform-independent login recording and lastlog retrieval
**/
@ -603,6 +582,9 @@ line_abbrevname(char *dst, const char *src, int dstsize)
memset(dst, '\0', dstsize);
if (strcmp(src, "ssh:notty") == 0)
return dst;
/* Always skip prefix if present */
if (strncmp(src, "/dev/", 5) == 0)
src += 5;
@ -1651,23 +1633,20 @@ utmpx_get_entry(struct logininfo *li)
#endif /* USE_UTMPX && HAVE_SETUTXDB && UTXDB_LASTLOGIN && HAVE_GETUTXUSER */
#ifdef USE_BTMP
/*
* Logs failed login attempts in _PATH_BTMP if that exists.
* The most common login failure is to give password instead of username.
* So the _PATH_BTMP file checked for the correct permission, so that
* only root can read it.
*/
/*
* Logs failed login attempts in _PATH_BTMP if that exists.
* The most common login failure is to give password instead of username.
* So the _PATH_BTMP file checked for the correct permission, so that only
* root can read it.
*/
void
record_failed_login(struct ssh *ssh, const char *username, const char *hostname,
const char *ttyn)
{
int fd;
struct utmp ut;
struct sockaddr_storage from;
socklen_t fromlen = sizeof(from);
struct sockaddr_in *a4;
struct sockaddr_in6 *a6;
struct logininfo li;
socklen_t fromlen = sizeof(li.hostaddr);
time_t t;
struct stat fst;
@ -1683,47 +1662,31 @@ record_failed_login(struct ssh *ssh, const char *username, const char *hostname,
strerror(errno));
goto out;
}
if((fst.st_mode & (S_IXGRP | S_IRWXO)) || (fst.st_uid != 0)){
if ((fst.st_mode & (S_IXGRP | S_IRWXO)) || fst.st_uid != 0) {
logit("Excess permission or bad ownership on file %s",
_PATH_BTMP);
goto out;
}
memset(&ut, 0, sizeof(ut));
/* strncpy because we don't necessarily want nul termination */
strncpy(ut.ut_user, username, sizeof(ut.ut_user));
strlcpy(ut.ut_line, "ssh:notty", sizeof(ut.ut_line));
/* Construct a logininfo and turn it into a utmp */
memset(&li, 0, sizeof(li));
li.type = LTYPE_LOGIN;
li.pid = getpid();
strlcpy(li.line, "ssh:notty", sizeof(li.line));
strlcpy(li.username, username, sizeof(li.username));
strlcpy(li.hostname, hostname, sizeof(li.hostname));
time(&t);
ut.ut_time = t; /* ut_time is not always a time_t */
ut.ut_type = LOGIN_PROCESS;
ut.ut_pid = getpid();
/* strncpy because we don't necessarily want nul termination */
strncpy(ut.ut_host, hostname, sizeof(ut.ut_host));
if (ssh_packet_connection_is_on_socket(ssh) &&
getpeername(ssh_packet_get_connection_in(ssh),
(struct sockaddr *)&from, &fromlen) == 0) {
ipv64_normalise_mapped(&from, &fromlen);
if (from.ss_family == AF_INET) {
a4 = (struct sockaddr_in *)&from;
memcpy(&ut.ut_addr, &(a4->sin_addr),
MIN_SIZEOF(ut.ut_addr, a4->sin_addr));
}
#ifdef HAVE_ADDR_V6_IN_UTMP
if (from.ss_family == AF_INET6) {
a6 = (struct sockaddr_in6 *)&from;
memcpy(&ut.ut_addr_v6, &(a6->sin6_addr),
MIN_SIZEOF(ut.ut_addr_v6, a6->sin6_addr));
}
#endif
li.tv_sec = t > 0 ? (unsigned long)t : 0;
if (ssh_packet_connection_is_on_socket(ssh)) {
(void)getpeername(ssh_packet_get_connection_in(ssh),
&li.hostaddr.sa, &fromlen);
}
construct_utmp(&li, &ut);
if (atomicio(vwrite, fd, &ut, sizeof(ut)) != sizeof(ut))
if (atomicio(vwrite, fd, &ut, sizeof(ut)) != sizeof(ut)) {
error("Failed to write to %s: %s", _PATH_BTMP,
strerror(errno));
}
out:
close(fd);
}