diff options
Diffstat (limited to 'main/dropbear/dropbear-fix-utmp.patch')
-rw-r--r-- | main/dropbear/dropbear-fix-utmp.patch | 157 |
1 files changed, 157 insertions, 0 deletions
diff --git a/main/dropbear/dropbear-fix-utmp.patch b/main/dropbear/dropbear-fix-utmp.patch new file mode 100644 index 00000000000..b06b8a41666 --- /dev/null +++ b/main/dropbear/dropbear-fix-utmp.patch @@ -0,0 +1,157 @@ +diff --git a/loginrec.c b/loginrec.c +index af10d95..9e5c3aa 100644 +--- a/src/loginrec.c ++++ b/src/loginrec.c +@@ -239,6 +239,13 @@ logininfo *login_alloc_entry(int pid, const char *username, + + newli = (struct logininfo *) m_malloc (sizeof(*newli)); + (void)login_init_entry(newli, pid, username, hostname, line); ++#ifdef HAVE_STRUCT_SOCKADDR_IN6 ++ if (inet_pton(AF_INET6, hostname, newli->hostaddr.sa_in6.sin6_addr.s6_addr) > 0) ++ newli->hostaddr.sa_in6.sin6_family = AF_INET6; ++ else ++#endif ++ if (inet_pton(AF_INET, hostname, &newli->hostaddr.sa_in.sin_addr.s_addr) > 0) ++ newli->hostaddr.sa_in.sin_family = AF_INET; + return newli; + } + +@@ -473,9 +480,6 @@ void + construct_utmp(struct logininfo *li, + struct utmp *ut) + { +-# ifdef HAVE_ADDR_V6_IN_UTMP +- struct sockaddr_in6 *sa6; +-# endif + memset(ut, '\0', sizeof(*ut)); + + /* First fill out fields used for both logins and logouts */ +@@ -528,12 +532,11 @@ construct_utmp(struct logininfo *li, + if (li->hostaddr.sa.sa_family == AF_INET) + ut->ut_addr = li->hostaddr.sa_in.sin_addr.s_addr; + # endif +-# ifdef HAVE_ADDR_V6_IN_UTMP ++# if defined(HAVE_STRUCT_UTMP_UT_ADDR_V6) && defined(HAVE_STRUCT_SOCKADDR_IN6) + /* this is just a 128-bit IPv6 address */ + if (li->hostaddr.sa.sa_family == AF_INET6) { +- sa6 = ((struct sockaddr_in6 *)&li->hostaddr.sa); +- memcpy(ut->ut_addr_v6, sa6->sin6_addr.s6_addr, 16); +- if (IN6_IS_ADDR_V4MAPPED(&sa6->sin6_addr)) { ++ memcpy(ut->ut_addr_v6, li->hostaddr.sa_in6.sin6_addr.s6_addr, 16); ++ if (IN6_IS_ADDR_V4MAPPED(&li->hostaddr.sa_in6.sin6_addr)) { + ut->ut_addr_v6[0] = ut->ut_addr_v6[3]; + ut->ut_addr_v6[1] = 0; + ut->ut_addr_v6[2] = 0; +@@ -569,9 +572,6 @@ set_utmpx_time(struct logininfo *li, struct utmpx *utx) + void + construct_utmpx(struct logininfo *li, struct utmpx *utx) + { +-# ifdef HAVE_ADDR_V6_IN_UTMP +- struct sockaddr_in6 *sa6; +-# endif + memset(utx, '\0', sizeof(*utx)); + # ifdef HAVE_STRUCT_UTMPX_UT_ID + line_abbrevname(utx->ut_id, li->line, sizeof(utx->ut_id)); +@@ -589,8 +589,6 @@ construct_utmpx(struct logininfo *li, struct utmpx *utx) + line_stripname(utx->ut_line, li->line, sizeof(utx->ut_line)); + set_utmpx_time(li, utx); + utx->ut_pid = li->pid; +- /* strncpy(): Don't necessarily want null termination */ +- strncpy(utx->ut_name, li->username, MIN_SIZEOF(utx->ut_name, li->username)); + + if (li->type == LTYPE_LOGOUT) + return; +@@ -600,6 +598,9 @@ construct_utmpx(struct logininfo *li, struct utmpx *utx) + * for logouts. + */ + ++ /* strncpy(): Don't necessarily want null termination */ ++ strncpy(utx->ut_name, li->username, MIN_SIZEOF(utx->ut_name, li->username)); ++ + # ifdef HAVE_STRUCT_UTMPX_UT_HOST + strncpy(utx->ut_host, li->hostname, MIN_SIZEOF(utx->ut_host, li->hostname)); + # endif +@@ -608,16 +609,15 @@ construct_utmpx(struct logininfo *li, struct utmpx *utx) + if (li->hostaddr.sa.sa_family == AF_INET) + utx->ut_addr = li->hostaddr.sa_in.sin_addr.s_addr; + # endif +-# ifdef HAVE_ADDR_V6_IN_UTMP ++# if defined(HAVE_STRUCT_UTMPX_UT_ADDR_V6) && defined(HAVE_STRUCT_SOCKADDR_IN6) + /* this is just a 128-bit IPv6 address */ + if (li->hostaddr.sa.sa_family == AF_INET6) { +- sa6 = ((struct sockaddr_in6 *)&li->hostaddr.sa); +- memcpy(ut->ut_addr_v6, sa6->sin6_addr.s6_addr, 16); +- if (IN6_IS_ADDR_V4MAPPED(&sa6->sin6_addr)) { +- ut->ut_addr_v6[0] = ut->ut_addr_v6[3]; +- ut->ut_addr_v6[1] = 0; +- ut->ut_addr_v6[2] = 0; +- ut->ut_addr_v6[3] = 0; ++ memcpy(utx->ut_addr_v6, li->hostaddr.sa_in6.sin6_addr.s6_addr, 16); ++ if (IN6_IS_ADDR_V4MAPPED(&li->hostaddr.sa_in6.sin6_addr)) { ++ utx->ut_addr_v6[0] = utx->ut_addr_v6[3]; ++ utx->ut_addr_v6[1] = 0; ++ utx->ut_addr_v6[2] = 0; ++ utx->ut_addr_v6[3] = 0; + } + } + # endif +@@ -1047,30 +1047,12 @@ wtmp_get_entry(struct logininfo *li) + **/ + + #ifdef USE_WTMPX +-/* write a wtmpx entry direct to the end of the file */ +-/* This is a slight modification of code in OpenBSD's logwtmp.c */ ++/* write a wtmpx entry via updwtmpx() */ + static int + wtmpx_write(struct logininfo *li, struct utmpx *utx) + { +- struct stat buf; +- int fd, ret = 1; +- +- if ((fd = open(WTMPX_FILE, O_WRONLY|O_APPEND, 0)) < 0) { +- dropbear_log(LOG_WARNING, "wtmpx_write: problem opening %s: %s", +- WTMPX_FILE, strerror(errno)); +- return 0; +- } +- +- if (fstat(fd, &buf) == 0) +- if (atomicio(vwrite, fd, utx, sizeof(*utx)) != sizeof(*utx)) { +- ftruncate(fd, buf.st_size); +- dropbear_log(LOG_WARNING, "wtmpx_write: problem writing %s: %s", +- WTMPX_FILE, strerror(errno)); +- ret = 0; +- } +- (void)close(fd); +- +- return ret; ++ updwtmpx(WTMPX_FILE, utx); ++ return 1; + } + + +diff --git a/loginrec.h b/loginrec.h +index b2e3778..f594ad7 100644 +--- a/src/loginrec.h ++++ b/src/loginrec.h +@@ -105,6 +105,9 @@ + union login_netinfo { + struct sockaddr sa; + struct sockaddr_in sa_in; ++#ifdef HAVE_STRUCT_SOCKADDR_IN6 ++ struct sockaddr_in6 sa_in6; ++#endif + #ifdef HAVE_STRUCT_SOCKADDR_STORAGE + struct sockaddr_storage sa_storage; + #endif +diff --git a/svr-chansession.c b/svr-chansession.c +index 656a968..bb4536c 100644 +--- a/src/svr-chansession.c ++++ b/src/svr-chansession.c +@@ -850,6 +850,7 @@ static int ptycommand(struct Channel *channel, struct ChanSess *chansess) { + * terminal used for stdout with the dup2 above, otherwise + * the wtmp login will not be recorded */ + li = chansess_login_alloc(chansess); ++ li->pid = getpid(); + login_login(li); + login_free_entry(li); + |