]> git.ipfire.org Git - thirdparty/openssh-portable.git/commitdiff
use construct_utmp to construct btmp records
authorDamien Miller <djm@mindrot.org>
Sun, 15 Sep 2024 02:53:59 +0000 (12:53 +1000)
committerDamien Miller <djm@mindrot.org>
Sun, 15 Sep 2024 02:53:59 +0000 (12:53 +1000)
Simpler and removes some code with the old-style BSD license.

loginrec.c

index 4f21499586afc5d87f2d28f639cb725e366cd25e..7460bb2c0329ad1ffea4e03a66b9f3ec6ef0d07d 100644 (file)
  * 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);
 }