1#ifndef __APPLE__ 2static const char rcsid[] = "$Header: /Users/Shared/libresolv_2/libresolv/dst_support.c,v 1.1 2006/03/01 19:01:36 majka Exp $"; 3#endif 4 5 6/* 7 * Portions Copyright (c) 1995-1998 by Trusted Information Systems, Inc. 8 * 9 * Permission to use, copy modify, and distribute this software for any 10 * purpose with or without fee is hereby granted, provided that the above 11 * copyright notice and this permission notice appear in all copies. 12 * 13 * THE SOFTWARE IS PROVIDED "AS IS" AND TRUSTED INFORMATION SYSTEMS 14 * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL 16 * TRUSTED INFORMATION SYSTEMS BE LIABLE FOR ANY SPECIAL, DIRECT, 17 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING 18 * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, 19 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION 20 * WITH THE USE OR PERFORMANCE OF THE SOFTWARE. 21 */ 22 23#ifndef __APPLE__ 24#include "port_before.h" 25#endif 26 27#include <stdio.h> 28#include <unistd.h> 29#include <memory.h> 30#include <string.h> 31#include <errno.h> 32#include <sys/stat.h> 33#include <netinet/in.h> 34#include <arpa/nameser.h> 35#include <resolv.h> 36 37#include "dst_internal.h" 38 39#ifndef __APPLE__ 40#include "port_after.h" 41#endif 42 43/* 44 * dst_s_verify_str() 45 * Validate that the input string(*str) is at the head of the input 46 * buffer(**buf). If so, move the buffer head pointer (*buf) to 47 * the first byte of data following the string(*str). 48 * Parameters 49 * buf Input buffer. 50 * str Input string. 51 * Return 52 * 0 *str is not the head of **buff 53 * 1 *str is the head of **buff, *buf is is advanced to 54 * the tail of **buf. 55 */ 56 57int 58dst_s_verify_str(const char **buf, const char *str) 59{ 60 int b, s; 61 if (*buf == NULL) /* error checks */ 62 return (0); 63 if (str == NULL || *str == '\0') 64 return (1); 65 66 b = strlen(*buf); /* get length of strings */ 67 s = strlen(str); 68 if (s > b || strncmp(*buf, str, s)) /* check if same */ 69 return (0); /* not a match */ 70 (*buf) += s; /* advance pointer */ 71 return (1); 72} 73 74#ifdef _UNUSED_API_ 75/* 76 * dst_s_calculate_bits 77 * Given a binary number represented in a u_char[], determine 78 * the number of significant bits used. 79 * Parameters 80 * str An input character string containing a binary number. 81 * max_bits The maximum possible significant bits. 82 * Return 83 * N The number of significant bits in str. 84 */ 85 86int 87dst_s_calculate_bits(const u_char *str, const int max_bits) 88{ 89 const u_char *p = str; 90 u_char i, j = 0x80; 91 int bits; 92 for (bits = max_bits; *p == 0x00 && bits > 0; p++) 93 bits -= 8; 94 for (i = *p; (i & j) != j; j >>= 1) 95 bits--; 96 return (bits); 97} 98#endif 99 100/* 101 * calculates a checksum used in dst for an id. 102 * takes an array of bytes and a length. 103 * returns a 16 bit checksum. 104 */ 105#ifdef __APPLE__ 106static 107#endif 108u_int16_t 109dst_s_id_calc(const u_char *key, const int keysize) 110{ 111 u_int32_t ac; 112 const u_char *kp = key; 113 int size = keysize; 114 115 if (!key || (keysize <= 0)) 116 return (-1); 117 118 for (ac = 0; size > 1; size -= 2, kp += 2) 119 ac += ((*kp) << 8) + *(kp + 1); 120 121 if (size > 0) 122 ac += ((*kp) << 8); 123 ac += (ac >> 16) & 0xffff; 124 125 return (ac & 0xffff); 126} 127 128/* 129 * dst_s_dns_key_id() Function to calculate DNSSEC footprint from KEY record 130 * rdata 131 * Input: 132 * dns_key_rdata: the raw data in wire format 133 * rdata_len: the size of the input data 134 * Output: 135 * the key footprint/id calculated from the key data 136 */ 137u_int16_t 138dst_s_dns_key_id(const u_char *dns_key_rdata, const int rdata_len) 139{ 140 if (!dns_key_rdata) 141 return 0; 142 143 /* compute id */ 144 if (dns_key_rdata[3] == KEY_RSA) /* Algorithm RSA */ 145 return dst_s_get_int16((const u_char *) 146 &dns_key_rdata[rdata_len - 3]); 147 else if (dns_key_rdata[3] == KEY_HMAC_MD5) 148 /* compatibility */ 149 return 0; 150 else 151 /* compute a checksum on the key part of the key rr */ 152 return dst_s_id_calc(dns_key_rdata, rdata_len); 153} 154 155/* 156 * dst_s_get_int16 157 * This routine extracts a 16 bit integer from a two byte character 158 * string. The character string is assumed to be in network byte 159 * order and may be unaligned. The number returned is in host order. 160 * Parameter 161 * buf A two byte character string. 162 * Return 163 * The converted integer value. 164 */ 165 166u_int16_t 167dst_s_get_int16(const u_char *buf) 168{ 169 register u_int16_t a = 0; 170 a = ((u_int16_t)(buf[0] << 8)) | ((u_int16_t)(buf[1])); 171 return (a); 172} 173 174 175#ifdef _UNUSED_API_ 176/* 177 * dst_s_get_int32 178 * This routine extracts a 32 bit integer from a four byte character 179 * string. The character string is assumed to be in network byte 180 * order and may be unaligned. The number returned is in host order. 181 * Parameter 182 * buf A four byte character string. 183 * Return 184 * The converted integer value. 185 */ 186 187u_int32_t 188dst_s_get_int32(const u_char *buf) 189{ 190 register u_int32_t a = 0; 191 a = ((u_int32_t)(buf[0] << 24)) | ((u_int32_t)(buf[1] << 16)) | 192 ((u_int32_t)(buf[2] << 8)) | ((u_int32_t)(buf[3])); 193 return (a); 194} 195#endif 196 197/* 198 * dst_s_put_int16 199 * Take a 16 bit integer and store the value in a two byte 200 * character string. The integer is assumed to be in network 201 * order and the string is returned in host order. 202 * 203 * Parameters 204 * buf Storage for a two byte character string. 205 * val 16 bit integer. 206 */ 207 208void 209dst_s_put_int16(u_int8_t *buf, const u_int16_t val) 210{ 211 buf[0] = (u_int8_t)(val >> 8); 212 buf[1] = (u_int8_t)(val); 213} 214 215#ifdef _UNUSED_API_ 216/* 217 * dst_s_put_int32 218 * Take a 32 bit integer and store the value in a four byte 219 * character string. The integer is assumed to be in network 220 * order and the string is returned in host order. 221 * 222 * Parameters 223 * buf Storage for a four byte character string. 224 * val 32 bit integer. 225 */ 226 227void 228dst_s_put_int32(u_int8_t *buf, const u_int32_t val) 229{ 230 buf[0] = (u_int8_t)(val >> 24); 231 buf[1] = (u_int8_t)(val >> 16); 232 buf[2] = (u_int8_t)(val >> 8); 233 buf[3] = (u_int8_t)(val); 234} 235#endif 236 237 238#ifdef _UNUSED_API_ 239/* 240 * dst_s_filename_length 241 * 242 * This function returns the number of bytes needed to hold the 243 * filename for a key file. '/', '\' and ':' are not allowed. 244 * form: K<keyname>+<alg>+<id>.<suffix> 245 * 246 * Returns 0 if the filename would contain either '\', '/' or ':' 247 */ 248size_t 249dst_s_filename_length(const char *name, const char *suffix) 250{ 251 if (name == NULL) 252 return (0); 253 if (strrchr(name, '\\')) 254 return (0); 255 if (strrchr(name, '/')) 256 return (0); 257 if (strrchr(name, ':')) 258 return (0); 259 if (suffix == NULL) 260 return (0); 261 if (strrchr(suffix, '\\')) 262 return (0); 263 if (strrchr(suffix, '/')) 264 return (0); 265 if (strrchr(suffix, ':')) 266 return (0); 267 return (1 + strlen(name) + 6 + strlen(suffix)); 268} 269#endif 270 271/* 272 * dst_s_build_filename () 273 * Builds a key filename from the key name, it's id, and a 274 * suffix. '\', '/' and ':' are not allowed. fA filename is of the 275 * form: K<keyname><id>.<suffix> 276 * form: K<keyname>+<alg>+<id>.<suffix> 277 * 278 * Returns -1 if the conversion fails: 279 * if the filename would be too long for space allotted 280 * if the filename would contain a '\', '/' or ':' 281 * Returns 0 on success 282 */ 283 284int 285dst_s_build_filename(char *filename, const char *name, u_int16_t id, 286 int alg, const char *suffix, size_t filename_length) 287{ 288 u_int32_t my_id; 289 if (filename == NULL) 290 return (-1); 291 memset(filename, 0, filename_length); 292 if (name == NULL) 293 return (-1); 294 if (suffix == NULL) 295 return (-1); 296 if (filename_length < 1 + strlen(name) + 4 + 6 + 1 + strlen(suffix)) 297 return (-1); 298 my_id = id; 299 sprintf(filename, "K%s+%03d+%05d.%s", name, alg, my_id, 300 (const char *) suffix); 301 if (strrchr(filename, '/')) 302 return (-1); 303 if (strrchr(filename, '\\')) 304 return (-1); 305 if (strrchr(filename, ':')) 306 return (-1); 307 return (0); 308} 309 310/* 311 * dst_s_fopen () 312 * Open a file in the dst_path directory. If perm is specified, the 313 * file is checked for existence first, and not opened if it exists. 314 * Parameters 315 * filename File to open 316 * mode Mode to open the file (passed directly to fopen) 317 * perm File permission, if creating a new file. 318 * Returns 319 * NULL Failure 320 * NON-NULL (FILE *) of opened file. 321 */ 322FILE * 323dst_s_fopen(const char *filename, const char *mode, int perm) 324{ 325 FILE *fp; 326 char pathname[PATH_MAX]; 327 size_t plen = sizeof(pathname); 328 329 if (*dst_path != '\0') { 330 strcpy(pathname, dst_path); 331 plen -= strlen(pathname); 332 } 333 else 334 pathname[0] = '\0'; 335 336 if (plen > strlen(filename)) 337 strncpy(&pathname[PATH_MAX - plen], filename, plen-1); 338 else 339 return (NULL); 340 341 fp = fopen(pathname, mode); 342 if (perm) 343 chmod(pathname, perm); 344 return (fp); 345} 346 347#ifdef _UNUSED_API_ 348void 349dst_s_dump(const int mode, const u_char *data, const int size, 350 const char *msg) 351{ 352#ifndef __APPLE__ 353 UNUSED(data); 354#endif 355 356 if (size > 0) { 357#ifdef LONG_TEST 358 static u_char scratch[1000]; 359 int n ; 360 n = b64_ntop(data, scratch, size, sizeof(scratch)); 361 printf("%s: %x %d %s\n", msg, mode, n, scratch); 362#else 363 printf("%s,%x %d\n", msg, mode, size); 364#endif 365 } 366} 367#endif 368