- grunk@cvs.openbsd.org 2008/06/11 21:01:35
     [ssh_config.5 key.h readconf.c readconf.h ssh-keygen.1 ssh-keygen.c key.c
      sshconnect.c]
     Introduce SSH Fingerprint ASCII Visualization, a technique inspired by the
     graphical hash visualization schemes known as "random art", and by
     Dan Kaminsky's musings on the subject during a BlackOp talk at the
     23C3 in Berlin.
     Scientific publication (original paper):
     "Hash Visualization: a New Technique to improve Real-World Security",
     Perrig A. and Song D., 1999, International Workshop on Cryptographic
     Techniques and E-Commerce (CrypTEC '99)
     http://sparrow.ece.cmu.edu/~adrian/projects/validation/validation.pdf
     The algorithm used here is a worm crawling over a discrete plane,
     leaving a trace (augmenting the field) everywhere it goes.
     Movement is taken from dgst_raw 2bit-wise.  Bumping into walls
     makes the respective movement vector be ignored for this turn,
     thus switching to the other color of the chessboard.
     Graphs are not unambiguous for now, because circles in graphs can be
     walked in either direction.
     discussions with several people,
     help, corrections and ok markus@ djm@
diff --git a/sshconnect.c b/sshconnect.c
index a604c97..1512996 100644
--- a/sshconnect.c
+++ b/sshconnect.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshconnect.c,v 1.203 2007/12/27 14:22:08 dtucker Exp $ */
+/* $OpenBSD: sshconnect.c,v 1.204 2008/06/11 21:01:35 grunk Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -602,7 +602,7 @@
 	Key *file_key;
 	const char *type = key_type(host_key);
 	char *ip = NULL, *host = NULL;
-	char hostline[1000], *hostp, *fp;
+	char hostline[1000], *hostp, *fp, *ra;
 	HostStatus host_status;
 	HostStatus ip_status;
 	int r, local = 0, host_ip_differ = 0;
@@ -740,6 +740,13 @@
 				logit("Warning: Permanently added the %s host "
 				    "key for IP address '%.128s' to the list "
 				    "of known hosts.", type, ip);
+		} else if (options.check_host_ip == SSHCTL_CHECKHOSTIP_FPR) {
+			fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX);
+			ra = key_fingerprint(host_key, SSH_FP_MD5,
+			    SSH_FP_RANDOMART);
+			logit("Host key fingerprint is %s\n%s\n", fp, ra);
+			xfree(ra);
+			xfree(fp);
 		}
 		break;
 	case HOST_NEW:
@@ -775,6 +782,8 @@
 				snprintf(msg1, sizeof(msg1), ".");
 			/* The default */
 			fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX);
+			ra = key_fingerprint(host_key, SSH_FP_MD5,
+			    SSH_FP_RANDOMART);
 			msg2[0] = '\0';
 			if (options.verify_host_key_dns) {
 				if (matching_host_key_dns)
@@ -789,10 +798,11 @@
 			snprintf(msg, sizeof(msg),
 			    "The authenticity of host '%.200s (%s)' can't be "
 			    "established%s\n"
-			    "%s key fingerprint is %s.\n%s"
+			    "%s key fingerprint is %s.\n%s\n%s"
 			    "Are you sure you want to continue connecting "
 			    "(yes/no)? ",
-			    host, ip, msg1, type, fp, msg2);
+			    host, ip, msg1, type, fp, ra, msg2);
+			xfree(ra);
 			xfree(fp);
 			if (!confirm(msg))
 				goto fail;
@@ -1063,18 +1073,20 @@
 show_key_from_file(const char *file, const char *host, int keytype)
 {
 	Key *found;
-	char *fp;
+	char *fp, *ra;
 	int line, ret;
 
 	found = key_new(keytype);
 	if ((ret = lookup_key_in_hostfile_by_type(file, host,
 	    keytype, found, &line))) {
 		fp = key_fingerprint(found, SSH_FP_MD5, SSH_FP_HEX);
+		ra = key_fingerprint(found, SSH_FP_MD5, SSH_FP_RANDOMART);
 		logit("WARNING: %s key found for host %s\n"
 		    "in %s:%d\n"
-		    "%s key fingerprint %s.",
+		    "%s key fingerprint %s.\n%s\n",
 		    key_type(found), host, file, line,
-		    key_type(found), fp);
+		    key_type(found), fp, ra);
+		xfree(ra);
 		xfree(fp);
 	}
 	key_free(found);