summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog23
-rw-r--r--key.c105
-rw-r--r--key.h5
-rw-r--r--readconf.c20
-rw-r--r--readconf.h6
-rw-r--r--ssh-keygen.19
-rw-r--r--ssh-keygen.c21
-rw-r--r--ssh_config.58
-rw-r--r--sshconnect.c26
9 files changed, 199 insertions, 24 deletions
diff --git a/ChangeLog b/ChangeLog
index 14eb11514..70d5baa58 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -3,6 +3,27 @@
3 - jmc@cvs.openbsd.org 2008/06/11 07:30:37 3 - jmc@cvs.openbsd.org 2008/06/11 07:30:37
4 [sshd.8] 4 [sshd.8]
5 kill trailing whitespace; 5 kill trailing whitespace;
6 - grunk@cvs.openbsd.org 2008/06/11 21:01:35
7 [ssh_config.5 key.h readconf.c readconf.h ssh-keygen.1 ssh-keygen.c key.c
8 sshconnect.c]
9 Introduce SSH Fingerprint ASCII Visualization, a technique inspired by the
10 graphical hash visualization schemes known as "random art", and by
11 Dan Kaminsky's musings on the subject during a BlackOp talk at the
12 23C3 in Berlin.
13 Scientific publication (original paper):
14 "Hash Visualization: a New Technique to improve Real-World Security",
15 Perrig A. and Song D., 1999, International Workshop on Cryptographic
16 Techniques and E-Commerce (CrypTEC '99)
17 http://sparrow.ece.cmu.edu/~adrian/projects/validation/validation.pdf
18 The algorithm used here is a worm crawling over a discrete plane,
19 leaving a trace (augmenting the field) everywhere it goes.
20 Movement is taken from dgst_raw 2bit-wise. Bumping into walls
21 makes the respective movement vector be ignored for this turn,
22 thus switching to the other color of the chessboard.
23 Graphs are not unambiguous for now, because circles in graphs can be
24 walked in either direction.
25 discussions with several people,
26 help, corrections and ok markus@ djm@
6 27
720080611 2820080611
8 - (djm) [channels.c configure.ac] 29 - (djm) [channels.c configure.ac]
@@ -4165,4 +4186,4 @@
4165 OpenServer 6 and add osr5bigcrypt support so when someone migrates 4186 OpenServer 6 and add osr5bigcrypt support so when someone migrates
4166 passwords between UnixWare and OpenServer they will still work. OK dtucker@ 4187 passwords between UnixWare and OpenServer they will still work. OK dtucker@
4167 4188
4168$Id: ChangeLog,v 1.4968 2008/06/12 18:32:00 dtucker Exp $ 4189$Id: ChangeLog,v 1.4969 2008/06/12 18:40:35 dtucker Exp $
diff --git a/key.c b/key.c
index 62bf8361d..5d357a8d6 100644
--- a/key.c
+++ b/key.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: key.c,v 1.69 2007/07/12 05:48:05 ray Exp $ */ 1/* $OpenBSD: key.c,v 1.70 2008/06/11 21:01:35 grunk Exp $ */
2/* 2/*
3 * read_bignum(): 3 * read_bignum():
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -35,6 +35,7 @@
35 35
36#include "includes.h" 36#include "includes.h"
37 37
38#include <sys/param.h>
38#include <sys/types.h> 39#include <sys/types.h>
39 40
40#include <openssl/evp.h> 41#include <openssl/evp.h>
@@ -295,6 +296,105 @@ key_fingerprint_bubblebabble(u_char *dgst_raw, u_int dgst_raw_len)
295 return retval; 296 return retval;
296} 297}
297 298
299/*
300 * Draw an ASCII-Art representing the fingerprint so human brain can
301 * profit from its built-in pattern recognition ability.
302 * This technique is called "random art" and can be found in some
303 * scientific publications like this original paper:
304 *
305 * "Hash Visualization: a New Technique to improve Real-World Security",
306 * Perrig A. and Song D., 1999, International Workshop on Cryptographic
307 * Techniques and E-Commerce (CrypTEC '99)
308 * sparrow.ece.cmu.edu/~adrian/projects/validation/validation.pdf
309 *
310 * The subject came up in a talk by Dan Kaminsky, too.
311 *
312 * If you see the picture is different, the key is different.
313 * If the picture looks the same, you still know nothing.
314 *
315 * The algorithm used here is a worm crawling over a discrete plane,
316 * leaving a trace (augmenting the field) everywhere it goes.
317 * Movement is taken from dgst_raw 2bit-wise. Bumping into walls
318 * makes the respective movement vector be ignored for this turn.
319 * Graphs are not unambiguous, because circles in graphs can be
320 * walked in either direction.
321 */
322#define FLDSIZE_Y 8
323#define FLDSIZE_X FLDSIZE_Y * 2
324static char *
325key_fingerprint_randomart(u_char *dgst_raw, u_int dgst_raw_len)
326{
327 /*
328 * Chars to be used after each other every time the worm
329 * intersects with itself. Matter of taste.
330 */
331 char *augmentation_string = " .o+=*BOX@%&#/^";
332 char *retval, *p;
333 char field[FLDSIZE_X][FLDSIZE_Y];
334 u_int i, b;
335 int x, y;
336
337 retval = xcalloc(1, (FLDSIZE_X + 3) * (FLDSIZE_Y + 2));
338
339 /* initialize field */
340 memset(field, ' ', FLDSIZE_X * FLDSIZE_Y * sizeof(char));
341 x = FLDSIZE_X / 2;
342 y = FLDSIZE_Y / 2;
343 field[x][y] = '.';
344
345 /* process raw key */
346 for (i = 0; i < dgst_raw_len; i++) {
347 int input;
348 /* each byte conveys four 2-bit move commands */
349 input = dgst_raw[i];
350 for (b = 0; b < 4; b++) {
351 /* evaluate 2 bit, rest is shifted later */
352 x += (input & 0x1) ? 1 : -1;
353 y += (input & 0x2) ? 1 : -1;
354
355 /* assure we are still in bounds */
356 x = MAX(x, 0);
357 y = MAX(y, 0);
358 x = MIN(x, FLDSIZE_X - 1);
359 y = MIN(y, FLDSIZE_Y - 1);
360
361 /* augment the field */
362 p = strchr(augmentation_string, field[x][y]);
363 if (*++p != '\0')
364 field[x][y] = *p;
365
366 input = input >> 2;
367 }
368 }
369
370 /* fill in retval */
371 p = retval;
372
373 /* output upper border */
374 *p++ = '+';
375 for (i = 0; i < FLDSIZE_X; i++)
376 *p++ = '-';
377 *p++ = '+';
378 *p++ = '\n';
379
380 /* output content */
381 for (y = 0; y < FLDSIZE_Y; y++) {
382 *p++ = '|';
383 for (x = 0; x < FLDSIZE_X; x++)
384 *p++ = field[x][y];
385 *p++ = '|';
386 *p++ = '\n';
387 }
388
389 /* output lower border */
390 *p++ = '+';
391 for (i = 0; i < FLDSIZE_X; i++)
392 *p++ = '-';
393 *p++ = '+';
394
395 return retval;
396}
397
298char * 398char *
299key_fingerprint(const Key *k, enum fp_type dgst_type, enum fp_rep dgst_rep) 399key_fingerprint(const Key *k, enum fp_type dgst_type, enum fp_rep dgst_rep)
300{ 400{
@@ -312,6 +412,9 @@ key_fingerprint(const Key *k, enum fp_type dgst_type, enum fp_rep dgst_rep)
312 case SSH_FP_BUBBLEBABBLE: 412 case SSH_FP_BUBBLEBABBLE:
313 retval = key_fingerprint_bubblebabble(dgst_raw, dgst_raw_len); 413 retval = key_fingerprint_bubblebabble(dgst_raw, dgst_raw_len);
314 break; 414 break;
415 case SSH_FP_RANDOMART:
416 retval = key_fingerprint_randomart(dgst_raw, dgst_raw_len);
417 break;
315 default: 418 default:
316 fatal("key_fingerprint_ex: bad digest representation %d", 419 fatal("key_fingerprint_ex: bad digest representation %d",
317 dgst_rep); 420 dgst_rep);
diff --git a/key.h b/key.h
index 6873dd793..14aac79c2 100644
--- a/key.h
+++ b/key.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: key.h,v 1.26 2006/08/03 03:34:42 deraadt Exp $ */ 1/* $OpenBSD: key.h,v 1.27 2008/06/11 21:01:35 grunk Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. 4 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
@@ -42,7 +42,8 @@ enum fp_type {
42}; 42};
43enum fp_rep { 43enum fp_rep {
44 SSH_FP_HEX, 44 SSH_FP_HEX,
45 SSH_FP_BUBBLEBABBLE 45 SSH_FP_BUBBLEBABBLE,
46 SSH_FP_RANDOMART
46}; 47};
47 48
48/* key is stored in external hardware */ 49/* key is stored in external hardware */
diff --git a/readconf.c b/readconf.c
index 3ddb4d392..1d61145c4 100644
--- a/readconf.c
+++ b/readconf.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: readconf.c,v 1.165 2008/01/19 23:09:49 djm Exp $ */ 1/* $OpenBSD: readconf.c,v 1.166 2008/06/11 21:01:35 grunk Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -452,7 +452,23 @@ parse_flag:
452 452
453 case oCheckHostIP: 453 case oCheckHostIP:
454 intptr = &options->check_host_ip; 454 intptr = &options->check_host_ip;
455 goto parse_flag; 455 arg = strdelim(&s);
456 if (!arg || *arg == '\0')
457 fatal("%.200s line %d: Missing CheckHostIP argument.",
458 filename, linenum);
459 value = 0; /* To avoid compiler warning... */
460 if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
461 value = SSHCTL_CHECKHOSTIP_YES;
462 else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
463 value = SSHCTL_CHECKHOSTIP_NO;
464 else if (strcmp(arg, "fingerprint") == 0)
465 value = SSHCTL_CHECKHOSTIP_FPR;
466 else
467 fatal("%.200s line %d: Bad CheckHostIP argument.",
468 filename, linenum);
469 if (*activep && *intptr == -1)
470 *intptr = value;
471 break;
456 472
457 case oVerifyHostKeyDNS: 473 case oVerifyHostKeyDNS:
458 intptr = &options->verify_host_key_dns; 474 intptr = &options->verify_host_key_dns;
diff --git a/readconf.h b/readconf.h
index 6257f4b2f..5c16a0ba6 100644
--- a/readconf.h
+++ b/readconf.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: readconf.h,v 1.72 2008/01/19 23:09:49 djm Exp $ */ 1/* $OpenBSD: readconf.h,v 1.73 2008/06/11 21:01:35 grunk Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -123,6 +123,10 @@ typedef struct {
123 123
124} Options; 124} Options;
125 125
126#define SSHCTL_CHECKHOSTIP_NO 0
127#define SSHCTL_CHECKHOSTIP_YES 1
128#define SSHCTL_CHECKHOSTIP_FPR 2
129
126#define SSHCTL_MASTER_NO 0 130#define SSHCTL_MASTER_NO 0
127#define SSHCTL_MASTER_YES 1 131#define SSHCTL_MASTER_YES 1
128#define SSHCTL_MASTER_AUTO 2 132#define SSHCTL_MASTER_AUTO 2
diff --git a/ssh-keygen.1 b/ssh-keygen.1
index 877935053..36249b288 100644
--- a/ssh-keygen.1
+++ b/ssh-keygen.1
@@ -1,4 +1,4 @@
1.\" $OpenBSD: ssh-keygen.1,v 1.75 2007/05/31 19:20:16 jmc Exp $ 1.\" $OpenBSD: ssh-keygen.1,v 1.76 2008/06/11 21:01:35 grunk Exp $
2.\" 2.\"
3.\" -*- nroff -*- 3.\" -*- nroff -*-
4.\" 4.\"
@@ -37,7 +37,7 @@
37.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 37.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
38.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 38.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39.\" 39.\"
40.Dd $Mdocdate: May 31 2007 $ 40.Dd $Mdocdate: June 11 2008 $
41.Dt SSH-KEYGEN 1 41.Dt SSH-KEYGEN 1
42.Os 42.Os
43.Sh NAME 43.Sh NAME
@@ -257,11 +257,12 @@ RFC 4716 SSH Public Key File Format.
257This option allows importing keys from several commercial 257This option allows importing keys from several commercial
258SSH implementations. 258SSH implementations.
259.It Fl l 259.It Fl l
260Show fingerprint of specified public key file. 260Show fingerprint and ASCII art representation of specified public key file.
261Private RSA1 keys are also supported. 261Private RSA1 keys are also supported.
262For RSA and DSA keys 262For RSA and DSA keys
263.Nm 263.Nm
264tries to find the matching public key file and prints its fingerprint. 264tries to find the matching public key file and prints its fingerprint
265and representation.
265.It Fl M Ar memory 266.It Fl M Ar memory
266Specify the amount of memory to use (in megabytes) when generating 267Specify the amount of memory to use (in megabytes) when generating
267candidate moduli for DH-GEX. 268candidate moduli for DH-GEX.
diff --git a/ssh-keygen.c b/ssh-keygen.c
index a03c6575d..c22e814da 100644
--- a/ssh-keygen.c
+++ b/ssh-keygen.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-keygen.c,v 1.166 2008/05/19 15:46:31 djm Exp $ */ 1/* $OpenBSD: ssh-keygen.c,v 1.167 2008/06/11 21:01:35 grunk Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -504,7 +504,7 @@ do_fingerprint(struct passwd *pw)
504{ 504{
505 FILE *f; 505 FILE *f;
506 Key *public; 506 Key *public;
507 char *comment = NULL, *cp, *ep, line[16*1024], *fp; 507 char *comment = NULL, *cp, *ep, line[16*1024], *fp, *ra;
508 int i, skip = 0, num = 0, invalid = 1; 508 int i, skip = 0, num = 0, invalid = 1;
509 enum fp_rep rep; 509 enum fp_rep rep;
510 enum fp_type fptype; 510 enum fp_type fptype;
@@ -522,9 +522,12 @@ do_fingerprint(struct passwd *pw)
522 public = key_load_public(identity_file, &comment); 522 public = key_load_public(identity_file, &comment);
523 if (public != NULL) { 523 if (public != NULL) {
524 fp = key_fingerprint(public, fptype, rep); 524 fp = key_fingerprint(public, fptype, rep);
525 ra = key_fingerprint(public, fptype, rep);
525 printf("%u %s %s\n", key_size(public), fp, comment); 526 printf("%u %s %s\n", key_size(public), fp, comment);
527 verbose("%s\n", ra);
526 key_free(public); 528 key_free(public);
527 xfree(comment); 529 xfree(comment);
530 xfree(ra);
528 xfree(fp); 531 xfree(fp);
529 exit(0); 532 exit(0);
530 } 533 }
@@ -582,8 +585,11 @@ do_fingerprint(struct passwd *pw)
582 } 585 }
583 comment = *cp ? cp : comment; 586 comment = *cp ? cp : comment;
584 fp = key_fingerprint(public, fptype, rep); 587 fp = key_fingerprint(public, fptype, rep);
588 ra = key_fingerprint(public, fptype, SSH_FP_RANDOMART);
585 printf("%u %s %s\n", key_size(public), fp, 589 printf("%u %s %s\n", key_size(public), fp,
586 comment ? comment : "no comment"); 590 comment ? comment : "no comment");
591 verbose("%s\n", ra);
592 xfree(ra);
587 xfree(fp); 593 xfree(fp);
588 key_free(public); 594 key_free(public);
589 invalid = 0; 595 invalid = 0;
@@ -603,12 +609,14 @@ print_host(FILE *f, const char *name, Key *public, int hash)
603 if (print_fingerprint) { 609 if (print_fingerprint) {
604 enum fp_rep rep; 610 enum fp_rep rep;
605 enum fp_type fptype; 611 enum fp_type fptype;
606 char *fp; 612 char *fp, *ra;
607 613
608 fptype = print_bubblebabble ? SSH_FP_SHA1 : SSH_FP_MD5; 614 fptype = print_bubblebabble ? SSH_FP_SHA1 : SSH_FP_MD5;
609 rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_HEX; 615 rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_HEX;
610 fp = key_fingerprint(public, fptype, rep); 616 fp = key_fingerprint(public, fptype, rep);
611 printf("%u %s %s\n", key_size(public), fp, name); 617 ra = key_fingerprint(public, fptype, SSH_FP_RANDOMART);
618 printf("%u %s %s\n%s\n", key_size(public), fp, name, ra);
619 xfree(ra);
612 xfree(fp); 620 xfree(fp);
613 } else { 621 } else {
614 if (hash && (name = host_hash(name, NULL, 0)) == NULL) 622 if (hash && (name = host_hash(name, NULL, 0)) == NULL)
@@ -1451,10 +1459,15 @@ passphrase_again:
1451 1459
1452 if (!quiet) { 1460 if (!quiet) {
1453 char *fp = key_fingerprint(public, SSH_FP_MD5, SSH_FP_HEX); 1461 char *fp = key_fingerprint(public, SSH_FP_MD5, SSH_FP_HEX);
1462 char *ra = key_fingerprint(public, SSH_FP_MD5,
1463 SSH_FP_RANDOMART);
1454 printf("Your public key has been saved in %s.\n", 1464 printf("Your public key has been saved in %s.\n",
1455 identity_file); 1465 identity_file);
1456 printf("The key fingerprint is:\n"); 1466 printf("The key fingerprint is:\n");
1457 printf("%s %s\n", fp, comment); 1467 printf("%s %s\n", fp, comment);
1468 printf("The key's randomart image is:\n");
1469 printf("%s\n", ra);
1470 xfree(ra);
1458 xfree(fp); 1471 xfree(fp);
1459 } 1472 }
1460 1473
diff --git a/ssh_config.5 b/ssh_config.5
index d6f3fbf80..28ac724c8 100644
--- a/ssh_config.5
+++ b/ssh_config.5
@@ -34,8 +34,8 @@
34.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
35.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36.\" 36.\"
37.\" $OpenBSD: ssh_config.5,v 1.106 2008/06/10 18:21:24 dtucker Exp $ 37.\" $OpenBSD: ssh_config.5,v 1.107 2008/06/11 21:01:35 grunk Exp $
38.Dd $Mdocdate: June 10 2008 $ 38.Dd $Mdocdate: June 11 2008 $
39.Dt SSH_CONFIG 5 39.Dt SSH_CONFIG 5
40.Os 40.Os
41.Sh NAME 41.Sh NAME
@@ -161,6 +161,10 @@ will additionally check the host IP address in the
161file. 161file.
162This allows ssh to detect if a host key changed due to DNS spoofing. 162This allows ssh to detect if a host key changed due to DNS spoofing.
163If the option is set to 163If the option is set to
164.Dq fingerprint ,
165not only the host IP address will be checked, but also an ASCII art
166representation of the key will be printed.
167If the option is set to
164.Dq no , 168.Dq no ,
165the check will not be executed. 169the check will not be executed.
166The default is 170The default is
diff --git a/sshconnect.c b/sshconnect.c
index a604c9724..151299614 100644
--- a/sshconnect.c
+++ b/sshconnect.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshconnect.c,v 1.203 2007/12/27 14:22:08 dtucker Exp $ */ 1/* $OpenBSD: sshconnect.c,v 1.204 2008/06/11 21:01:35 grunk Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -602,7 +602,7 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
602 Key *file_key; 602 Key *file_key;
603 const char *type = key_type(host_key); 603 const char *type = key_type(host_key);
604 char *ip = NULL, *host = NULL; 604 char *ip = NULL, *host = NULL;
605 char hostline[1000], *hostp, *fp; 605 char hostline[1000], *hostp, *fp, *ra;
606 HostStatus host_status; 606 HostStatus host_status;
607 HostStatus ip_status; 607 HostStatus ip_status;
608 int r, local = 0, host_ip_differ = 0; 608 int r, local = 0, host_ip_differ = 0;
@@ -740,6 +740,13 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
740 logit("Warning: Permanently added the %s host " 740 logit("Warning: Permanently added the %s host "
741 "key for IP address '%.128s' to the list " 741 "key for IP address '%.128s' to the list "
742 "of known hosts.", type, ip); 742 "of known hosts.", type, ip);
743 } else if (options.check_host_ip == SSHCTL_CHECKHOSTIP_FPR) {
744 fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX);
745 ra = key_fingerprint(host_key, SSH_FP_MD5,
746 SSH_FP_RANDOMART);
747 logit("Host key fingerprint is %s\n%s\n", fp, ra);
748 xfree(ra);
749 xfree(fp);
743 } 750 }
744 break; 751 break;
745 case HOST_NEW: 752 case HOST_NEW:
@@ -775,6 +782,8 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
775 snprintf(msg1, sizeof(msg1), "."); 782 snprintf(msg1, sizeof(msg1), ".");
776 /* The default */ 783 /* The default */
777 fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX); 784 fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX);
785 ra = key_fingerprint(host_key, SSH_FP_MD5,
786 SSH_FP_RANDOMART);
778 msg2[0] = '\0'; 787 msg2[0] = '\0';
779 if (options.verify_host_key_dns) { 788 if (options.verify_host_key_dns) {
780 if (matching_host_key_dns) 789 if (matching_host_key_dns)
@@ -789,10 +798,11 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
789 snprintf(msg, sizeof(msg), 798 snprintf(msg, sizeof(msg),
790 "The authenticity of host '%.200s (%s)' can't be " 799 "The authenticity of host '%.200s (%s)' can't be "
791 "established%s\n" 800 "established%s\n"
792 "%s key fingerprint is %s.\n%s" 801 "%s key fingerprint is %s.\n%s\n%s"
793 "Are you sure you want to continue connecting " 802 "Are you sure you want to continue connecting "
794 "(yes/no)? ", 803 "(yes/no)? ",
795 host, ip, msg1, type, fp, msg2); 804 host, ip, msg1, type, fp, ra, msg2);
805 xfree(ra);
796 xfree(fp); 806 xfree(fp);
797 if (!confirm(msg)) 807 if (!confirm(msg))
798 goto fail; 808 goto fail;
@@ -1063,18 +1073,20 @@ static int
1063show_key_from_file(const char *file, const char *host, int keytype) 1073show_key_from_file(const char *file, const char *host, int keytype)
1064{ 1074{
1065 Key *found; 1075 Key *found;
1066 char *fp; 1076 char *fp, *ra;
1067 int line, ret; 1077 int line, ret;
1068 1078
1069 found = key_new(keytype); 1079 found = key_new(keytype);
1070 if ((ret = lookup_key_in_hostfile_by_type(file, host, 1080 if ((ret = lookup_key_in_hostfile_by_type(file, host,
1071 keytype, found, &line))) { 1081 keytype, found, &line))) {
1072 fp = key_fingerprint(found, SSH_FP_MD5, SSH_FP_HEX); 1082 fp = key_fingerprint(found, SSH_FP_MD5, SSH_FP_HEX);
1083 ra = key_fingerprint(found, SSH_FP_MD5, SSH_FP_RANDOMART);
1073 logit("WARNING: %s key found for host %s\n" 1084 logit("WARNING: %s key found for host %s\n"
1074 "in %s:%d\n" 1085 "in %s:%d\n"
1075 "%s key fingerprint %s.", 1086 "%s key fingerprint %s.\n%s\n",
1076 key_type(found), host, file, line, 1087 key_type(found), host, file, line,
1077 key_type(found), fp); 1088 key_type(found), fp, ra);
1089 xfree(ra);
1078 xfree(fp); 1090 xfree(fp);
1079 } 1091 }
1080 key_free(found); 1092 key_free(found);