File util-linux-agetty-ssh-host-keys.patch of Package util-linux

From 275a215e3ee02d8240d22b2bc61abcdd6b24c35f Mon Sep 17 00:00:00 2001
From: Stanislav Brabec <sbrabec@suse.cz>
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 <sbrabec@suse.cz>
---
 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

openSUSE Build Service is sponsored by