summaryrefslogtreecommitdiff
path: root/hostfile.c
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2000-03-26 13:04:51 +1000
committerDamien Miller <djm@mindrot.org>2000-03-26 13:04:51 +1000
commit450a7a1ff40fe7c2d84c93b83cf2df53445d807d (patch)
treedb6d08bdea65edd34ba2e323a31e2b1ca5e5fbd4 /hostfile.c
parent2c9279fa667827384fceb243f890cba1dbe480de (diff)
- OpenBSD CVS update
- [auth-krb4.c] -Wall - [auth-rh-rsa.c auth-rsa.c hostfile.c hostfile.h key.c key.h match.c] [match.h ssh.c ssh.h sshconnect.c sshd.c] initial support for DSA keys. ok deraadt@, niels@ - [cipher.c cipher.h] remove unused cipher_attack_detected code - [scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh.1 sshd.8] Fix some formatting problems I missed before. - [ssh.1 sshd.8] fix spelling errors, From: FreeBSD - [ssh.c] switch to raw mode only if he _get_ a pty (not if we _want_ a pty).
Diffstat (limited to 'hostfile.c')
-rw-r--r--hostfile.c202
1 files changed, 58 insertions, 144 deletions
diff --git a/hostfile.c b/hostfile.c
index ea92fa048..a6684fa2c 100644
--- a/hostfile.c
+++ b/hostfile.c
@@ -14,63 +14,32 @@
14 */ 14 */
15 15
16#include "includes.h" 16#include "includes.h"
17RCSID("$OpenBSD: hostfile.c,v 1.13 2000/02/18 10:20:20 markus Exp $"); 17RCSID("$OpenBSD: hostfile.c,v 1.14 2000/03/23 22:15:33 markus Exp $");
18
19#ifdef HAVE_OPENSSL
20#include <openssl/bn.h>
21#include <openssl/rsa.h>
22#include <openssl/dsa.h>
23#endif
24#ifdef HAVE_SSL
25#include <ssl/bn.h>
26#include <ssl/rsa.h>
27#include <ssl/dsa.h>
28#endif
18 29
19#include "packet.h" 30#include "packet.h"
31#include "match.h"
20#include "ssh.h" 32#include "ssh.h"
33#include "key.h"
34#include "hostfile.h"
21 35
22/* 36/*
23 * Reads a multiple-precision integer in decimal from the buffer, and advances 37 * Parses an RSA (number of bits, e, n) or DSA key from a string. Moves the
24 * the pointer. The integer must already be initialized. This function is 38 * pointer over the key. Skips any whitespace at the beginning and at end.
25 * permitted to modify the buffer. This leaves *cpp to point just beyond the
26 * last processed (and maybe modified) character. Note that this may modify
27 * the buffer containing the number.
28 */ 39 */
29 40
30int 41int
31auth_rsa_read_bignum(char **cpp, BIGNUM * value) 42hostfile_read_key(char **cpp, unsigned int *bitsp, Key *ret)
32{
33 char *cp = *cpp;
34 int old;
35
36 /* Skip any leading whitespace. */
37 for (; *cp == ' ' || *cp == '\t'; cp++)
38 ;
39
40 /* Check that it begins with a decimal digit. */
41 if (*cp < '0' || *cp > '9')
42 return 0;
43
44 /* Save starting position. */
45 *cpp = cp;
46
47 /* Move forward until all decimal digits skipped. */
48 for (; *cp >= '0' && *cp <= '9'; cp++)
49 ;
50
51 /* Save the old terminating character, and replace it by \0. */
52 old = *cp;
53 *cp = 0;
54
55 /* Parse the number. */
56 if (BN_dec2bn(&value, *cpp) == 0)
57 return 0;
58
59 /* Restore old terminating character. */
60 *cp = old;
61
62 /* Move beyond the number and return success. */
63 *cpp = cp;
64 return 1;
65}
66
67/*
68 * Parses an RSA key (number of bits, e, n) from a string. Moves the pointer
69 * over the key. Skips any whitespace at the beginning and at end.
70 */
71
72int
73auth_rsa_read_key(char **cpp, unsigned int *bitsp, BIGNUM * e, BIGNUM * n)
74{ 43{
75 unsigned int bits; 44 unsigned int bits;
76 char *cp; 45 char *cp;
@@ -85,12 +54,7 @@ auth_rsa_read_key(char **cpp, unsigned int *bitsp, BIGNUM * e, BIGNUM * n)
85 for (bits = 0; *cp >= '0' && *cp <= '9'; cp++) 54 for (bits = 0; *cp >= '0' && *cp <= '9'; cp++)
86 bits = 10 * bits + *cp - '0'; 55 bits = 10 * bits + *cp - '0';
87 56
88 /* Get public exponent. */ 57 if (!key_read(ret, bits, &cp))
89 if (!auth_rsa_read_bignum(&cp, e))
90 return 0;
91
92 /* Get public modulus. */
93 if (!auth_rsa_read_bignum(&cp, n))
94 return 0; 58 return 0;
95 59
96 /* Skip trailing whitespace. */ 60 /* Skip trailing whitespace. */
@@ -103,63 +67,30 @@ auth_rsa_read_key(char **cpp, unsigned int *bitsp, BIGNUM * e, BIGNUM * n)
103 return 1; 67 return 1;
104} 68}
105 69
106/*
107 * Tries to match the host name (which must be in all lowercase) against the
108 * comma-separated sequence of subpatterns (each possibly preceded by ! to
109 * indicate negation). Returns true if there is a positive match; zero
110 * otherwise.
111 */
112
113int 70int
114match_hostname(const char *host, const char *pattern, unsigned int len) 71auth_rsa_read_key(char **cpp, unsigned int *bitsp, BIGNUM * e, BIGNUM * n)
115{ 72{
116 char sub[1024]; 73 Key *k = key_new(KEY_RSA);
117 int negated; 74 int ret = hostfile_read_key(cpp, bitsp, k);
118 int got_positive; 75 BN_copy(e, k->rsa->e);
119 unsigned int i, subi; 76 BN_copy(n, k->rsa->n);
120 77 key_free(k);
121 got_positive = 0; 78 return ret;
122 for (i = 0; i < len;) { 79}
123 /* Check if the subpattern is negated. */
124 if (pattern[i] == '!') {
125 negated = 1;
126 i++;
127 } else
128 negated = 0;
129
130 /*
131 * Extract the subpattern up to a comma or end. Convert the
132 * subpattern to lowercase.
133 */
134 for (subi = 0;
135 i < len && subi < sizeof(sub) - 1 && pattern[i] != ',';
136 subi++, i++)
137 sub[subi] = isupper(pattern[i]) ? tolower(pattern[i]) : pattern[i];
138 /* If subpattern too long, return failure (no match). */
139 if (subi >= sizeof(sub) - 1)
140 return 0;
141
142 /* If the subpattern was terminated by a comma, skip the comma. */
143 if (i < len && pattern[i] == ',')
144 i++;
145
146 /* Null-terminate the subpattern. */
147 sub[subi] = '\0';
148 80
149 /* Try to match the subpattern against the host name. */ 81int
150 if (match_pattern(host, sub)) { 82hostfile_check_key(int bits, Key *key, const char *host, const char *filename, int linenum)
151 if (negated) 83{
152 return 0; /* Fail */ 84 if (key == NULL || key->type != KEY_RSA || key->rsa == NULL)
153 else 85 return 1;
154 got_positive = 1; 86 if (bits != BN_num_bits(key->rsa->n)) {
155 } 87 error("Warning: %s, line %d: keysize mismatch for host %s: "
88 "actual %d vs. announced %d.",
89 filename, linenum, host, BN_num_bits(key->rsa->n), bits);
90 error("Warning: replace %d with %d in %s, line %d.",
91 bits, BN_num_bits(key->rsa->n), filename, linenum);
156 } 92 }
157 93 return 1;
158 /*
159 * Return success if got a positive match. If there was a negative
160 * match, we have already returned zero and never get here.
161 */
162 return got_positive;
163} 94}
164 95
165/* 96/*
@@ -170,8 +101,7 @@ match_hostname(const char *host, const char *pattern, unsigned int len)
170 */ 101 */
171 102
172HostStatus 103HostStatus
173check_host_in_hostfile(const char *filename, const char *host, 104check_host_in_hostfile(const char *filename, const char *host, Key *key, Key *found)
174 BIGNUM * e, BIGNUM * n, BIGNUM * ke, BIGNUM * kn)
175{ 105{
176 FILE *f; 106 FILE *f;
177 char line[8192]; 107 char line[8192];
@@ -180,6 +110,8 @@ check_host_in_hostfile(const char *filename, const char *host,
180 char *cp, *cp2; 110 char *cp, *cp2;
181 HostStatus end_return; 111 HostStatus end_return;
182 112
113 if (key == NULL)
114 fatal("no key to look up");
183 /* Open the file containing the list of known hosts. */ 115 /* Open the file containing the list of known hosts. */
184 f = fopen(filename, "r"); 116 f = fopen(filename, "r");
185 if (!f) 117 if (!f)
@@ -221,18 +153,13 @@ check_host_in_hostfile(const char *filename, const char *host,
221 * Extract the key from the line. This will skip any leading 153 * Extract the key from the line. This will skip any leading
222 * whitespace. Ignore badly formatted lines. 154 * whitespace. Ignore badly formatted lines.
223 */ 155 */
224 if (!auth_rsa_read_key(&cp, &kbits, ke, kn)) 156 if (!hostfile_read_key(&cp, &kbits, found))
157 continue;
158 if (!hostfile_check_key(kbits, found, host, filename, linenum))
225 continue; 159 continue;
226 160
227 if (kbits != BN_num_bits(kn)) {
228 error("Warning: %s, line %d: keysize mismatch for host %s: "
229 "actual %d vs. announced %d.",
230 filename, linenum, host, BN_num_bits(kn), kbits);
231 error("Warning: replace %d with %d in %s, line %d.",
232 kbits, BN_num_bits(kn), filename, linenum);
233 }
234 /* Check if the current key is the same as the given key. */ 161 /* Check if the current key is the same as the given key. */
235 if (BN_cmp(ke, e) == 0 && BN_cmp(kn, n) == 0) { 162 if (key_equal(key, found)) {
236 /* Ok, they match. */ 163 /* Ok, they match. */
237 fclose(f); 164 fclose(f);
238 return HOST_OK; 165 return HOST_OK;
@@ -260,41 +187,28 @@ check_host_in_hostfile(const char *filename, const char *host,
260 */ 187 */
261 188
262int 189int
263add_host_to_hostfile(const char *filename, const char *host, 190add_host_to_hostfile(const char *filename, const char *host, Key *key)
264 BIGNUM * e, BIGNUM * n)
265{ 191{
266 FILE *f; 192 FILE *f;
267 char *buf; 193 int success = 0;
268 unsigned int bits; 194
195 if (key == NULL)
196 return 1;
269 197
270 /* Open the file for appending. */ 198 /* Open the file for appending. */
271 f = fopen(filename, "a"); 199 f = fopen(filename, "a");
272 if (!f) 200 if (!f)
273 return 0; 201 return 0;
274 202
275 /* size of modulus 'n' */ 203 fprintf(f, "%s ", host);
276 bits = BN_num_bits(n); 204 if (key_write(key, f)) {
277 205 fprintf(f, "\n");
278 /* Print the host name and key to the file. */ 206 success = 1;
279 fprintf(f, "%s %u ", host, bits); 207 } else {
280 buf = BN_bn2dec(e); 208 error("add_host_to_hostfile: saving key failed");
281 if (buf == NULL) {
282 error("add_host_to_hostfile: BN_bn2dec(e) failed");
283 fclose(f);
284 return 0;
285 } 209 }
286 fprintf(f, "%s ", buf);
287 free(buf);
288 buf = BN_bn2dec(n);
289 if (buf == NULL) {
290 error("add_host_to_hostfile: BN_bn2dec(n) failed");
291 fclose(f);
292 return 0;
293 }
294 fprintf(f, "%s\n", buf);
295 free(buf);
296 210
297 /* Close the file. */ 211 /* Close the file. */
298 fclose(f); 212 fclose(f);
299 return 1; 213 return success;
300} 214}