From 8c710dddc585022ad6503d0bfb3eb7291b6ef05c Mon Sep 17 00:00:00 2001 From: Simon Tatham Date: Sun, 24 Mar 2019 14:06:17 +0000 Subject: [PATCH] cgtest: update OpenSSH fingerprinting mechanism. We can only get fingerprints compatible with our own system by passing the '-E md5' option to ssh-keygen. Also, we must strip the "MD5:" prefix from the hash component of the returned fingerprint. Since that hash appears in the middle of the string we were previously extracting, I've reworked the whole cleanup_fp function to use the new ptrlen_get_word, which makes it easy to extract two words from the string and then strip a prefix off the second one. --- cmdgen.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/cmdgen.c b/cmdgen.c index e1ff0ec8..4d6d9e4e 100644 --- a/cmdgen.c +++ b/cmdgen.c @@ -1214,19 +1214,21 @@ void filecmp(char *file1, char *file2, char *fmt, ...) char *cleanup_fp(char *s) { - char *p; + ptrlen pl = ptrlen_from_asciz(s); + static const char separators[] = " \n\t"; - if (!strncmp(s, "ssh-", 4)) { - s += strcspn(s, " \n\t"); - s += strspn(s, " \n\t"); - } + /* Skip initial key type word if we find one */ + if (ptrlen_startswith(pl, PTRLEN_LITERAL("ssh-"), NULL)) + ptrlen_get_word(&pl, separators); - p = s; - s += strcspn(s, " \n\t"); - s += strspn(s, " \n\t"); - s += strcspn(s, " \n\t"); + /* Expect two words giving the key length and the hash */ + ptrlen bits = ptrlen_get_word(&pl, separators); + ptrlen hash = ptrlen_get_word(&pl, separators); - return dupprintf("%.*s", (int)(s - p), p); + /* Strip "MD5:" prefix if it's present, and do nothing if it isn't */ + ptrlen_startswith(hash, PTRLEN_LITERAL("MD5:"), &hash); + + return dupprintf("%.*s %.*s", PTRLEN_PRINTF(bits), PTRLEN_PRINTF(hash)); } char *get_fp(char *filename) @@ -1316,7 +1318,7 @@ int main(int argc, char **argv) { char *cmdbuf; fp = NULL; - cmdbuf = dupprintf("ssh-keygen -l -f '%s' > '%s'", + cmdbuf = dupprintf("ssh-keygen -E md5 -l -f '%s' > '%s'", pubfilename, tmpfilename1); if (system(cmdbuf) || (fp = get_fp(tmpfilename1)) == NULL) {