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