Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package util-linux for openSUSE:Factory checked in at 2025-09-10 17:30:10 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/util-linux (Old) and /work/SRC/openSUSE:Factory/.util-linux.new.1977 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "util-linux" Wed Sep 10 17:30:10 2025 rev:301 rq:1303156 version:2.41.1 Changes: -------- --- /work/SRC/openSUSE:Factory/util-linux/util-linux.changes 2025-08-13 16:30:16.287798582 +0200 +++ /work/SRC/openSUSE:Factory/.util-linux.new.1977/util-linux.changes 2025-09-10 17:30:15.049556148 +0200 @@ -1,0 +2,9 @@ +Mon Aug 11 23:54:47 UTC 2025 - Stanislav Brabec <[email protected]> + +- Implement escape code for printing of ssh host keys in agetty + issue file (util-linux-agetty-ssh-host-keys.patch. +- Include fixes from + https://github.com/util-linux/util-linux/pull/3649 (jsc#PED-8734, + util-linux-lib-netlink.patch, util-linux-agetty-netlink.patch). + +------------------------------------------------------------------- New: ---- util-linux-agetty-ssh-host-keys.patch ----------(New B)---------- New:- Implement escape code for printing of ssh host keys in agetty issue file (util-linux-agetty-ssh-host-keys.patch. - Include fixes from ----------(New E)---------- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ util-linux.spec ++++++ --- /var/tmp/diff_new_pack.zLbROD/_old 2025-09-10 17:30:16.173603413 +0200 +++ /var/tmp/diff_new_pack.zLbROD/_new 2025-09-10 17:30:16.177603582 +0200 @@ -114,6 +114,8 @@ Patch6: util-linux-lib-netlink.patch # PATCH-FEATURE-UPSTREAM util-linux-agetty-netlink.patch boo1139983 jsc#PED-8734 [email protected] -- Implement netlink based IP address detection and issue reload. Patch7: util-linux-agetty-netlink.patch +# PATCH-FEATURE-OPENSUSE util-linux-agetty-ssh-host-keys.patch [email protected] -- Implement escape code for printing of ssh host keys in agetty issue file. +Patch8: util-linux-agetty-ssh-host-keys.patch BuildRequires: audit-devel BuildRequires: bc BuildRequires: binutils-devel ++++++ util-linux-agetty-netlink.patch ++++++ --- /var/tmp/diff_new_pack.zLbROD/_old 2025-09-10 17:30:16.325609805 +0200 +++ /var/tmp/diff_new_pack.zLbROD/_new 2025-09-10 17:30:16.337610310 +0200 @@ -1,8 +1,7 @@ -From 1ddc84875c150ca7c142adba9bfcd4bf4323a3c4 Mon Sep 17 00:00:00 2001 +From bf7c46ef9158f3baae6b637ebb73a24d8460d394 Mon Sep 17 00:00:00 2001 From: Stanislav Brabec <[email protected]> Date: Wed, 9 Jul 2025 14:35:28 +0200 Subject: [PATCH 2/2] agetty: Implement netlink based IP processing -References: https://github.com/util-linux/util-linux/pull/3649 The current \4 and \6 issue file escapes implementation is inferior. It uses get getifaddrs() to get a list of IP addresses. This function does not @@ -48,8 +47,8 @@ Signed-off-by: Stanislav Brabec <[email protected]> --- term-utils/agetty.8.adoc | 6 + - term-utils/agetty.c | 414 ++++++++++++++++++++++----------------- - 2 files changed, 244 insertions(+), 176 deletions(-) + term-utils/agetty.c | 417 ++++++++++++++++++++++----------------- + 2 files changed, 246 insertions(+), 177 deletions(-) diff --git a/term-utils/agetty.8.adoc b/term-utils/agetty.8.adoc index a33f12a3f..6670498f5 100644 @@ -69,7 +68,7 @@ Insert the baudrate of the current line. diff --git a/term-utils/agetty.c b/term-utils/agetty.c -index f65e511ca..1f5d937e4 100644 +index 5e564c4f0..c37417e1e 100644 --- a/term-utils/agetty.c +++ b/term-utils/agetty.c @@ -32,10 +32,7 @@ @@ -109,7 +108,15 @@ char *mem_old; #endif unsigned int do_tcsetattr : 1, -@@ -1603,81 +1603,7 @@ done: +@@ -364,6 +364,7 @@ int main(int argc, char **argv) + }; + struct issue issue = { + .mem = NULL, ++ .nl.fd = -1 + }; + char *login_argv[LOGIN_ARGV_MAX + 1]; + int login_argc = 0; +@@ -1603,81 +1604,7 @@ done: } #ifdef AGETTY_RELOAD @@ -192,7 +199,7 @@ { char buffer[sizeof(struct inotify_event) + NAME_MAX + 1]; fd_set rfds; -@@ -1711,9 +1637,9 @@ static int wait_for_term_input(int fd) +@@ -1711,9 +1638,9 @@ static int wait_for_term_input(int fd) FD_SET(inotify_fd, &rfds); nfds = max(nfds, inotify_fd); } @@ -205,7 +212,7 @@ } /* If waiting fails, just fall through, presumably reading input will fail */ -@@ -1725,9 +1651,10 @@ static int wait_for_term_input(int fd) +@@ -1725,9 +1652,10 @@ static int wait_for_term_input(int fd) } @@ -219,7 +226,7 @@ /* Just drain the inotify buffer */ } else if (inotify_fd >= 0 && FD_ISSET(inotify_fd, &rfds)) { -@@ -1937,11 +1864,44 @@ static void eval_issue_file(struct issue *ie, +@@ -1937,11 +1865,44 @@ static void eval_issue_file(struct issue *ie, struct options *op, struct termios *tp) { @@ -241,7 +248,7 @@ + netlink_groups = RTMGRP_IPV4_IFADDR | RTMGRP_IPV6_IFADDR; + + /* Already initialized? */ -+ if (ie->nl.fd) ++ if (ie->nl.fd >= 0) + goto skip; + /* Prepare netlink. */ + ul_nl_init(&(ie->nl)); @@ -261,13 +268,13 @@ + /* In case of any error, the addrq list is just empty, and we can use + * the code without any error checking. */ + ul_nl_close(&(ie->nl)); -+ ie->nl.fd = 0; ++ ie->nl.fd = -1; +skip: +#endif /* * The custom issue file or directory list specified by: * agetty --issue-file <path[:path]...> -@@ -1986,11 +1946,6 @@ static void eval_issue_file(struct issue *ie, +@@ -1986,11 +1947,6 @@ static void eval_issue_file(struct issue *ie, issuedir_read(ie, _PATH_SYSCONFSTATICDIR "/" _PATH_ISSUE_DIRNAME, op, tp); done: @@ -279,7 +286,16 @@ if (ie->output) { fclose(ie->output); ie->output = NULL; -@@ -2032,13 +1987,19 @@ again: +@@ -2002,7 +1958,7 @@ done: + */ + static void show_issue(struct options *op) + { +- struct issue ie = { .output = NULL }; ++ struct issue ie = { .output = NULL, .nl.fd = -1 }; + struct termios tp; + + memset(&tp, 0, sizeof(struct termios)); +@@ -2032,13 +1988,19 @@ again: puts(_("[press ENTER to login]")); #ifdef AGETTY_RELOAD /* reload issue */ @@ -293,15 +309,15 @@ - goto again; + { + /* TODO: Close to set netlink_groups again using pass 1 */ -+ /* if (ie->nl.fd) ul_nl_close(&(ie->nl)); -+ * ie->nl.fd = NULL; */ ++ /* if (ie->nl.fd >= 0) ul_nl_close(&(ie->nl)); ++ * ie->nl.fd = -1; */ + + goto again; + } } } #endif -@@ -2168,7 +2129,7 @@ static char *get_logname(struct issue *ie, struct options *op, struct termios *t +@@ -2168,7 +2130,7 @@ static char *get_logname(struct issue *ie, struct options *op, struct termios *t no_reload: #ifdef AGETTY_RELOAD @@ -310,16 +326,16 @@ /* refresh prompt -- discard input data, clear terminal * and call do_prompt() again */ -@@ -2177,6 +2138,8 @@ static char *get_logname(struct issue *ie, struct options *op, struct termios *t +@@ -2177,6 +2139,8 @@ static char *get_logname(struct issue *ie, struct options *op, struct termios *t eval_issue_file(ie, op, tp); if (!issue_is_changed(ie)) goto no_reload; -+ /* if (ie->nl.fd) ul_nl_close(&(ie->nl)); -+ * ie->nl.fd = NULL; */ ++ /* if (ie->nl.fd >= 0) ul_nl_close(&(ie->nl)); ++ * ie->nl.fd = -1; */ tcflush(STDIN_FILENO, TCIFLUSH); if ((op->flags & F_VCONSOLE) && (op->flags & F_NOCLEAR) == 0) -@@ -2576,92 +2539,170 @@ static void log_warn(const char *fmt, ...) +@@ -2576,92 +2540,170 @@ static void log_warn(const char *fmt, ...) va_end(ap); } @@ -560,7 +576,7 @@ } /* -@@ -2860,26 +2901,47 @@ static void output_special_char(struct issue *ie, +@@ -2860,26 +2902,47 @@ static void output_special_char(struct issue *ie, case '4': case '6': { ++++++ util-linux-agetty-ssh-host-keys.patch ++++++ >From 275a215e3ee02d8240d22b2bc61abcdd6b24c35f Mon Sep 17 00:00:00 2001 From: Stanislav Brabec <[email protected]> Date: Fri, 8 Aug 2025 02:39:28 +0200 Subject: [PATCH] agetty: Implement \k: print ssh host keys Implement new keyword \k that will print all ssh host keys. Signed-off-by: Stanislav Brabec <[email protected]> --- term-utils/agetty.8.adoc | 3 +++ term-utils/agetty.c | 56 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/term-utils/agetty.8.adoc b/term-utils/agetty.8.adoc index 6670498f5..f84ec2e1e 100644 --- a/term-utils/agetty.8.adoc +++ b/term-utils/agetty.8.adoc @@ -304,6 +304,9 @@ Insert the string "1 user" or "<n> users" where <n> is the number of current use v:: Insert the version of the OS, that is, the build-date and such. +k:: +Print host ssh keys. + An example. On my system, the following _/etc/issue_ file: .... diff --git a/term-utils/agetty.c b/term-utils/agetty.c index c37417e1e..d53882ef7 100644 --- a/term-utils/agetty.c +++ b/term-utils/agetty.c @@ -33,6 +33,7 @@ #include <grp.h> #include <pwd.h> #include <netdb.h> +#include <glob.h> #include <sys/utsname.h> #include "strutils.h" @@ -2706,6 +2707,58 @@ static void dump_iface_all(struct issue *ie, fputs("\n", ie->output); } +#define SSH_KEYGEN_BUFFER_SIZE 512 +void print_ssh_keys(FILE *fd) { + glob_t glob_result; + int rc; + + rc = glob("/etc/ssh/ssh_host_*_key.pub", 0, NULL, &glob_result); + if (rc != 0) { + if (rc == GLOB_NOMATCH) { + fprintf(fd, _("No SSH host keys found.\n")); + } + globfree(&glob_result); + return; + } + + for (size_t i = 0; i < glob_result.gl_pathc; i++) { + int pipefd[2]; + pid_t pid; + + if (pipe(pipefd) == -1) { + continue; + } + pid = fork(); + if (pid == -1) { + close(pipefd[0]); + close(pipefd[1]); + continue; + } + if (pid == 0) { + char *argv[] = {"ssh-keygen", "-l", "-f", glob_result.gl_pathv[i], NULL}; + + close(pipefd[0]); + dup2(pipefd[1], STDOUT_FILENO); + close(pipefd[1]); + execvp("ssh-keygen", argv); + return; + } else { + char buffer[SSH_KEYGEN_BUFFER_SIZE]; + + close(pipefd[1]); + wait(NULL); + if (fgets(buffer, sizeof(buffer), fdopen(pipefd[0], "r")) != NULL) { + char field2[SSH_KEYGEN_BUFFER_SIZE], field4[SSH_KEYGEN_BUFFER_SIZE]; + if (sscanf(buffer, "%*s %s %*s %s", field2, field4) == 2) { + fprintf(fd, _("SSH host key: %s %s\n"), field2, field4); + } + } + close(pipefd[0]); + } + } + globfree(&glob_result); + return; +} /* * parses \x{argument}, if not argument specified then returns NULL, the @fd * has to point to one char after the sequence (it means '{'). @@ -2944,6 +2997,9 @@ static void output_special_char(struct issue *ie, } break; #endif + case 'k': + print_ssh_keys(ie->output); + break; default: putc(c, ie->output); break; -- 2.48.1 ++++++ util-linux-lib-netlink.patch ++++++ --- /var/tmp/diff_new_pack.zLbROD/_old 2025-09-10 17:30:16.361611319 +0200 +++ /var/tmp/diff_new_pack.zLbROD/_new 2025-09-10 17:30:16.365611488 +0200 @@ -1,8 +1,7 @@ -From 7d11ab55ce140cb03ffebb55856c0a766853d83e Mon Sep 17 00:00:00 2001 +From 02b917ba6fa43908a39f15c9496de04910044c0e Mon Sep 17 00:00:00 2001 From: Stanislav Brabec <[email protected]> Date: Wed, 9 Jul 2025 14:29:10 +0200 Subject: [PATCH 1/2] New netlink library -References: https://github.com/util-linux/util-linux/pull/3649 To support netlink and IP address processing, two new library files were added: @@ -18,13 +17,13 @@ Signed-off-by: Stanislav Brabec <[email protected]> --- include/Makemodule.am | 2 + - include/netaddrq.h | 124 +++++++ + include/netaddrq.h | 124 ++++++++ include/netlink.h | 171 ++++++++++ lib/Makemodule.am | 11 + lib/meson.build | 2 + - lib/netaddrq.c | 729 ++++++++++++++++++++++++++++++++++++++++++ + lib/netaddrq.c | 716 ++++++++++++++++++++++++++++++++++++++++++ lib/netlink.c | 465 +++++++++++++++++++++++++++ - 7 files changed, 1504 insertions(+) + 7 files changed, 1491 insertions(+) create mode 100644 include/netaddrq.h create mode 100644 include/netlink.h create mode 100644 lib/netaddrq.c @@ -406,10 +405,10 @@ randutils.c diff --git a/lib/netaddrq.c b/lib/netaddrq.c new file mode 100644 -index 000000000..11730cf07 +index 000000000..67a43cb85 --- /dev/null +++ b/lib/netaddrq.c -@@ -0,0 +1,729 @@ +@@ -0,0 +1,716 @@ +/* + * Netlink address quality rating list builder + * @@ -503,7 +502,7 @@ + +#define DBG_CASE(x) case x: str = #x; break +#define DBG_CASE_DEF8(x) default: snprintf(strx+2, 3, "%02hhx", x); str = strx; break -+static char *ip_rating(enum ul_netaddrq_ip_rating q) ++static char *ip_rating_as_string(enum ul_netaddrq_ip_rating q) +{ + char *str; + static char strx[5] = "0x"; @@ -565,11 +564,7 @@ + DBG(LIST, ul_debugobj(addrq, + "new ifa_index in addrq")); + if (!(ifaceq = malloc(sizeof(struct ul_netaddrq_iface)))) -+ { -+ DBG(LIST, ul_debugobj(addrq, -+ "malloc() 1 failed")); -+ return -1; -+ } ++ return -ENOMEM; + INIT_LIST_HEAD(&(ifaceq->ip_quality_list_4)); + INIT_LIST_HEAD(&(ifaceq->ip_quality_list_6)); + ifaceq->ifa_index = nl->addr.ifa_index; @@ -602,7 +597,7 @@ + list_for_each(li, ipq_list) { + ipq = list_entry(li, struct ul_netaddrq_ip, entry); + if (ipq->addr->address_len == nl->addr.address_len) -+ if (memcmp(ipq->addr->address, nl->addr.address, ++ if (!memcmp(ipq->addr->address, nl->addr.address, + nl->addr.address_len)) + break; + } @@ -618,17 +613,13 @@ + + addr = ul_nl_addr_dup(&(nl->addr)); + if (!addr) { -+ DBG(LIST, ul_debugobj(addrq, -+ "ul_nl_addr_dup() failed")); -+ rc = -1; ++ rc = -ENOMEM; + goto error; + } + if (ipq == NULL) { + if (!(ipq = malloc(sizeof(struct ul_netaddrq_ip)))) + { -+ DBG(LIST, ul_debugobj(addrq, -+ "malloc() 3 failed")); -+ rc = -1; ++ rc = -ENOMEM; + ul_nl_addr_free(addr); + goto error; + } @@ -645,7 +636,7 @@ + DBG(ADDRQ, + ul_debugobj(addrq, "%s rating: %s", + ul_nl_addr_ntop_address(&(nl->addr)), -+ ip_rating(ipq->quality))); ++ ip_rating_as_string(ipq->quality))); + } else { + /* UL_NL_RTM_DEL */ + if (ipq == NULL) @@ -689,18 +680,14 @@ + struct ul_netaddrq_data *addrq; + + netaddrq_init_debug(); -+ if (!(nl->data_addr = malloc(sizeof(struct ul_netaddrq_data)))) -+ return -1; ++ if (!(nl->data_addr = calloc(1, sizeof(struct ul_netaddrq_data)))) ++ return -ENOMEM; + nl->callback_addr = callback_addrq; + addrq = UL_NETADDRQ_DATA(nl); + addrq->callback_pre = callback_pre; + addrq->callback_post = callback_post; + addrq->callback_data = data; -+ addrq->nifaces = 0; -+ addrq->overflow = false; + INIT_LIST_HEAD(&(addrq->ifaces)); -+ addrq->ifaces_change_4 = false; -+ addrq->ifaces_change_6 = false; + DBG(LIST, ul_debugobj(addrq, "callback initialized")); + return 0; +} @@ -725,7 +712,7 @@ + DBG(BEST, + ul_debugobj((*best), "%s -> best[%s]", + ul_nl_addr_ntop_address(ipq->addr), -+ ip_rating(ipq->quality))); ++ ip_rating_as_string(ipq->quality))); + (*best)[ipq->quality] = ipq; + } + @@ -733,7 +720,7 @@ + { + threshold = ipq->quality; + DBG(BEST, -+ ul_debug("threshold %s", ip_rating(threshold))); ++ ul_debug("threshold %s", ip_rating_as_string(threshold))); + + } + } @@ -793,8 +780,7 @@ + *threshold = ul_netaddrq_bestaddr(nl, best_ifaceq, &best, ifa_family); + if (best[*threshold]) + return ul_nl_addr_ntop_address(best[*threshold]->addr); -+ else -+ return NULL; ++ return NULL; +} + +struct ul_netaddrq_iface *ul_netaddrq_iface_by_name(const struct ul_nl_data *nl, @@ -1141,7 +1127,7 @@ +#endif /* TEST_PROGRAM_NETADDRQ */ diff --git a/lib/netlink.c b/lib/netlink.c new file mode 100644 -index 000000000..c57be4ce0 +index 000000000..fbe04dd4c --- /dev/null +++ b/lib/netlink.c @@ -0,0 +1,465 @@ @@ -1373,7 +1359,7 @@ + +int ul_nl_process(struct ul_nl_data *nl, bool async, bool loop) +{ -+ char buf[4096]; ++ char buf[BUFSIZ]; + struct sockaddr_nl snl; + struct nlmsghdr *nh; + int rc; @@ -1476,20 +1462,21 @@ + +struct ul_nl_addr *ul_nl_addr_dup (struct ul_nl_addr *addr) { + struct ul_nl_addr *newaddr; -+ newaddr = malloc(sizeof(struct ul_nl_addr)); -+ if (!newaddr) goto error1; ++ newaddr = calloc(1, sizeof(struct ul_nl_addr)); ++ if (!newaddr) ++ goto error; + memcpy(newaddr, addr, sizeof(struct ul_nl_addr)); + if (addr->ifa_address_len) { + newaddr->ifa_address = malloc(addr->ifa_address_len); + if (!newaddr->ifa_address) -+ goto error2; ++ goto error; + memcpy(newaddr->ifa_address, addr->ifa_address, + addr->ifa_address_len); + } + if (addr->ifa_local_len) { + newaddr->ifa_local = malloc(addr->ifa_local_len); + if (!newaddr->ifa_local) -+ goto error3; ++ goto error; + memcpy(newaddr->ifa_local, addr->ifa_local, + addr->ifa_local_len); + } @@ -1497,22 +1484,21 @@ + newaddr->address = newaddr->ifa_local; + else + newaddr->address = newaddr->ifa_address; -+ if ((newaddr->ifname = strdup(addr->ifname))) -+ return newaddr; -+ free(newaddr->ifa_local); -+error3: -+ free(newaddr->ifa_address); -+error2: -+ free(newaddr); -+error1: ++ if (!(newaddr->ifname = strdup(addr->ifname))) ++ goto error; ++ return newaddr; ++error: ++ ul_nl_addr_free(newaddr); + return NULL; +} + +void ul_nl_addr_free (struct ul_nl_addr *addr) { -+ free(addr->ifa_address); -+ free(addr->ifa_local); -+ free(addr->ifname); -+ free(addr); ++ if (addr) { ++ free(addr->ifa_address); ++ free(addr->ifa_local); ++ free(addr->ifname); ++ free(addr); ++ } +} + +const char *ul_nl_addr_ntop (const struct ul_nl_addr *addr, int addrid) {
