Absolute File Name: | /home/opencoverage/opencoverage/guest-scripts/openssh/src/dns.c |
Source code | Switch to Preprocessed file |
Line | Source | Count | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | /* $OpenBSD: dns.c,v 1.38 2018/02/23 15:58:37 markus Exp $ */ | - | ||||||||||||
2 | - | |||||||||||||
3 | /* | - | ||||||||||||
4 | * Copyright (c) 2003 Wesley Griffin. All rights reserved. | - | ||||||||||||
5 | * Copyright (c) 2003 Jakob Schlyter. All rights reserved. | - | ||||||||||||
6 | * | - | ||||||||||||
7 | * Redistribution and use in source and binary forms, with or without | - | ||||||||||||
8 | * modification, are permitted provided that the following conditions | - | ||||||||||||
9 | * are met: | - | ||||||||||||
10 | * 1. Redistributions of source code must retain the above copyright | - | ||||||||||||
11 | * notice, this list of conditions and the following disclaimer. | - | ||||||||||||
12 | * 2. Redistributions in binary form must reproduce the above copyright | - | ||||||||||||
13 | * notice, this list of conditions and the following disclaimer in the | - | ||||||||||||
14 | * documentation and/or other materials provided with the distribution. | - | ||||||||||||
15 | * | - | ||||||||||||
16 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | - | ||||||||||||
17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | - | ||||||||||||
18 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | - | ||||||||||||
19 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | - | ||||||||||||
20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | - | ||||||||||||
21 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | - | ||||||||||||
22 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | - | ||||||||||||
23 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | - | ||||||||||||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | - | ||||||||||||
25 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | - | ||||||||||||
26 | */ | - | ||||||||||||
27 | - | |||||||||||||
28 | #include "includes.h" | - | ||||||||||||
29 | - | |||||||||||||
30 | #include <sys/types.h> | - | ||||||||||||
31 | #include <sys/socket.h> | - | ||||||||||||
32 | - | |||||||||||||
33 | #include <netdb.h> | - | ||||||||||||
34 | #include <stdarg.h> | - | ||||||||||||
35 | #include <stdio.h> | - | ||||||||||||
36 | #include <string.h> | - | ||||||||||||
37 | #include <stdarg.h> | - | ||||||||||||
38 | #include <stdlib.h> | - | ||||||||||||
39 | - | |||||||||||||
40 | #include "xmalloc.h" | - | ||||||||||||
41 | #include "sshkey.h" | - | ||||||||||||
42 | #include "ssherr.h" | - | ||||||||||||
43 | #include "dns.h" | - | ||||||||||||
44 | #include "log.h" | - | ||||||||||||
45 | #include "digest.h" | - | ||||||||||||
46 | - | |||||||||||||
47 | static const char *errset_text[] = { | - | ||||||||||||
48 | "success", /* 0 ERRSET_SUCCESS */ | - | ||||||||||||
49 | "out of memory", /* 1 ERRSET_NOMEMORY */ | - | ||||||||||||
50 | "general failure", /* 2 ERRSET_FAIL */ | - | ||||||||||||
51 | "invalid parameter", /* 3 ERRSET_INVAL */ | - | ||||||||||||
52 | "name does not exist", /* 4 ERRSET_NONAME */ | - | ||||||||||||
53 | "data does not exist", /* 5 ERRSET_NODATA */ | - | ||||||||||||
54 | }; | - | ||||||||||||
55 | - | |||||||||||||
56 | static const char * | - | ||||||||||||
57 | dns_result_totext(unsigned int res) | - | ||||||||||||
58 | { | - | ||||||||||||
59 | switch (res) { | - | ||||||||||||
60 | case ERRSET_SUCCESS: never executed: case 0: | 0 | ||||||||||||
61 | return errset_text[ERRSET_SUCCESS]; never executed: return errset_text[0]; | 0 | ||||||||||||
62 | case ERRSET_NOMEMORY: never executed: case 1: | 0 | ||||||||||||
63 | return errset_text[ERRSET_NOMEMORY]; never executed: return errset_text[1]; | 0 | ||||||||||||
64 | case ERRSET_FAIL: never executed: case 2: | 0 | ||||||||||||
65 | return errset_text[ERRSET_FAIL]; never executed: return errset_text[2]; | 0 | ||||||||||||
66 | case ERRSET_INVAL: never executed: case 3: | 0 | ||||||||||||
67 | return errset_text[ERRSET_INVAL]; never executed: return errset_text[3]; | 0 | ||||||||||||
68 | case ERRSET_NONAME: never executed: case 4: | 0 | ||||||||||||
69 | return errset_text[ERRSET_NONAME]; never executed: return errset_text[4]; | 0 | ||||||||||||
70 | case ERRSET_NODATA: never executed: case 5: | 0 | ||||||||||||
71 | return errset_text[ERRSET_NODATA]; never executed: return errset_text[5]; | 0 | ||||||||||||
72 | default: never executed: default: | 0 | ||||||||||||
73 | return "unknown error"; never executed: return "unknown error"; | 0 | ||||||||||||
74 | } | - | ||||||||||||
75 | } | - | ||||||||||||
76 | - | |||||||||||||
77 | /* | - | ||||||||||||
78 | * Read SSHFP parameters from key buffer. | - | ||||||||||||
79 | */ | - | ||||||||||||
80 | static int | - | ||||||||||||
81 | dns_read_key(u_int8_t *algorithm, u_int8_t *digest_type, | - | ||||||||||||
82 | u_char **digest, size_t *digest_len, struct sshkey *key) | - | ||||||||||||
83 | { | - | ||||||||||||
84 | int r, success = 0; | - | ||||||||||||
85 | int fp_alg = -1; | - | ||||||||||||
86 | - | |||||||||||||
87 | switch (key->type) { | - | ||||||||||||
88 | case KEY_RSA: never executed: case KEY_RSA: | 0 | ||||||||||||
89 | *algorithm = SSHFP_KEY_RSA; | - | ||||||||||||
90 | if (!*digest_type)
| 0 | ||||||||||||
91 | *digest_type = SSHFP_HASH_SHA1; never executed: *digest_type = SSHFP_HASH_SHA1; | 0 | ||||||||||||
92 | break; never executed: break; | 0 | ||||||||||||
93 | case KEY_DSA: never executed: case KEY_DSA: | 0 | ||||||||||||
94 | *algorithm = SSHFP_KEY_DSA; | - | ||||||||||||
95 | if (!*digest_type)
| 0 | ||||||||||||
96 | *digest_type = SSHFP_HASH_SHA1; never executed: *digest_type = SSHFP_HASH_SHA1; | 0 | ||||||||||||
97 | break; never executed: break; | 0 | ||||||||||||
98 | case KEY_ECDSA: never executed: case KEY_ECDSA: | 0 | ||||||||||||
99 | *algorithm = SSHFP_KEY_ECDSA; | - | ||||||||||||
100 | if (!*digest_type)
| 0 | ||||||||||||
101 | *digest_type = SSHFP_HASH_SHA256; never executed: *digest_type = SSHFP_HASH_SHA256; | 0 | ||||||||||||
102 | break; never executed: break; | 0 | ||||||||||||
103 | case KEY_ED25519: never executed: case KEY_ED25519: | 0 | ||||||||||||
104 | *algorithm = SSHFP_KEY_ED25519; | - | ||||||||||||
105 | if (!*digest_type)
| 0 | ||||||||||||
106 | *digest_type = SSHFP_HASH_SHA256; never executed: *digest_type = SSHFP_HASH_SHA256; | 0 | ||||||||||||
107 | break; never executed: break; | 0 | ||||||||||||
108 | case KEY_XMSS: never executed: case KEY_XMSS: | 0 | ||||||||||||
109 | *algorithm = SSHFP_KEY_XMSS; | - | ||||||||||||
110 | if (!*digest_type)
| 0 | ||||||||||||
111 | *digest_type = SSHFP_HASH_SHA256; never executed: *digest_type = SSHFP_HASH_SHA256; | 0 | ||||||||||||
112 | break; never executed: break; | 0 | ||||||||||||
113 | default: never executed: default: | 0 | ||||||||||||
114 | *algorithm = SSHFP_KEY_RESERVED; /* 0 */ | - | ||||||||||||
115 | *digest_type = SSHFP_HASH_RESERVED; /* 0 */ | - | ||||||||||||
116 | } never executed: end of block | 0 | ||||||||||||
117 | - | |||||||||||||
118 | switch (*digest_type) { | - | ||||||||||||
119 | case SSHFP_HASH_SHA1: never executed: case SSHFP_HASH_SHA1: | 0 | ||||||||||||
120 | fp_alg = SSH_DIGEST_SHA1; | - | ||||||||||||
121 | break; never executed: break; | 0 | ||||||||||||
122 | case SSHFP_HASH_SHA256: never executed: case SSHFP_HASH_SHA256: | 0 | ||||||||||||
123 | fp_alg = SSH_DIGEST_SHA256; | - | ||||||||||||
124 | break; never executed: break; | 0 | ||||||||||||
125 | default: never executed: default: | 0 | ||||||||||||
126 | *digest_type = SSHFP_HASH_RESERVED; /* 0 */ | - | ||||||||||||
127 | } never executed: end of block | 0 | ||||||||||||
128 | - | |||||||||||||
129 | if (*algorithm && *digest_type) {
| 0 | ||||||||||||
130 | if ((r = sshkey_fingerprint_raw(key, fp_alg, digest,
| 0 | ||||||||||||
131 | digest_len)) != 0)
| 0 | ||||||||||||
132 | fatal("%s: sshkey_fingerprint_raw: %s", __func__, never executed: fatal("%s: sshkey_fingerprint_raw: %s", __func__, ssh_err(r)); | 0 | ||||||||||||
133 | ssh_err(r)); never executed: fatal("%s: sshkey_fingerprint_raw: %s", __func__, ssh_err(r)); | 0 | ||||||||||||
134 | success = 1; | - | ||||||||||||
135 | } else { never executed: end of block | 0 | ||||||||||||
136 | *digest = NULL; | - | ||||||||||||
137 | *digest_len = 0; | - | ||||||||||||
138 | success = 0; | - | ||||||||||||
139 | } never executed: end of block | 0 | ||||||||||||
140 | - | |||||||||||||
141 | return success; never executed: return success; | 0 | ||||||||||||
142 | } | - | ||||||||||||
143 | - | |||||||||||||
144 | /* | - | ||||||||||||
145 | * Read SSHFP parameters from rdata buffer. | - | ||||||||||||
146 | */ | - | ||||||||||||
147 | static int | - | ||||||||||||
148 | dns_read_rdata(u_int8_t *algorithm, u_int8_t *digest_type, | - | ||||||||||||
149 | u_char **digest, size_t *digest_len, u_char *rdata, int rdata_len) | - | ||||||||||||
150 | { | - | ||||||||||||
151 | int success = 0; | - | ||||||||||||
152 | - | |||||||||||||
153 | *algorithm = SSHFP_KEY_RESERVED; | - | ||||||||||||
154 | *digest_type = SSHFP_HASH_RESERVED; | - | ||||||||||||
155 | - | |||||||||||||
156 | if (rdata_len >= 2) {
| 0 | ||||||||||||
157 | *algorithm = rdata[0]; | - | ||||||||||||
158 | *digest_type = rdata[1]; | - | ||||||||||||
159 | *digest_len = rdata_len - 2; | - | ||||||||||||
160 | - | |||||||||||||
161 | if (*digest_len > 0) {
| 0 | ||||||||||||
162 | *digest = xmalloc(*digest_len); | - | ||||||||||||
163 | memcpy(*digest, rdata + 2, *digest_len); | - | ||||||||||||
164 | } else { never executed: end of block | 0 | ||||||||||||
165 | *digest = (u_char *)xstrdup(""); | - | ||||||||||||
166 | } never executed: end of block | 0 | ||||||||||||
167 | - | |||||||||||||
168 | success = 1; | - | ||||||||||||
169 | } never executed: end of block | 0 | ||||||||||||
170 | - | |||||||||||||
171 | return success; never executed: return success; | 0 | ||||||||||||
172 | } | - | ||||||||||||
173 | - | |||||||||||||
174 | /* | - | ||||||||||||
175 | * Check if hostname is numerical. | - | ||||||||||||
176 | * Returns -1 if hostname is numeric, 0 otherwise | - | ||||||||||||
177 | */ | - | ||||||||||||
178 | static int | - | ||||||||||||
179 | is_numeric_hostname(const char *hostname) | - | ||||||||||||
180 | { | - | ||||||||||||
181 | struct addrinfo hints, *ai; | - | ||||||||||||
182 | - | |||||||||||||
183 | /* | - | ||||||||||||
184 | * We shouldn't ever get a null host but if we do then log an error | - | ||||||||||||
185 | * and return -1 which stops DNS key fingerprint processing. | - | ||||||||||||
186 | */ | - | ||||||||||||
187 | if (hostname == NULL) {
| 0 | ||||||||||||
188 | error("is_numeric_hostname called with NULL hostname"); | - | ||||||||||||
189 | return -1; never executed: return -1; | 0 | ||||||||||||
190 | } | - | ||||||||||||
191 | - | |||||||||||||
192 | memset(&hints, 0, sizeof(hints)); | - | ||||||||||||
193 | hints.ai_socktype = SOCK_DGRAM; | - | ||||||||||||
194 | hints.ai_flags = AI_NUMERICHOST; | - | ||||||||||||
195 | - | |||||||||||||
196 | if (getaddrinfo(hostname, NULL, &hints, &ai) == 0) {
| 0 | ||||||||||||
197 | freeaddrinfo(ai); | - | ||||||||||||
198 | return -1; never executed: return -1; | 0 | ||||||||||||
199 | } | - | ||||||||||||
200 | - | |||||||||||||
201 | return 0; never executed: return 0; | 0 | ||||||||||||
202 | } | - | ||||||||||||
203 | - | |||||||||||||
204 | /* | - | ||||||||||||
205 | * Verify the given hostname, address and host key using DNS. | - | ||||||||||||
206 | * Returns 0 if lookup succeeds, -1 otherwise | - | ||||||||||||
207 | */ | - | ||||||||||||
208 | int | - | ||||||||||||
209 | verify_host_key_dns(const char *hostname, struct sockaddr *address, | - | ||||||||||||
210 | struct sshkey *hostkey, int *flags) | - | ||||||||||||
211 | { | - | ||||||||||||
212 | u_int counter; | - | ||||||||||||
213 | int result; | - | ||||||||||||
214 | struct rrsetinfo *fingerprints = NULL; | - | ||||||||||||
215 | - | |||||||||||||
216 | u_int8_t hostkey_algorithm; | - | ||||||||||||
217 | u_int8_t hostkey_digest_type = SSHFP_HASH_RESERVED; | - | ||||||||||||
218 | u_char *hostkey_digest; | - | ||||||||||||
219 | size_t hostkey_digest_len; | - | ||||||||||||
220 | - | |||||||||||||
221 | u_int8_t dnskey_algorithm; | - | ||||||||||||
222 | u_int8_t dnskey_digest_type; | - | ||||||||||||
223 | u_char *dnskey_digest; | - | ||||||||||||
224 | size_t dnskey_digest_len; | - | ||||||||||||
225 | - | |||||||||||||
226 | *flags = 0; | - | ||||||||||||
227 | - | |||||||||||||
228 | debug3("verify_host_key_dns"); | - | ||||||||||||
229 | if (hostkey == NULL)
| 0 | ||||||||||||
230 | fatal("No key to look up!"); never executed: fatal("No key to look up!"); | 0 | ||||||||||||
231 | - | |||||||||||||
232 | if (is_numeric_hostname(hostname)) {
| 0 | ||||||||||||
233 | debug("skipped DNS lookup for numerical hostname"); | - | ||||||||||||
234 | return -1; never executed: return -1; | 0 | ||||||||||||
235 | } | - | ||||||||||||
236 | - | |||||||||||||
237 | result = getrrsetbyname(hostname, DNS_RDATACLASS_IN, | - | ||||||||||||
238 | DNS_RDATATYPE_SSHFP, 0, &fingerprints); | - | ||||||||||||
239 | if (result) {
| 0 | ||||||||||||
240 | verbose("DNS lookup error: %s", dns_result_totext(result)); | - | ||||||||||||
241 | return -1; never executed: return -1; | 0 | ||||||||||||
242 | } | - | ||||||||||||
243 | - | |||||||||||||
244 | if (fingerprints->rri_flags & RRSET_VALIDATED) {
| 0 | ||||||||||||
245 | *flags |= DNS_VERIFY_SECURE; | - | ||||||||||||
246 | debug("found %d secure fingerprints in DNS", | - | ||||||||||||
247 | fingerprints->rri_nrdatas); | - | ||||||||||||
248 | } else { never executed: end of block | 0 | ||||||||||||
249 | debug("found %d insecure fingerprints in DNS", | - | ||||||||||||
250 | fingerprints->rri_nrdatas); | - | ||||||||||||
251 | } never executed: end of block | 0 | ||||||||||||
252 | - | |||||||||||||
253 | /* Initialize default host key parameters */ | - | ||||||||||||
254 | if (!dns_read_key(&hostkey_algorithm, &hostkey_digest_type,
| 0 | ||||||||||||
255 | &hostkey_digest, &hostkey_digest_len, hostkey)) {
| 0 | ||||||||||||
256 | error("Error calculating host key fingerprint."); | - | ||||||||||||
257 | freerrset(fingerprints); | - | ||||||||||||
258 | return -1; never executed: return -1; | 0 | ||||||||||||
259 | } | - | ||||||||||||
260 | - | |||||||||||||
261 | if (fingerprints->rri_nrdatas)
| 0 | ||||||||||||
262 | *flags |= DNS_VERIFY_FOUND; never executed: *flags |= 0x00000001; | 0 | ||||||||||||
263 | - | |||||||||||||
264 | for (counter = 0; counter < fingerprints->rri_nrdatas; counter++) {
| 0 | ||||||||||||
265 | /* | - | ||||||||||||
266 | * Extract the key from the answer. Ignore any badly | - | ||||||||||||
267 | * formatted fingerprints. | - | ||||||||||||
268 | */ | - | ||||||||||||
269 | if (!dns_read_rdata(&dnskey_algorithm, &dnskey_digest_type,
| 0 | ||||||||||||
270 | &dnskey_digest, &dnskey_digest_len,
| 0 | ||||||||||||
271 | fingerprints->rri_rdatas[counter].rdi_data,
| 0 | ||||||||||||
272 | fingerprints->rri_rdatas[counter].rdi_length)) {
| 0 | ||||||||||||
273 | verbose("Error parsing fingerprint from DNS."); | - | ||||||||||||
274 | continue; never executed: continue; | 0 | ||||||||||||
275 | } | - | ||||||||||||
276 | - | |||||||||||||
277 | if (hostkey_digest_type != dnskey_digest_type) {
| 0 | ||||||||||||
278 | hostkey_digest_type = dnskey_digest_type; | - | ||||||||||||
279 | free(hostkey_digest); | - | ||||||||||||
280 | - | |||||||||||||
281 | /* Initialize host key parameters */ | - | ||||||||||||
282 | if (!dns_read_key(&hostkey_algorithm,
| 0 | ||||||||||||
283 | &hostkey_digest_type, &hostkey_digest,
| 0 | ||||||||||||
284 | &hostkey_digest_len, hostkey)) {
| 0 | ||||||||||||
285 | error("Error calculating key fingerprint."); | - | ||||||||||||
286 | freerrset(fingerprints); | - | ||||||||||||
287 | return -1; never executed: return -1; | 0 | ||||||||||||
288 | } | - | ||||||||||||
289 | } never executed: end of block | 0 | ||||||||||||
290 | - | |||||||||||||
291 | /* Check if the current key is the same as the given key */ | - | ||||||||||||
292 | if (hostkey_algorithm == dnskey_algorithm &&
| 0 | ||||||||||||
293 | hostkey_digest_type == dnskey_digest_type) {
| 0 | ||||||||||||
294 | if (hostkey_digest_len == dnskey_digest_len &&
| 0 | ||||||||||||
295 | timingsafe_bcmp(hostkey_digest, dnskey_digest,
| 0 | ||||||||||||
296 | hostkey_digest_len) == 0)
| 0 | ||||||||||||
297 | *flags |= DNS_VERIFY_MATCH; never executed: *flags |= 0x00000002; | 0 | ||||||||||||
298 | } never executed: end of block | 0 | ||||||||||||
299 | free(dnskey_digest); | - | ||||||||||||
300 | } never executed: end of block | 0 | ||||||||||||
301 | - | |||||||||||||
302 | free(hostkey_digest); /* from sshkey_fingerprint_raw() */ | - | ||||||||||||
303 | freerrset(fingerprints); | - | ||||||||||||
304 | - | |||||||||||||
305 | if (*flags & DNS_VERIFY_FOUND)
| 0 | ||||||||||||
306 | if (*flags & DNS_VERIFY_MATCH)
| 0 | ||||||||||||
307 | debug("matching host key fingerprint found in DNS"); never executed: debug("matching host key fingerprint found in DNS"); | 0 | ||||||||||||
308 | else | - | ||||||||||||
309 | debug("mismatching host key fingerprint found in DNS"); never executed: debug("mismatching host key fingerprint found in DNS"); | 0 | ||||||||||||
310 | else | - | ||||||||||||
311 | debug("no host key fingerprint found in DNS"); never executed: debug("no host key fingerprint found in DNS"); | 0 | ||||||||||||
312 | - | |||||||||||||
313 | return 0; never executed: return 0; | 0 | ||||||||||||
314 | } | - | ||||||||||||
315 | - | |||||||||||||
316 | /* | - | ||||||||||||
317 | * Export the fingerprint of a key as a DNS resource record | - | ||||||||||||
318 | */ | - | ||||||||||||
319 | int | - | ||||||||||||
320 | export_dns_rr(const char *hostname, struct sshkey *key, FILE *f, int generic) | - | ||||||||||||
321 | { | - | ||||||||||||
322 | u_int8_t rdata_pubkey_algorithm = 0; | - | ||||||||||||
323 | u_int8_t rdata_digest_type = SSHFP_HASH_RESERVED; | - | ||||||||||||
324 | u_int8_t dtype; | - | ||||||||||||
325 | u_char *rdata_digest; | - | ||||||||||||
326 | size_t i, rdata_digest_len; | - | ||||||||||||
327 | int success = 0; | - | ||||||||||||
328 | - | |||||||||||||
329 | for (dtype = SSHFP_HASH_SHA1; dtype < SSHFP_HASH_MAX; dtype++) {
| 0 | ||||||||||||
330 | rdata_digest_type = dtype; | - | ||||||||||||
331 | if (dns_read_key(&rdata_pubkey_algorithm, &rdata_digest_type,
| 0 | ||||||||||||
332 | &rdata_digest, &rdata_digest_len, key)) {
| 0 | ||||||||||||
333 | if (generic) {
| 0 | ||||||||||||
334 | fprintf(f, "%s IN TYPE%d \\# %zu %02x %02x ", | - | ||||||||||||
335 | hostname, DNS_RDATATYPE_SSHFP, | - | ||||||||||||
336 | 2 + rdata_digest_len, | - | ||||||||||||
337 | rdata_pubkey_algorithm, rdata_digest_type); | - | ||||||||||||
338 | } else { never executed: end of block | 0 | ||||||||||||
339 | fprintf(f, "%s IN SSHFP %d %d ", hostname, | - | ||||||||||||
340 | rdata_pubkey_algorithm, rdata_digest_type); | - | ||||||||||||
341 | } never executed: end of block | 0 | ||||||||||||
342 | for (i = 0; i < rdata_digest_len; i++)
| 0 | ||||||||||||
343 | fprintf(f, "%02x", rdata_digest[i]); never executed: fprintf(f, "%02x", rdata_digest[i]); | 0 | ||||||||||||
344 | fprintf(f, "\n"); | - | ||||||||||||
345 | free(rdata_digest); /* from sshkey_fingerprint_raw() */ | - | ||||||||||||
346 | success = 1; | - | ||||||||||||
347 | } never executed: end of block | 0 | ||||||||||||
348 | } never executed: end of block | 0 | ||||||||||||
349 | - | |||||||||||||
350 | /* No SSHFP record was generated at all */ | - | ||||||||||||
351 | if (success == 0) {
| 0 | ||||||||||||
352 | error("%s: unsupported algorithm and/or digest_type", __func__); | - | ||||||||||||
353 | } never executed: end of block | 0 | ||||||||||||
354 | - | |||||||||||||
355 | return success; never executed: return success; | 0 | ||||||||||||
356 | } | - | ||||||||||||
Source code | Switch to Preprocessed file |