11305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* $OpenBSD: hostfile.c,v 1.50 2010/12/04 13:31:37 djm Exp $ */ 21305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 31305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Author: Tatu Ylonen <ylo@cs.hut.fi> 41305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 51305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * All rights reserved 61305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Functions for manipulating the known hosts files. 71305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 81305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * As far as I am concerned, the code I have written for this software 91305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * can be used freely for any purpose. Any derived versions of this 101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * software must be clearly marked as such, and if the derived work is 111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * incompatible with the protocol description in the RFC file, it must be 121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * called by a name other than "ssh" or "Secure Shell". 131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Copyright (c) 1999, 2000 Markus Friedl. All rights reserved. 161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Copyright (c) 1999 Niels Provos. All rights reserved. 171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Redistribution and use in source and binary forms, with or without 191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * modification, are permitted provided that the following conditions 201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * are met: 211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 1. Redistributions of source code must retain the above copyright 221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * notice, this list of conditions and the following disclaimer. 231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 2. Redistributions in binary form must reproduce the above copyright 241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * notice, this list of conditions and the following disclaimer in the 251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * documentation and/or other materials provided with the distribution. 261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "includes.h" 401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <sys/types.h> 421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <netinet/in.h> 441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <openssl/hmac.h> 461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <openssl/sha.h> 471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <resolv.h> 491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <stdarg.h> 501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <stdio.h> 511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <stdlib.h> 521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <string.h> 531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "xmalloc.h" 551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "match.h" 561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "key.h" 571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "hostfile.h" 581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "log.h" 591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "misc.h" 601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstruct hostkeys { 621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood struct hostkey_entry *entries; 631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int num_entries; 641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}; 651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int 671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodextract_salt(const char *s, u_int l, char *salt, size_t salt_len) 681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *p, *b64salt; 701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int b64len; 711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int ret; 721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (l < sizeof(HASH_MAGIC) - 1) { 741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug2("extract_salt: string too short"); 751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (-1); 761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (strncmp(s, HASH_MAGIC, sizeof(HASH_MAGIC) - 1) != 0) { 781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug2("extract_salt: invalid magic identifier"); 791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (-1); 801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s += sizeof(HASH_MAGIC) - 1; 821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood l -= sizeof(HASH_MAGIC) - 1; 831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((p = memchr(s, HASH_DELIM, l)) == NULL) { 841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug2("extract_salt: missing salt termination character"); 851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (-1); 861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood b64len = p - s; 891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Sanity check */ 901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (b64len == 0 || b64len > 1024) { 911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug2("extract_salt: bad encoded salt length %u", b64len); 921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (-1); 931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood b64salt = xmalloc(1 + b64len); 951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood memcpy(b64salt, s, b64len); 961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood b64salt[b64len] = '\0'; 971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ret = __b64_pton(b64salt, salt, salt_len); 991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(b64salt); 1001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (ret == -1) { 1011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug2("extract_salt: salt decode error"); 1021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (-1); 1031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 1041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (ret != SHA_DIGEST_LENGTH) { 1051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug2("extract_salt: expected salt len %d, got %d", 1061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood SHA_DIGEST_LENGTH, ret); 1071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (-1); 1081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 1091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (0); 1111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 1121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodchar * 1141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodhost_hash(const char *host, const char *name_from_hostfile, u_int src_len) 1151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 1161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood const EVP_MD *md = EVP_sha1(); 1171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood HMAC_CTX mac_ctx; 1181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char salt[256], result[256], uu_salt[512], uu_result[512]; 1191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood static char encoded[1024]; 1201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int i, len; 1211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood len = EVP_MD_size(md); 1231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (name_from_hostfile == NULL) { 1251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Create new salt */ 1261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (i = 0; i < len; i++) 1271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood salt[i] = arc4random(); 1281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else { 1291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Extract salt from known host entry */ 1301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (extract_salt(name_from_hostfile, src_len, salt, 1311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood sizeof(salt)) == -1) 1321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (NULL); 1331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 1341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood HMAC_Init(&mac_ctx, salt, len, md); 1361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood HMAC_Update(&mac_ctx, host, strlen(host)); 1371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood HMAC_Final(&mac_ctx, result, NULL); 1381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood HMAC_cleanup(&mac_ctx); 1391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (__b64_ntop(salt, len, uu_salt, sizeof(uu_salt)) == -1 || 1411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood __b64_ntop(result, len, uu_result, sizeof(uu_result)) == -1) 1421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("host_hash: __b64_ntop failed"); 1431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood snprintf(encoded, sizeof(encoded), "%s%s%c%s", HASH_MAGIC, uu_salt, 1451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood HASH_DELIM, uu_result); 1461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (encoded); 1481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 1491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 1511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Parses an RSA (number of bits, e, n) or DSA key from a string. Moves the 1521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * pointer over the key. Skips any whitespace at the beginning and at end. 1531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 1541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint 1561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodhostfile_read_key(char **cpp, u_int *bitsp, Key *ret) 1571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 1581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *cp; 1591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Skip leading whitespace. */ 1611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (cp = *cpp; *cp == ' ' || *cp == '\t'; cp++) 1621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ; 1631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (key_read(ret, &cp) != 1) 1651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 1661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Skip trailing whitespace. */ 1681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (; *cp == ' ' || *cp == '\t'; cp++) 1691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ; 1701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Return results. */ 1721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *cpp = cp; 1731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (bitsp != NULL) 1741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *bitsp = key_size(ret); 1751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 1; 1761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 1771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int 1791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodhostfile_check_key(int bits, const Key *key, const char *host, 1801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood const char *filename, u_long linenum) 1811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 1821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (key == NULL || key->type != KEY_RSA1 || key->rsa == NULL) 1831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 1; 1841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (bits != BN_num_bits(key->rsa->n)) { 1851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood logit("Warning: %s, line %lu: keysize mismatch for host %s: " 1861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood "actual %d vs. announced %d.", 1871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood filename, linenum, host, BN_num_bits(key->rsa->n), bits); 1881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood logit("Warning: replace %d with %d in %s, line %lu.", 1891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood bits, BN_num_bits(key->rsa->n), filename, linenum); 1901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 1911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 1; 1921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 1931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic HostkeyMarker 1951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodcheck_markers(char **cpp) 1961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 1971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char marker[32], *sp, *cp = *cpp; 1981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int ret = MRK_NONE; 1991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood while (*cp == '@') { 2011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Only one marker is allowed */ 2021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (ret != MRK_NONE) 2031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return MRK_ERROR; 2041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Markers are terminated by whitespace */ 2051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((sp = strchr(cp, ' ')) == NULL && 2061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (sp = strchr(cp, '\t')) == NULL) 2071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return MRK_ERROR; 2081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Extract marker for comparison */ 2091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (sp <= cp + 1 || sp >= cp + sizeof(marker)) 2101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return MRK_ERROR; 2111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood memcpy(marker, cp, sp - cp); 2121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood marker[sp - cp] = '\0'; 2131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (strcmp(marker, CA_MARKER) == 0) 2141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ret = MRK_CA; 2151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood else if (strcmp(marker, REVOKE_MARKER) == 0) 2161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ret = MRK_REVOKE; 2171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood else 2181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return MRK_ERROR; 2191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Skip past marker and any whitespace that follows it */ 2211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood cp = sp; 2221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (; *cp == ' ' || *cp == '\t'; cp++) 2231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ; 2241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 2251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *cpp = cp; 2261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return ret; 2271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 2281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstruct hostkeys * 2301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodinit_hostkeys(void) 2311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 2321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood struct hostkeys *ret = xcalloc(1, sizeof(*ret)); 2331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ret->entries = NULL; 2351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return ret; 2361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 2371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 2391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodload_hostkeys(struct hostkeys *hostkeys, const char *host, const char *path) 2401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 2411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood FILE *f; 2421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char line[8192]; 2431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_long linenum = 0, num_loaded = 0; 2441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *cp, *cp2, *hashed_host; 2451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood HostkeyMarker marker; 2461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Key *key; 2471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int kbits; 2481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((f = fopen(path, "r")) == NULL) 2501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return; 2511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug3("%s: loading entries for host \"%.100s\" from file \"%s\"", 2521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood __func__, host, path); 2531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood while (read_keyfile_line(f, path, line, sizeof(line), &linenum) == 0) { 2541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood cp = line; 2551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Skip any leading whitespace, comments and empty lines. */ 2571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (; *cp == ' ' || *cp == '\t'; cp++) 2581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ; 2591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!*cp || *cp == '#' || *cp == '\n') 2601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood continue; 2611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((marker = check_markers(&cp)) == MRK_ERROR) { 2631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood verbose("%s: invalid marker at %s:%lu", 2641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood __func__, path, linenum); 2651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood continue; 2661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 2671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Find the end of the host name portion. */ 2691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (cp2 = cp; *cp2 && *cp2 != ' ' && *cp2 != '\t'; cp2++) 2701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ; 2711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Check if the host name matches. */ 2731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (match_hostname(host, cp, (u_int) (cp2 - cp)) != 1) { 2741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (*cp != HASH_DELIM) 2751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood continue; 2761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood hashed_host = host_hash(host, cp, (u_int) (cp2 - cp)); 2771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (hashed_host == NULL) { 2781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("Invalid hashed host line %lu of %s", 2791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood linenum, path); 2801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood continue; 2811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 2821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (strncmp(hashed_host, cp, (u_int) (cp2 - cp)) != 0) 2831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood continue; 2841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 2851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Got a match. Skip host name. */ 2871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood cp = cp2; 2881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 2901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Extract the key from the line. This will skip any leading 2911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * whitespace. Ignore badly formatted lines. 2921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 2931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood key = key_new(KEY_UNSPEC); 2941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!hostfile_read_key(&cp, &kbits, key)) { 2951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood key_free(key); 2961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood key = key_new(KEY_RSA1); 2971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!hostfile_read_key(&cp, &kbits, key)) { 2981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood key_free(key); 2991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood continue; 3001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 3011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 3021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!hostfile_check_key(kbits, key, host, path, linenum)) 3031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood continue; 3041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 3051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug3("%s: found %skey type %s in file %s:%lu", __func__, 3061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood marker == MRK_NONE ? "" : 3071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (marker == MRK_CA ? "ca " : "revoked "), 3081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood key_type(key), path, linenum); 3091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood hostkeys->entries = xrealloc(hostkeys->entries, 3101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood hostkeys->num_entries + 1, sizeof(*hostkeys->entries)); 3111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood hostkeys->entries[hostkeys->num_entries].host = xstrdup(host); 3121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood hostkeys->entries[hostkeys->num_entries].file = xstrdup(path); 3131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood hostkeys->entries[hostkeys->num_entries].line = linenum; 3141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood hostkeys->entries[hostkeys->num_entries].key = key; 3151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood hostkeys->entries[hostkeys->num_entries].marker = marker; 3161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood hostkeys->num_entries++; 3171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood num_loaded++; 3181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 3191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug3("%s: loaded %lu keys", __func__, num_loaded); 3201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fclose(f); 3211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return; 3221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 3231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 3241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 3251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodfree_hostkeys(struct hostkeys *hostkeys) 3261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 3271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int i; 3281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 3291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (i = 0; i < hostkeys->num_entries; i++) { 3301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(hostkeys->entries[i].host); 3311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(hostkeys->entries[i].file); 3321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood key_free(hostkeys->entries[i].key); 3331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood bzero(hostkeys->entries + i, sizeof(*hostkeys->entries)); 3341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 3351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (hostkeys->entries != NULL) 3361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(hostkeys->entries); 3371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood hostkeys->entries = NULL; 3381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood hostkeys->num_entries = 0; 3391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(hostkeys); 3401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 3411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 3421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int 3431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodcheck_key_not_revoked(struct hostkeys *hostkeys, Key *k) 3441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 3451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int is_cert = key_is_cert(k); 3461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int i; 3471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 3481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (i = 0; i < hostkeys->num_entries; i++) { 3491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (hostkeys->entries[i].marker != MRK_REVOKE) 3501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood continue; 3511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (key_equal_public(k, hostkeys->entries[i].key)) 3521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 3531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (is_cert && 3541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood key_equal_public(k->cert->signature_key, 3551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood hostkeys->entries[i].key)) 3561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 3571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 3581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 3591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 3601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 3611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 3621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Match keys against a specified key, or look one up by key type. 3631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 3641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * If looking for a keytype (key == NULL) and one is found then return 3651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * HOST_FOUND, otherwise HOST_NEW. 3661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 3671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * If looking for a key (key != NULL): 3681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 1. If the key is a cert and a matching CA is found, return HOST_OK 3691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 2. If the key is not a cert and a matching key is found, return HOST_OK 3701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 3. If no key matches but a key with a different type is found, then 3711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * return HOST_CHANGED 3721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 4. If no matching keys are found, then return HOST_NEW. 3731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 3741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Finally, check any found key is not revoked. 3751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 3761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic HostStatus 3771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodcheck_hostkeys_by_key_or_type(struct hostkeys *hostkeys, 3781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Key *k, int keytype, const struct hostkey_entry **found) 3791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 3801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int i; 3811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood HostStatus end_return = HOST_NEW; 3821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int want_cert = key_is_cert(k); 3831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood HostkeyMarker want_marker = want_cert ? MRK_CA : MRK_NONE; 3841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int proto = (k ? k->type : keytype) == KEY_RSA1 ? 1 : 2; 3851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 3861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (found != NULL) 3871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *found = NULL; 3881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 3891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (i = 0; i < hostkeys->num_entries; i++) { 3901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (proto == 1 && hostkeys->entries[i].key->type != KEY_RSA1) 3911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood continue; 3921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (proto == 2 && hostkeys->entries[i].key->type == KEY_RSA1) 3931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood continue; 3941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (hostkeys->entries[i].marker != want_marker) 3951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood continue; 3961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (k == NULL) { 3971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (hostkeys->entries[i].key->type != keytype) 3981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood continue; 3991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood end_return = HOST_FOUND; 4001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (found != NULL) 4011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *found = hostkeys->entries + i; 4021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood k = hostkeys->entries[i].key; 4031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 4041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 4051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (want_cert) { 4061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (key_equal_public(k->cert->signature_key, 4071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood hostkeys->entries[i].key)) { 4081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* A matching CA exists */ 4091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood end_return = HOST_OK; 4101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (found != NULL) 4111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *found = hostkeys->entries + i; 4121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 4131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 4141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else { 4151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (key_equal(k, hostkeys->entries[i].key)) { 4161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood end_return = HOST_OK; 4171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (found != NULL) 4181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *found = hostkeys->entries + i; 4191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 4201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 4211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* A non-maching key exists */ 4221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood end_return = HOST_CHANGED; 4231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (found != NULL) 4241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *found = hostkeys->entries + i; 4251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 4261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 4271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (check_key_not_revoked(hostkeys, k) != 0) { 4281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood end_return = HOST_REVOKED; 4291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (found != NULL) 4301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *found = NULL; 4311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 4321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return end_return; 4331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 4341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 4351305e95ba6ff9fa202d0818caf10405df4b0f648Mike LockwoodHostStatus 4361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodcheck_key_in_hostkeys(struct hostkeys *hostkeys, Key *key, 4371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood const struct hostkey_entry **found) 4381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 4391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (key == NULL) 4401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("no key to look up"); 4411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return check_hostkeys_by_key_or_type(hostkeys, key, 0, found); 4421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 4431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 4441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint 4451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodlookup_key_in_hostkeys_by_type(struct hostkeys *hostkeys, int keytype, 4461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood const struct hostkey_entry **found) 4471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 4481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (check_hostkeys_by_key_or_type(hostkeys, NULL, keytype, 4491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood found) == HOST_FOUND); 4501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 4511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 4521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 4531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Appends an entry to the host file. Returns false if the entry could not 4541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * be appended. 4551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 4561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 4571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint 4581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodadd_host_to_hostfile(const char *filename, const char *host, const Key *key, 4591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int store_hash) 4601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 4611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood FILE *f; 4621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int success = 0; 4631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *hashed_host = NULL; 4641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 4651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (key == NULL) 4661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 1; /* XXX ? */ 4671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood f = fopen(filename, "a"); 4681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!f) 4691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 4701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 4711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (store_hash) { 4721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((hashed_host = host_hash(host, NULL, 0)) == NULL) { 4731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("add_host_to_hostfile: host_hash failed"); 4741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fclose(f); 4751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 4761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 4771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 4781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fprintf(f, "%s ", store_hash ? hashed_host : host); 4791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 4801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (key_write(key, f)) { 4811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood success = 1; 4821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else { 4831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("add_host_to_hostfile: saving key in %s failed", filename); 4841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 4851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fprintf(f, "\n"); 4861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fclose(f); 4871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return success; 4881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 489