#include #include #include #include #include #include #include #include extern const char *__progname; #include "b64.h" #include "hkdb.h" #include "cmdline.h" const char *default_hkdb_path(void) { const char *d; char *p; d = get_sshdir("host key database"); asprintf(&p,"%s/known-hosts",d); return(p); } void check_host_key(HKALG *hk, const void *pkdata, int pklen) { void *h; unsigned char fp[16]; FILE *f; int c; int i; int j; void *b64; h = md5_init(); md5_process_bytes(h,pkdata,pklen); md5_result(h,&fp[0]); printf("host key fingerprint: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",fp[0],fp[1],fp[2],fp[3],fp[4],fp[5],fp[6],fp[7],fp[8],fp[9],fp[10],fp[11],fp[12],fp[13],fp[14],fp[15]); f = fopen(hostkeydb,"r"); if (f == 0) { fprintf(stderr,"%s: can't verify host key: can't open %s: %s\n",__progname,hostkeydb,strerror(errno)); return; } b64 = 0; while <"nextline"> (1) { do <"notfound"> { if (b64) b64r_done(b64); b64 = 0; c = getc(f); if (c == EOF) break <"notfound">; ungetc(c,f); do <"flushline"> { do <"syntax"> { do <"mismatch"> { for (i=0;host[i];i++) { c = getc(f); if (tolower(c) != tolower(host[i])) break <"flushline">; } c = getc(f); if (c != ' ') break <"flushline">; for (i=0;hk->name[i];i++) { c = getc(f); if (c != hk->name[i]) break <"flushline">; } c = getc(f); if (c != ' ') break <"flushline">; b64 = b64r_init(&b64_stdio_get,f); for (i=0;i; case B64R_ERR: break <"syntax">; } if (c != ((const unsigned char *)pkdata)[i]) break <"mismatch">; } c = b64r_get(b64); if (c != B64R_EOF) break <"mismatch">; b64r_done(b64); b64 = 0; c = getc(f); if (c != ' ') break <"syntax">; c = getc(f); if (c != '.') break <"syntax">; c = getc(f); if (c != '\n') break <"syntax">; printf("Host key matches\n"); break <"nextline">; } while (0); printf("\ * * * * * * * * * * * * *\n\ * *\n\ * HOST KEY MISMATCH!! *\n\ * *\n\ * * * * * * * * * * * * *\n\ "); printf("host:"); for (j=0;j (1) { c = b64r_get(b64); switch (c) { case B64R_EOF: break <"printloop">; case B64R_ERR: printf(" (err)"); break <"printloop">; default: printf(" %02x",c); break; } } break; } printf("\n"); break <"nextline">; } while (0); fprintf(stderr,"%s: syntax error in %s/%s entry in %s\n",__progname,host,hk->name,hostkeydb); } while (0); while <"flushing"> (1) { switch (c) { case '\n': case EOF: break <"flushing">; break; } c = getc(f); } if (c == EOF) break; continue <"nextline">; } while (0); printf("%s/%s not known",host,hk->name); if (savehostkey) { int fd; int n; char *buf; int bx; FILE *tf; void *w64; static int bufw(void *cookie __attribute__((__unused__)), const char *data, int len) { if (bx+len > n) abort(); bcopy(data,buf+bx,len); bx += len; return(len); } static void bufput(void *cookie __attribute__((__unused__)), int ch) { putc(ch,tf); } printf(" (recording it)\n"); fd = open(hostkeydb,O_WRONLY|O_APPEND,0); if (fd < 0) { fprintf(stderr,"%s: can't record host key: can't open %s for write: %s\n",__progname,hostkeydb,strerror(errno)); } else { n = strlen(host) + 1 + strlen(hk->name) + 1 + (((pklen+2)/3)*4) + 3; buf = malloc(n); bx = 0; tf = fwopen(0,bufw); fprintf(tf,"%s %s ",host,hk->name); w64 = b64w_init(bufput,0); for (i=0;i