summaryrefslogtreecommitdiff
path: root/hostfile.c
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>1999-11-25 00:26:21 +1100
committerDamien Miller <djm@mindrot.org>1999-11-25 00:26:21 +1100
commit95def09838fc61b37b6ea7cd5c234a465b4b129b (patch)
tree042744f76f40a326b873cb1c3690a6d7d966bc3e /hostfile.c
parent4d2f15f895f4c795afc008aeff3fd2ceffbc44f4 (diff)
- Merged very large OpenBSD source code reformat
- OpenBSD CVS updates - [channels.c cipher.c compat.c log-client.c scp.c serverloop.c] [ssh.h sshd.8 sshd.c] syslog changes: * Unified Logmessage for all auth-types, for success and for failed * Standard connections get only ONE line in the LOG when level==LOG: Auth-attempts are logged only, if authentication is: a) successfull or b) with passwd or c) we had more than AUTH_FAIL_LOG failues * many log() became verbose() * old behaviour with level=VERBOSE - [readconf.c readconf.h ssh.1 ssh.h sshconnect.c sshd.c] tranfer s/key challenge/response data in SSH_SMSG_AUTH_TIS_CHALLENGE messages. allows use of s/key in windows (ttssh, securecrt) and ssh-1.2.27 clients without 'ssh -v', ok: niels@ - [sshd.8] -V, for fallback to openssh in SSH2 compatibility mode - [sshd.c] fix sigchld race; cjc5@po.cwru.edu
Diffstat (limited to 'hostfile.c')
-rw-r--r--hostfile.c457
1 files changed, 224 insertions, 233 deletions
diff --git a/hostfile.c b/hostfile.c
index de21c904e..61046f071 100644
--- a/hostfile.c
+++ b/hostfile.c
@@ -1,20 +1,20 @@
1/* 1/*
2 2 *
3hostfile.c 3 * hostfile.c
4 4 *
5Author: Tatu Ylonen <ylo@cs.hut.fi> 5 * Author: Tatu Ylonen <ylo@cs.hut.fi>
6 6 *
7Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 7 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
8 All rights reserved 8 * All rights reserved
9 9 *
10Created: Thu Jun 29 07:10:56 1995 ylo 10 * Created: Thu Jun 29 07:10:56 1995 ylo
11 11 *
12Functions for manipulating the known hosts files. 12 * Functions for manipulating the known hosts files.
13 13 *
14*/ 14 */
15 15
16#include "includes.h" 16#include "includes.h"
17RCSID("$Id: hostfile.c,v 1.4 1999/11/17 06:29:08 damien Exp $"); 17RCSID("$Id: hostfile.c,v 1.5 1999/11/24 13:26:22 damien Exp $");
18 18
19#include "packet.h" 19#include "packet.h"
20#include "ssh.h" 20#include "ssh.h"
@@ -26,140 +26,136 @@ RCSID("$Id: hostfile.c,v 1.4 1999/11/17 06:29:08 damien Exp $");
26 modify the buffer containing the number. */ 26 modify the buffer containing the number. */
27 27
28int 28int
29auth_rsa_read_bignum(char **cpp, BIGNUM *value) 29auth_rsa_read_bignum(char **cpp, BIGNUM * value)
30{ 30{
31 char *cp = *cpp; 31 char *cp = *cpp;
32 int len, old; 32 int len, old;
33
34 /* Skip any leading whitespace. */
35 for (; *cp == ' ' || *cp == '\t'; cp++);
33 36
34 /* Skip any leading whitespace. */ 37 /* Check that it begins with a hex digit. */
35 for (; *cp == ' ' || *cp == '\t'; cp++) 38 if (*cp < '0' || *cp > '9')
36 ; 39 return 0;
37 40
38 /* Check that it begins with a hex digit. */ 41 /* Save starting position. */
39 if (*cp < '0' || *cp > '9') 42 *cpp = cp;
40 return 0;
41 43
42 /* Save starting position. */ 44 /* Move forward until all hex digits skipped. */
43 *cpp = cp; 45 for (; *cp >= '0' && *cp <= '9'; cp++);
44 46
45 /* Move forward until all hex digits skipped. */ 47 /* Compute the length of the hex number. */
46 for (; *cp >= '0' && *cp <= '9'; cp++) 48 len = cp - *cpp;
47 ;
48 49
49 /* Compute the length of the hex number. */ 50 /* Save the old terminating character, and replace it by \0. */
50 len = cp - *cpp; 51 old = *cp;
52 *cp = 0;
51 53
52 /* Save the old terminating character, and replace it by \0. */
53 old = *cp;
54 *cp = 0;
55 54
56 55 /* Parse the number. */
57 /* Parse the number. */ 56 if (BN_dec2bn(&value, *cpp) == 0)
58 if (BN_dec2bn(&value, *cpp) == 0) 57 return 0;
59 return 0;
60 58
61 /* Restore old terminating character. */ 59 /* Restore old terminating character. */
62 *cp = old; 60 *cp = old;
63 61
64 /* Move beyond the number and return success. */ 62 /* Move beyond the number and return success. */
65 *cpp = cp; 63 *cpp = cp;
66 return 1; 64 return 1;
67} 65}
68 66
69/* Parses an RSA key (number of bits, e, n) from a string. Moves the pointer 67/* Parses an RSA key (number of bits, e, n) from a string. Moves the pointer
70 over the key. Skips any whitespace at the beginning and at end. */ 68 over the key. Skips any whitespace at the beginning and at end. */
71 69
72int 70int
73auth_rsa_read_key(char **cpp, unsigned int *bitsp, BIGNUM *e, BIGNUM *n) 71auth_rsa_read_key(char **cpp, unsigned int *bitsp, BIGNUM * e, BIGNUM * n)
74{ 72{
75 unsigned int bits; 73 unsigned int bits;
76 char *cp; 74 char *cp;
77 75
78 /* Skip leading whitespace. */ 76 /* Skip leading whitespace. */
79 for (cp = *cpp; *cp == ' ' || *cp == '\t'; cp++) 77 for (cp = *cpp; *cp == ' ' || *cp == '\t'; cp++);
80 ; 78
81 79 /* Get number of bits. */
82 /* Get number of bits. */ 80 if (*cp < '0' || *cp > '9')
83 if (*cp < '0' || *cp > '9') 81 return 0; /* Bad bit count... */
84 return 0; /* Bad bit count... */ 82 for (bits = 0; *cp >= '0' && *cp <= '9'; cp++)
85 for (bits = 0; *cp >= '0' && *cp <= '9'; cp++) 83 bits = 10 * bits + *cp - '0';
86 bits = 10 * bits + *cp - '0'; 84
87 85 /* Get public exponent. */
88 /* Get public exponent. */ 86 if (!auth_rsa_read_bignum(&cp, e))
89 if (!auth_rsa_read_bignum(&cp, e)) 87 return 0;
90 return 0; 88
91 89 /* Get public modulus. */
92 /* Get public modulus. */ 90 if (!auth_rsa_read_bignum(&cp, n))
93 if (!auth_rsa_read_bignum(&cp, n)) 91 return 0;
94 return 0; 92
95 93 /* Skip trailing whitespace. */
96 /* Skip trailing whitespace. */ 94 for (; *cp == ' ' || *cp == '\t'; cp++);
97 for (; *cp == ' ' || *cp == '\t'; cp++) 95
98 ; 96 /* Return results. */
99 97 *cpp = cp;
100 /* Return results. */ 98 *bitsp = bits;
101 *cpp = cp; 99 return 1;
102 *bitsp = bits;
103 return 1;
104} 100}
105 101
106/* Tries to match the host name (which must be in all lowercase) against the 102/* Tries to match the host name (which must be in all lowercase) against the
107 comma-separated sequence of subpatterns (each possibly preceded by ! to 103 comma-separated sequence of subpatterns (each possibly preceded by ! to
108 indicate negation). Returns true if there is a positive match; zero 104 indicate negation). Returns true if there is a positive match; zero
109 otherwise. */ 105 otherwise. */
110 106
111int 107int
112match_hostname(const char *host, const char *pattern, unsigned int len) 108match_hostname(const char *host, const char *pattern, unsigned int len)
113{ 109{
114 char sub[1024]; 110 char sub[1024];
115 int negated; 111 int negated;
116 int got_positive; 112 int got_positive;
117 unsigned int i, subi; 113 unsigned int i, subi;
118 114
119 got_positive = 0; 115 got_positive = 0;
120 for (i = 0; i < len;) 116 for (i = 0; i < len;) {
121 { 117 /* Check if the subpattern is negated. */
122 /* Check if the subpattern is negated. */ 118 if (pattern[i] == '!') {
123 if (pattern[i] == '!') 119 negated = 1;
124 { 120 i++;
125 negated = 1; 121 } else
126 i++; 122 negated = 0;
123
124 /* Extract the subpattern up to a comma or end. Convert
125 the subpattern to lowercase. */
126 for (subi = 0;
127 i < len && subi < sizeof(sub) - 1 && pattern[i] != ',';
128 subi++, i++)
129 sub[subi] = isupper(pattern[i]) ? tolower(pattern[i]) : pattern[i];
130 /* If subpattern too long, return failure (no match). */
131 if (subi >= sizeof(sub) - 1)
132 return 0;
133
134 /* If the subpattern was terminated by a comma, skip the
135 comma. */
136 if (i < len && pattern[i] == ',')
137 i++;
138
139 /* Null-terminate the subpattern. */
140 sub[subi] = '\0';
141
142 /* Try to match the subpattern against the host name. */
143 if (match_pattern(host, sub)) {
144 if (negated)
145 return 0; /* Fail if host matches
146 any negated subpattern. */
147 else
148 got_positive = 1;
149 }
127 } 150 }
128 else 151
129 negated = 0; 152 /* Return success if got a positive match. If there was a
130 153 negative match, we have already returned zero and never get
131 /* Extract the subpattern up to a comma or end. Convert the subpattern 154 here. */
132 to lowercase. */ 155 return got_positive;
133 for (subi = 0;
134 i < len && subi < sizeof(sub) - 1 && pattern[i] != ',';
135 subi++, i++)
136 sub[subi] = isupper(pattern[i]) ? tolower(pattern[i]) : pattern[i];
137 /* If subpattern too long, return failure (no match). */
138 if (subi >= sizeof(sub) - 1)
139 return 0;
140
141 /* If the subpattern was terminated by a comma, skip the comma. */
142 if (i < len && pattern[i] == ',')
143 i++;
144
145 /* Null-terminate the subpattern. */
146 sub[subi] = '\0';
147
148 /* Try to match the subpattern against the host name. */
149 if (match_pattern(host, sub)) {
150 if (negated)
151 return 0; /* Fail if host matches any negated subpattern. */
152 else
153 got_positive = 1;
154 }
155 }
156
157 /* Return success if got a positive match. If there was a negative match,
158 we have already returned zero and never get here. */
159 return got_positive;
160} 156}
161 157
162/* Checks whether the given host (which must be in all lowercase) is 158/* Checks whether the given host (which must be in all lowercase) is
163 already in the list of our known hosts. 159 already in the list of our known hosts.
164 Returns HOST_OK if the host is known and has the specified key, 160 Returns HOST_OK if the host is known and has the specified key,
165 HOST_NEW if the host is not known, and HOST_CHANGED if the host is known 161 HOST_NEW if the host is not known, and HOST_CHANGED if the host is known
@@ -167,87 +163,82 @@ match_hostname(const char *host, const char *pattern, unsigned int len)
167 163
168HostStatus 164HostStatus
169check_host_in_hostfile(const char *filename, const char *host, 165check_host_in_hostfile(const char *filename, const char *host,
170 BIGNUM *e, BIGNUM *n, BIGNUM *ke, BIGNUM *kn) 166 BIGNUM * e, BIGNUM * n, BIGNUM * ke, BIGNUM * kn)
171{ 167{
172 FILE *f; 168 FILE *f;
173 char line[8192]; 169 char line[8192];
174 int linenum = 0; 170 int linenum = 0;
175 unsigned int bits, kbits, hostlen; 171 unsigned int bits, kbits, hostlen;
176 char *cp, *cp2; 172 char *cp, *cp2;
177 HostStatus end_return; 173 HostStatus end_return;
178 174
179 /* Open the file containing the list of known hosts. */ 175 /* Open the file containing the list of known hosts. */
180 f = fopen(filename, "r"); 176 f = fopen(filename, "r");
181 if (!f) 177 if (!f)
182 return HOST_NEW; 178 return HOST_NEW;
183 179
184 /* Cache the length of the host name. */ 180 /* Cache the length of the host name. */
185 hostlen = strlen(host); 181 hostlen = strlen(host);
186 182
187 /* Return value when the loop terminates. This is set to HOST_CHANGED if 183 /* Return value when the loop terminates. This is set to
188 we have seen a different key for the host and have not found the proper 184 HOST_CHANGED if we have seen a different key for the host and
189 one. */ 185 have not found the proper one. */
190 end_return = HOST_NEW; 186 end_return = HOST_NEW;
191 187
192 /* size of modulus 'n' */ 188 /* size of modulus 'n' */
193 bits = BN_num_bits(n); 189 bits = BN_num_bits(n);
194 190
195 /* Go trough the file. */ 191 /* Go trough the file. */
196 while (fgets(line, sizeof(line), f)) 192 while (fgets(line, sizeof(line), f)) {
197 { 193 cp = line;
198 cp = line; 194 linenum++;
199 linenum++; 195
200 196 /* Skip any leading whitespace. */
201 /* Skip any leading whitespace. */ 197 for (; *cp == ' ' || *cp == '\t'; cp++);
202 for (; *cp == ' ' || *cp == '\t'; cp++) 198
203 ; 199 /* Ignore comment lines and empty lines. */
204 200 if (!*cp || *cp == '#' || *cp == '\n')
205 /* Ignore comment lines and empty lines. */ 201 continue;
206 if (!*cp || *cp == '#' || *cp == '\n') 202
207 continue; 203 /* Find the end of the host name portion. */
208 204 for (cp2 = cp; *cp2 && *cp2 != ' ' && *cp2 != '\t'; cp2++);
209 /* Find the end of the host name portion. */ 205
210 for (cp2 = cp; *cp2 && *cp2 != ' ' && *cp2 != '\t'; cp2++) 206 /* Check if the host name matches. */
211 ; 207 if (!match_hostname(host, cp, (unsigned int) (cp2 - cp)))
212 208 continue;
213 /* Check if the host name matches. */ 209
214 if (!match_hostname(host, cp, (unsigned int)(cp2 - cp))) 210 /* Got a match. Skip host name. */
215 continue; 211 cp = cp2;
216 212
217 /* Got a match. Skip host name. */ 213 /* Extract the key from the line. This will skip any
218 cp = cp2; 214 leading whitespace. Ignore badly formatted lines. */
219 215 if (!auth_rsa_read_key(&cp, &kbits, ke, kn))
220 /* Extract the key from the line. This will skip any leading 216 continue;
221 whitespace. Ignore badly formatted lines. */ 217
222 if (!auth_rsa_read_key(&cp, &kbits, ke, kn)) 218 if (kbits != BN_num_bits(kn)) {
223 continue; 219 error("Warning: error in %s, line %d: keysize mismatch for host %s: "
224 220 "actual size %d vs. announced %d.",
225 if (kbits != BN_num_bits(kn)) { 221 filename, linenum, host, BN_num_bits(kn), kbits);
226 error("Warning: error in %s, line %d: keysize mismatch for host %s: " 222 error("Warning: replace %d with %d in %s, line %d.",
227 "actual size %d vs. announced %d.", 223 kbits, BN_num_bits(kn), filename, linenum);
228 filename, linenum, host, BN_num_bits(kn), kbits); 224 }
229 error("Warning: replace %d with %d in %s, line %d.", 225 /* Check if the current key is the same as the given key. */
230 kbits, BN_num_bits(kn), filename, linenum); 226 if (BN_cmp(ke, e) == 0 && BN_cmp(kn, n) == 0) {
231 } 227 /* Ok, they match. */
232 228 fclose(f);
233 /* Check if the current key is the same as the given key. */ 229 return HOST_OK;
234 if (BN_cmp(ke, e) == 0 && BN_cmp(kn, n) == 0) 230 }
235 { 231 /* They do not match. We will continue to go through the
236 /* Ok, they match. */ 232 file; however, we note that we will not return that it
237 fclose(f); 233 is new. */
238 return HOST_OK; 234 end_return = HOST_CHANGED;
239 } 235 }
240 236 /* Clear variables and close the file. */
241 /* They do not match. We will continue to go through the file; however, 237 fclose(f);
242 we note that we will not return that it is new. */ 238
243 end_return = HOST_CHANGED; 239 /* Return either HOST_NEW or HOST_CHANGED, depending on whether we
244 } 240 saw a different key for the host. */
245 /* Clear variables and close the file. */ 241 return end_return;
246 fclose(f);
247
248 /* Return either HOST_NEW or HOST_CHANGED, depending on whether we saw a
249 different key for the host. */
250 return end_return;
251} 242}
252 243
253/* Appends an entry to the host file. Returns false if the entry 244/* Appends an entry to the host file. Returns false if the entry
@@ -255,40 +246,40 @@ check_host_in_hostfile(const char *filename, const char *host,
255 246
256int 247int
257add_host_to_hostfile(const char *filename, const char *host, 248add_host_to_hostfile(const char *filename, const char *host,
258 BIGNUM *e, BIGNUM *n) 249 BIGNUM * e, BIGNUM * n)
259{ 250{
260 FILE *f; 251 FILE *f;
261 char *buf; 252 char *buf;
262 unsigned int bits; 253 unsigned int bits;
263 254
264 /* Open the file for appending. */ 255 /* Open the file for appending. */
265 f = fopen(filename, "a"); 256 f = fopen(filename, "a");
266 if (!f) 257 if (!f)
267 return 0; 258 return 0;
268 259
269 /* size of modulus 'n' */ 260 /* size of modulus 'n' */
270 bits = BN_num_bits(n); 261 bits = BN_num_bits(n);
271 262
272 /* Print the host name and key to the file. */ 263 /* Print the host name and key to the file. */
273 fprintf(f, "%s %u ", host, bits); 264 fprintf(f, "%s %u ", host, bits);
274 buf = BN_bn2dec(e); 265 buf = BN_bn2dec(e);
275 if (buf == NULL) { 266 if (buf == NULL) {
276 error("add_host_to_hostfile: BN_bn2dec(e) failed"); 267 error("add_host_to_hostfile: BN_bn2dec(e) failed");
277 fclose(f); 268 fclose(f);
278 return 0; 269 return 0;
279 } 270 }
280 fprintf(f, "%s ", buf); 271 fprintf(f, "%s ", buf);
281 free (buf); 272 free(buf);
282 buf = BN_bn2dec(n); 273 buf = BN_bn2dec(n);
283 if (buf == NULL) { 274 if (buf == NULL) {
284 error("add_host_to_hostfile: BN_bn2dec(n) failed"); 275 error("add_host_to_hostfile: BN_bn2dec(n) failed");
285 fclose(f); 276 fclose(f);
286 return 0; 277 return 0;
287 } 278 }
288 fprintf(f, "%s\n", buf); 279 fprintf(f, "%s\n", buf);
289 free (buf); 280 free(buf);
290 281
291 /* Close the file. */ 282 /* Close the file. */
292 fclose(f); 283 fclose(f);
293 return 1; 284 return 1;
294} 285}