From 275a215e3ee02d8240d22b2bc61abcdd6b24c35f Mon Sep 17 00:00:00 2001 From: Stanislav Brabec 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 --- 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 " users" where 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 #include #include +#include #include #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