1*0Sstevel@tonic-gate static const char rcsid[] = "$Header: /proj/cvs/isc/bind8/src/lib/dst/support.c,v 1.11 2001/05/29 05:48:16 marka Exp $"; 2*0Sstevel@tonic-gate 3*0Sstevel@tonic-gate /* 4*0Sstevel@tonic-gate * Copyright 2001-2002 Sun Microsystems, Inc. All rights reserved. 5*0Sstevel@tonic-gate * Use is subject to license terms. 6*0Sstevel@tonic-gate */ 7*0Sstevel@tonic-gate 8*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 9*0Sstevel@tonic-gate 10*0Sstevel@tonic-gate /* 11*0Sstevel@tonic-gate * Portions Copyright (c) 1995-1998 by Trusted Information Systems, Inc. 12*0Sstevel@tonic-gate * 13*0Sstevel@tonic-gate * Permission to use, copy modify, and distribute this software for any 14*0Sstevel@tonic-gate * purpose with or without fee is hereby granted, provided that the above 15*0Sstevel@tonic-gate * copyright notice and this permission notice appear in all copies. 16*0Sstevel@tonic-gate * 17*0Sstevel@tonic-gate * THE SOFTWARE IS PROVIDED "AS IS" AND TRUSTED INFORMATION SYSTEMS 18*0Sstevel@tonic-gate * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL 19*0Sstevel@tonic-gate * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL 20*0Sstevel@tonic-gate * TRUSTED INFORMATION SYSTEMS BE LIABLE FOR ANY SPECIAL, DIRECT, 21*0Sstevel@tonic-gate * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING 22*0Sstevel@tonic-gate * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, 23*0Sstevel@tonic-gate * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION 24*0Sstevel@tonic-gate * WITH THE USE OR PERFORMANCE OF THE SOFTWARE. 25*0Sstevel@tonic-gate */ 26*0Sstevel@tonic-gate 27*0Sstevel@tonic-gate #include "port_before.h" 28*0Sstevel@tonic-gate 29*0Sstevel@tonic-gate #include <stdio.h> 30*0Sstevel@tonic-gate #include <unistd.h> 31*0Sstevel@tonic-gate #include <memory.h> 32*0Sstevel@tonic-gate #include <string.h> 33*0Sstevel@tonic-gate #include <errno.h> 34*0Sstevel@tonic-gate #include <sys/stat.h> 35*0Sstevel@tonic-gate #include <netinet/in.h> 36*0Sstevel@tonic-gate #include <arpa/nameser.h> 37*0Sstevel@tonic-gate #include <resolv.h> 38*0Sstevel@tonic-gate 39*0Sstevel@tonic-gate #include "dst_internal.h" 40*0Sstevel@tonic-gate 41*0Sstevel@tonic-gate #include "port_after.h" 42*0Sstevel@tonic-gate /* 43*0Sstevel@tonic-gate * dst_s_conv_bignum_u8_to_b64 44*0Sstevel@tonic-gate * This function converts binary data stored as a u_char[] to a 45*0Sstevel@tonic-gate * base-64 string. Leading zeroes are discarded. If a header is 46*0Sstevel@tonic-gate * supplied, it is prefixed to the input prior to encoding. The 47*0Sstevel@tonic-gate * output is \n\0 terminated (the \0 is not included in output length). 48*0Sstevel@tonic-gate * Parameters 49*0Sstevel@tonic-gate * out_buf binary data to convert 50*0Sstevel@tonic-gate * header character string to prefix to the output (label) 51*0Sstevel@tonic-gate * bin_data binary data 52*0Sstevel@tonic-gate * bin_len size of binary data 53*0Sstevel@tonic-gate * Return 54*0Sstevel@tonic-gate * -1 not enough space in output work area 55*0Sstevel@tonic-gate * 0 no output 56*0Sstevel@tonic-gate * >0 number of bytes written to output work area 57*0Sstevel@tonic-gate */ 58*0Sstevel@tonic-gate 59*0Sstevel@tonic-gate int 60*0Sstevel@tonic-gate dst_s_conv_bignum_u8_to_b64(char *out_buf, const int out_len, 61*0Sstevel@tonic-gate const char *header, const u_char *bin_data, 62*0Sstevel@tonic-gate const int bin_len) 63*0Sstevel@tonic-gate { 64*0Sstevel@tonic-gate const u_char *bp = bin_data; 65*0Sstevel@tonic-gate char *op = out_buf; 66*0Sstevel@tonic-gate int lenh = 0, len64 = 0; 67*0Sstevel@tonic-gate int local_in_len = bin_len; 68*0Sstevel@tonic-gate int local_out_len = out_len; 69*0Sstevel@tonic-gate 70*0Sstevel@tonic-gate if (bin_data == NULL || bin_len <= 0) /* no data no */ 71*0Sstevel@tonic-gate return (0); 72*0Sstevel@tonic-gate 73*0Sstevel@tonic-gate if (out_buf == NULL || out_len <= 0) /* no output_work area */ 74*0Sstevel@tonic-gate return (-1); 75*0Sstevel@tonic-gate 76*0Sstevel@tonic-gate /* suppress leading \0 */ 77*0Sstevel@tonic-gate for (; (*bp == 0x0) && (local_in_len > 0); local_in_len--) 78*0Sstevel@tonic-gate bp++; 79*0Sstevel@tonic-gate 80*0Sstevel@tonic-gate if (header) { /* add header to output string */ 81*0Sstevel@tonic-gate lenh = strlen(header); 82*0Sstevel@tonic-gate if (lenh < out_len) 83*0Sstevel@tonic-gate memcpy(op, header, lenh); 84*0Sstevel@tonic-gate else 85*0Sstevel@tonic-gate return (-1); 86*0Sstevel@tonic-gate local_out_len -= lenh; 87*0Sstevel@tonic-gate op += lenh; 88*0Sstevel@tonic-gate } 89*0Sstevel@tonic-gate len64 = b64_ntop(bp, local_in_len, op, local_out_len - 2); 90*0Sstevel@tonic-gate if (len64 < 0) 91*0Sstevel@tonic-gate return (-1); 92*0Sstevel@tonic-gate op += len64++; 93*0Sstevel@tonic-gate *(op++) = '\n'; /* put CR in the output */ 94*0Sstevel@tonic-gate *op = '\0'; /* make sure output is 0 terminated */ 95*0Sstevel@tonic-gate return (lenh + len64); 96*0Sstevel@tonic-gate } 97*0Sstevel@tonic-gate 98*0Sstevel@tonic-gate 99*0Sstevel@tonic-gate /* 100*0Sstevel@tonic-gate * dst_s_verify_str() 101*0Sstevel@tonic-gate * Validate that the input string(*str) is at the head of the input 102*0Sstevel@tonic-gate * buffer(**buf). If so, move the buffer head pointer (*buf) to 103*0Sstevel@tonic-gate * the first byte of data following the string(*str). 104*0Sstevel@tonic-gate * Parameters 105*0Sstevel@tonic-gate * buf Input buffer. 106*0Sstevel@tonic-gate * str Input string. 107*0Sstevel@tonic-gate * Return 108*0Sstevel@tonic-gate * 0 *str is not the head of **buff 109*0Sstevel@tonic-gate * 1 *str is the head of **buff, *buf is is advanced to 110*0Sstevel@tonic-gate * the tail of **buf. 111*0Sstevel@tonic-gate */ 112*0Sstevel@tonic-gate 113*0Sstevel@tonic-gate int 114*0Sstevel@tonic-gate dst_s_verify_str(const char **buf, const char *str) 115*0Sstevel@tonic-gate { 116*0Sstevel@tonic-gate int b, s; 117*0Sstevel@tonic-gate if (*buf == NULL) /* error checks */ 118*0Sstevel@tonic-gate return (0); 119*0Sstevel@tonic-gate if (str == NULL || *str == '\0') 120*0Sstevel@tonic-gate return (1); 121*0Sstevel@tonic-gate 122*0Sstevel@tonic-gate b = strlen(*buf); /* get length of strings */ 123*0Sstevel@tonic-gate s = strlen(str); 124*0Sstevel@tonic-gate if (s > b || strncmp(*buf, str, s)) /* check if same */ 125*0Sstevel@tonic-gate return (0); /* not a match */ 126*0Sstevel@tonic-gate (*buf) += s; /* advance pointer */ 127*0Sstevel@tonic-gate return (1); 128*0Sstevel@tonic-gate } 129*0Sstevel@tonic-gate 130*0Sstevel@tonic-gate 131*0Sstevel@tonic-gate /* 132*0Sstevel@tonic-gate * dst_s_conv_bignum_b64_to_u8 133*0Sstevel@tonic-gate * Read a line of base-64 encoded string from the input buffer, 134*0Sstevel@tonic-gate * convert it to binary, and store it in an output area. The 135*0Sstevel@tonic-gate * input buffer is read until reaching a newline marker or the 136*0Sstevel@tonic-gate * end of the buffer. The binary data is stored in the last X 137*0Sstevel@tonic-gate * number of bytes of the output area where X is the size of the 138*0Sstevel@tonic-gate * binary output. If the operation is successful, the input buffer 139*0Sstevel@tonic-gate * pointer is advanced. This procedure does not do network to host 140*0Sstevel@tonic-gate * byte order conversion. 141*0Sstevel@tonic-gate * Parameters 142*0Sstevel@tonic-gate * buf Pointer to encoded input string. Pointer is updated if 143*0Sstevel@tonic-gate * function is successfull. 144*0Sstevel@tonic-gate * loc Output area. 145*0Sstevel@tonic-gate * loclen Size in bytes of output area. 146*0Sstevel@tonic-gate * Return 147*0Sstevel@tonic-gate * >0 Return = number of bytes of binary data stored in loc. 148*0Sstevel@tonic-gate * 0 Failure. 149*0Sstevel@tonic-gate */ 150*0Sstevel@tonic-gate 151*0Sstevel@tonic-gate int 152*0Sstevel@tonic-gate dst_s_conv_bignum_b64_to_u8(const char **buf, u_char *loc, const int loclen) 153*0Sstevel@tonic-gate { 154*0Sstevel@tonic-gate int blen; 155*0Sstevel@tonic-gate char *bp; 156*0Sstevel@tonic-gate u_char bstr[RAW_KEY_SIZE]; 157*0Sstevel@tonic-gate 158*0Sstevel@tonic-gate if (buf == NULL || *buf == NULL) { /* error checks */ 159*0Sstevel@tonic-gate EREPORT(("dst_s_conv_bignum_b64_to_u8: null input buffer.\n")); 160*0Sstevel@tonic-gate return (0); 161*0Sstevel@tonic-gate } 162*0Sstevel@tonic-gate bp = strchr(*buf, '\n'); /* find length of input line */ 163*0Sstevel@tonic-gate if (bp != NULL) 164*0Sstevel@tonic-gate *bp = (u_char) NULL; 165*0Sstevel@tonic-gate 166*0Sstevel@tonic-gate blen = b64_pton(*buf, bstr, sizeof(bstr)); 167*0Sstevel@tonic-gate if (blen <= 0) { 168*0Sstevel@tonic-gate EREPORT(("dst_s_conv_bignum_b64_to_u8: decoded value is null.\n")); 169*0Sstevel@tonic-gate return (0); 170*0Sstevel@tonic-gate } 171*0Sstevel@tonic-gate else if (loclen < blen) { 172*0Sstevel@tonic-gate EREPORT(("dst_s_conv_bignum_b64_to_u8: decoded value is longer than output buffer.\n")); 173*0Sstevel@tonic-gate return (0); 174*0Sstevel@tonic-gate } 175*0Sstevel@tonic-gate if (bp) 176*0Sstevel@tonic-gate *buf = bp; /* advancing buffer past \n */ 177*0Sstevel@tonic-gate memset(loc, 0, loclen - blen); /* clearing unused output area */ 178*0Sstevel@tonic-gate memcpy(loc + loclen - blen, bstr, blen); /* write last blen bytes */ 179*0Sstevel@tonic-gate return (blen); 180*0Sstevel@tonic-gate } 181*0Sstevel@tonic-gate 182*0Sstevel@tonic-gate 183*0Sstevel@tonic-gate /* 184*0Sstevel@tonic-gate * dst_s_calculate_bits 185*0Sstevel@tonic-gate * Given a binary number represented in a u_char[], determine 186*0Sstevel@tonic-gate * the number of significant bits used. 187*0Sstevel@tonic-gate * Parameters 188*0Sstevel@tonic-gate * str An input character string containing a binary number. 189*0Sstevel@tonic-gate * max_bits The maximum possible significant bits. 190*0Sstevel@tonic-gate * Return 191*0Sstevel@tonic-gate * N The number of significant bits in str. 192*0Sstevel@tonic-gate */ 193*0Sstevel@tonic-gate 194*0Sstevel@tonic-gate int 195*0Sstevel@tonic-gate dst_s_calculate_bits(const u_char *str, const int max_bits) 196*0Sstevel@tonic-gate { 197*0Sstevel@tonic-gate const u_char *p = str; 198*0Sstevel@tonic-gate u_char i, j = 0x80; 199*0Sstevel@tonic-gate int bits; 200*0Sstevel@tonic-gate for (bits = max_bits; *p == 0x00 && bits > 0; p++) 201*0Sstevel@tonic-gate bits -= 8; 202*0Sstevel@tonic-gate for (i = *p; (i & j) != j; j >>= 1) 203*0Sstevel@tonic-gate bits--; 204*0Sstevel@tonic-gate return (bits); 205*0Sstevel@tonic-gate } 206*0Sstevel@tonic-gate 207*0Sstevel@tonic-gate 208*0Sstevel@tonic-gate /* 209*0Sstevel@tonic-gate * calculates a checksum used in dst for an id. 210*0Sstevel@tonic-gate * takes an array of bytes and a length. 211*0Sstevel@tonic-gate * returns a 16 bit checksum. 212*0Sstevel@tonic-gate */ 213*0Sstevel@tonic-gate u_int16_t 214*0Sstevel@tonic-gate dst_s_id_calc(const u_char *key, const int keysize) 215*0Sstevel@tonic-gate { 216*0Sstevel@tonic-gate u_int32_t ac; 217*0Sstevel@tonic-gate const u_char *kp = key; 218*0Sstevel@tonic-gate int size = keysize; 219*0Sstevel@tonic-gate 220*0Sstevel@tonic-gate if (!key || (keysize <= 0)) 221*0Sstevel@tonic-gate return (-1); 222*0Sstevel@tonic-gate 223*0Sstevel@tonic-gate for (ac = 0; size > 1; size -= 2, kp += 2) 224*0Sstevel@tonic-gate ac += ((*kp) << 8) + *(kp + 1); 225*0Sstevel@tonic-gate 226*0Sstevel@tonic-gate if (size > 0) 227*0Sstevel@tonic-gate ac += ((*kp) << 8); 228*0Sstevel@tonic-gate ac += (ac >> 16) & 0xffff; 229*0Sstevel@tonic-gate 230*0Sstevel@tonic-gate return (ac & 0xffff); 231*0Sstevel@tonic-gate } 232*0Sstevel@tonic-gate 233*0Sstevel@tonic-gate /* 234*0Sstevel@tonic-gate * dst_s_dns_key_id() Function to calculate DNSSEC footprint from KEY record 235*0Sstevel@tonic-gate * rdata 236*0Sstevel@tonic-gate * Input: 237*0Sstevel@tonic-gate * dns_key_rdata: the raw data in wire format 238*0Sstevel@tonic-gate * rdata_len: the size of the input data 239*0Sstevel@tonic-gate * Output: 240*0Sstevel@tonic-gate * the key footprint/id calculated from the key data 241*0Sstevel@tonic-gate */ 242*0Sstevel@tonic-gate u_int16_t 243*0Sstevel@tonic-gate dst_s_dns_key_id(const u_char *dns_key_rdata, const int rdata_len) 244*0Sstevel@tonic-gate { 245*0Sstevel@tonic-gate if (!dns_key_rdata) 246*0Sstevel@tonic-gate return 0; 247*0Sstevel@tonic-gate 248*0Sstevel@tonic-gate /* compute id */ 249*0Sstevel@tonic-gate if (dns_key_rdata[3] == KEY_RSA) /* Algorithm RSA */ 250*0Sstevel@tonic-gate return dst_s_get_int16((const u_char *) 251*0Sstevel@tonic-gate &dns_key_rdata[rdata_len - 3]); 252*0Sstevel@tonic-gate else if (dns_key_rdata[3] == KEY_HMAC_MD5) 253*0Sstevel@tonic-gate /* compatibility */ 254*0Sstevel@tonic-gate return 0; 255*0Sstevel@tonic-gate else 256*0Sstevel@tonic-gate /* compute a checksum on the key part of the key rr */ 257*0Sstevel@tonic-gate return dst_s_id_calc(dns_key_rdata, rdata_len); 258*0Sstevel@tonic-gate } 259*0Sstevel@tonic-gate 260*0Sstevel@tonic-gate /* 261*0Sstevel@tonic-gate * dst_s_get_int16 262*0Sstevel@tonic-gate * This routine extracts a 16 bit integer from a two byte character 263*0Sstevel@tonic-gate * string. The character string is assumed to be in network byte 264*0Sstevel@tonic-gate * order and may be unaligned. The number returned is in host order. 265*0Sstevel@tonic-gate * Parameter 266*0Sstevel@tonic-gate * buf A two byte character string. 267*0Sstevel@tonic-gate * Return 268*0Sstevel@tonic-gate * The converted integer value. 269*0Sstevel@tonic-gate */ 270*0Sstevel@tonic-gate 271*0Sstevel@tonic-gate u_int16_t 272*0Sstevel@tonic-gate dst_s_get_int16(const u_char *buf) 273*0Sstevel@tonic-gate { 274*0Sstevel@tonic-gate register u_int16_t a = 0; 275*0Sstevel@tonic-gate a = ((u_int16_t)(buf[0] << 8)) | ((u_int16_t)(buf[1])); 276*0Sstevel@tonic-gate return (a); 277*0Sstevel@tonic-gate } 278*0Sstevel@tonic-gate 279*0Sstevel@tonic-gate 280*0Sstevel@tonic-gate /* 281*0Sstevel@tonic-gate * dst_s_get_int32 282*0Sstevel@tonic-gate * This routine extracts a 32 bit integer from a four byte character 283*0Sstevel@tonic-gate * string. The character string is assumed to be in network byte 284*0Sstevel@tonic-gate * order and may be unaligned. The number returned is in host order. 285*0Sstevel@tonic-gate * Parameter 286*0Sstevel@tonic-gate * buf A four byte character string. 287*0Sstevel@tonic-gate * Return 288*0Sstevel@tonic-gate * The converted integer value. 289*0Sstevel@tonic-gate */ 290*0Sstevel@tonic-gate 291*0Sstevel@tonic-gate u_int32_t 292*0Sstevel@tonic-gate dst_s_get_int32(const u_char *buf) 293*0Sstevel@tonic-gate { 294*0Sstevel@tonic-gate register u_int32_t a = 0; 295*0Sstevel@tonic-gate a = ((u_int32_t)(buf[0] << 24)) | ((u_int32_t)(buf[1] << 16)) | 296*0Sstevel@tonic-gate ((u_int32_t)(buf[2] << 8)) | ((u_int32_t)(buf[3])); 297*0Sstevel@tonic-gate return (a); 298*0Sstevel@tonic-gate } 299*0Sstevel@tonic-gate 300*0Sstevel@tonic-gate 301*0Sstevel@tonic-gate /* 302*0Sstevel@tonic-gate * dst_s_put_int16 303*0Sstevel@tonic-gate * Take a 16 bit integer and store the value in a two byte 304*0Sstevel@tonic-gate * character string. The integer is assumed to be in network 305*0Sstevel@tonic-gate * order and the string is returned in host order. 306*0Sstevel@tonic-gate * 307*0Sstevel@tonic-gate * Parameters 308*0Sstevel@tonic-gate * buf Storage for a two byte character string. 309*0Sstevel@tonic-gate * val 16 bit integer. 310*0Sstevel@tonic-gate */ 311*0Sstevel@tonic-gate 312*0Sstevel@tonic-gate void 313*0Sstevel@tonic-gate dst_s_put_int16(u_int8_t *buf, const u_int16_t val) 314*0Sstevel@tonic-gate { 315*0Sstevel@tonic-gate buf[0] = (u_int8_t)(val >> 8); 316*0Sstevel@tonic-gate buf[1] = (u_int8_t)(val); 317*0Sstevel@tonic-gate } 318*0Sstevel@tonic-gate 319*0Sstevel@tonic-gate 320*0Sstevel@tonic-gate /* 321*0Sstevel@tonic-gate * dst_s_put_int32 322*0Sstevel@tonic-gate * Take a 32 bit integer and store the value in a four byte 323*0Sstevel@tonic-gate * character string. The integer is assumed to be in network 324*0Sstevel@tonic-gate * order and the string is returned in host order. 325*0Sstevel@tonic-gate * 326*0Sstevel@tonic-gate * Parameters 327*0Sstevel@tonic-gate * buf Storage for a four byte character string. 328*0Sstevel@tonic-gate * val 32 bit integer. 329*0Sstevel@tonic-gate */ 330*0Sstevel@tonic-gate 331*0Sstevel@tonic-gate void 332*0Sstevel@tonic-gate dst_s_put_int32(u_int8_t *buf, const u_int32_t val) 333*0Sstevel@tonic-gate { 334*0Sstevel@tonic-gate buf[0] = (u_int8_t)(val >> 24); 335*0Sstevel@tonic-gate buf[1] = (u_int8_t)(val >> 16); 336*0Sstevel@tonic-gate buf[2] = (u_int8_t)(val >> 8); 337*0Sstevel@tonic-gate buf[3] = (u_int8_t)(val); 338*0Sstevel@tonic-gate } 339*0Sstevel@tonic-gate 340*0Sstevel@tonic-gate 341*0Sstevel@tonic-gate /* 342*0Sstevel@tonic-gate * dst_s_filename_length 343*0Sstevel@tonic-gate * 344*0Sstevel@tonic-gate * This function returns the number of bytes needed to hold the 345*0Sstevel@tonic-gate * filename for a key file. '/', '\' and ':' are not allowed. 346*0Sstevel@tonic-gate * form: K<keyname>+<alg>+<id>.<suffix> 347*0Sstevel@tonic-gate * 348*0Sstevel@tonic-gate * Returns 0 if the filename would contain either '\', '/' or ':' 349*0Sstevel@tonic-gate */ 350*0Sstevel@tonic-gate size_t 351*0Sstevel@tonic-gate dst_s_filename_length(const char *name, const char *suffix) 352*0Sstevel@tonic-gate { 353*0Sstevel@tonic-gate if (name == NULL) 354*0Sstevel@tonic-gate return (0); 355*0Sstevel@tonic-gate if (strrchr(name, '\\')) 356*0Sstevel@tonic-gate return (0); 357*0Sstevel@tonic-gate if (strrchr(name, '/')) 358*0Sstevel@tonic-gate return (0); 359*0Sstevel@tonic-gate if (strrchr(name, ':')) 360*0Sstevel@tonic-gate return (0); 361*0Sstevel@tonic-gate if (suffix == NULL) 362*0Sstevel@tonic-gate return (0); 363*0Sstevel@tonic-gate if (strrchr(suffix, '\\')) 364*0Sstevel@tonic-gate return (0); 365*0Sstevel@tonic-gate if (strrchr(suffix, '/')) 366*0Sstevel@tonic-gate return (0); 367*0Sstevel@tonic-gate if (strrchr(suffix, ':')) 368*0Sstevel@tonic-gate return (0); 369*0Sstevel@tonic-gate return (1 + strlen(name) + 6 + strlen(suffix)); 370*0Sstevel@tonic-gate } 371*0Sstevel@tonic-gate 372*0Sstevel@tonic-gate 373*0Sstevel@tonic-gate /* 374*0Sstevel@tonic-gate * dst_s_build_filename () 375*0Sstevel@tonic-gate * Builds a key filename from the key name, it's id, and a 376*0Sstevel@tonic-gate * suffix. '\', '/' and ':' are not allowed. fA filename is of the 377*0Sstevel@tonic-gate * form: K<keyname><id>.<suffix> 378*0Sstevel@tonic-gate * form: K<keyname>+<alg>+<id>.<suffix> 379*0Sstevel@tonic-gate * 380*0Sstevel@tonic-gate * Returns -1 if the conversion fails: 381*0Sstevel@tonic-gate * if the filename would be too long for space allotted 382*0Sstevel@tonic-gate * if the filename would contain a '\', '/' or ':' 383*0Sstevel@tonic-gate * Returns 0 on success 384*0Sstevel@tonic-gate */ 385*0Sstevel@tonic-gate 386*0Sstevel@tonic-gate int 387*0Sstevel@tonic-gate dst_s_build_filename(char *filename, const char *name, u_int16_t id, 388*0Sstevel@tonic-gate int alg, const char *suffix, size_t filename_length) 389*0Sstevel@tonic-gate { 390*0Sstevel@tonic-gate u_int32_t my_id; 391*0Sstevel@tonic-gate if (filename == NULL) 392*0Sstevel@tonic-gate return (-1); 393*0Sstevel@tonic-gate memset(filename, 0, filename_length); 394*0Sstevel@tonic-gate if (name == NULL) 395*0Sstevel@tonic-gate return (-1); 396*0Sstevel@tonic-gate if (suffix == NULL) 397*0Sstevel@tonic-gate return (-1); 398*0Sstevel@tonic-gate if (filename_length < 1 + strlen(name) + 4 + 6 + 1 + strlen(suffix)) 399*0Sstevel@tonic-gate return (-1); 400*0Sstevel@tonic-gate my_id = id; 401*0Sstevel@tonic-gate sprintf(filename, "K%s+%03d+%05d.%s", name, alg, my_id, 402*0Sstevel@tonic-gate (const char *) suffix); 403*0Sstevel@tonic-gate if (strrchr(filename, '/')) 404*0Sstevel@tonic-gate return (-1); 405*0Sstevel@tonic-gate if (strrchr(filename, '\\')) 406*0Sstevel@tonic-gate return (-1); 407*0Sstevel@tonic-gate if (strrchr(filename, ':')) 408*0Sstevel@tonic-gate return (-1); 409*0Sstevel@tonic-gate return (0); 410*0Sstevel@tonic-gate } 411*0Sstevel@tonic-gate 412*0Sstevel@tonic-gate /* 413*0Sstevel@tonic-gate * dst_s_fopen () 414*0Sstevel@tonic-gate * Open a file in the dst_path directory. If perm is specified, the 415*0Sstevel@tonic-gate * file is checked for existence first, and not opened if it exists. 416*0Sstevel@tonic-gate * Parameters 417*0Sstevel@tonic-gate * filename File to open 418*0Sstevel@tonic-gate * mode Mode to open the file (passed directly to fopen) 419*0Sstevel@tonic-gate * perm File permission, if creating a new file. 420*0Sstevel@tonic-gate * Returns 421*0Sstevel@tonic-gate * NULL Failure 422*0Sstevel@tonic-gate * NON-NULL (FILE *) of opened file. 423*0Sstevel@tonic-gate */ 424*0Sstevel@tonic-gate FILE * 425*0Sstevel@tonic-gate dst_s_fopen(const char *filename, const char *mode, int perm) 426*0Sstevel@tonic-gate { 427*0Sstevel@tonic-gate FILE *fp; 428*0Sstevel@tonic-gate char pathname[PATH_MAX]; 429*0Sstevel@tonic-gate size_t plen = sizeof(pathname); 430*0Sstevel@tonic-gate 431*0Sstevel@tonic-gate if (*dst_path != '\0') { 432*0Sstevel@tonic-gate strcpy(pathname, dst_path); 433*0Sstevel@tonic-gate plen -= strlen(pathname); 434*0Sstevel@tonic-gate } 435*0Sstevel@tonic-gate else 436*0Sstevel@tonic-gate pathname[0] = '\0'; 437*0Sstevel@tonic-gate 438*0Sstevel@tonic-gate if (plen > strlen(filename)) 439*0Sstevel@tonic-gate strncpy(&pathname[PATH_MAX - plen], filename, plen-1); 440*0Sstevel@tonic-gate else 441*0Sstevel@tonic-gate return (NULL); 442*0Sstevel@tonic-gate 443*0Sstevel@tonic-gate fp = fopen(pathname, mode); 444*0Sstevel@tonic-gate if (perm) 445*0Sstevel@tonic-gate chmod(pathname, perm); 446*0Sstevel@tonic-gate return (fp); 447*0Sstevel@tonic-gate } 448*0Sstevel@tonic-gate 449*0Sstevel@tonic-gate void 450*0Sstevel@tonic-gate dst_s_dump(const int mode, const u_char *data, const int size, 451*0Sstevel@tonic-gate const char *msg) 452*0Sstevel@tonic-gate { 453*0Sstevel@tonic-gate UNUSED(data); 454*0Sstevel@tonic-gate 455*0Sstevel@tonic-gate if (size > 0) { 456*0Sstevel@tonic-gate #ifdef LONG_TEST 457*0Sstevel@tonic-gate static u_char scratch[1000]; 458*0Sstevel@tonic-gate int n ; 459*0Sstevel@tonic-gate n = b64_ntop(data, scratch, size, sizeof(scratch)); 460*0Sstevel@tonic-gate printf("%s: %x %d %s\n", msg, mode, n, scratch); 461*0Sstevel@tonic-gate #else 462*0Sstevel@tonic-gate printf("%s,%x %d\n", msg, mode, size); 463*0Sstevel@tonic-gate #endif 464*0Sstevel@tonic-gate } 465*0Sstevel@tonic-gate } 466