1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 #include <ctype.h> 29 #include <stdio.h> 30 #include <string.h> 31 #include <stdlib.h> 32 #include <pthread.h> 33 #include <syslog.h> 34 #include <sys/varargs.h> 35 #include <sys/types.h> 36 #include <smbsrv/string.h> 37 38 #define C2H(c) "0123456789ABCDEF"[(c)] 39 #define H2C(c) (((c) >= '0' && (c) <= '9') ? ((c) - '0') : \ 40 ((c) >= 'a' && (c) <= 'f') ? ((c) - 'a' + 10) : \ 41 ((c) >= 'A' && (c) <= 'F') ? ((c) - 'A' + 10) : \ 42 '\0') 43 #define DEFAULT_SBOX_SIZE 256 44 45 /* 46 * 47 * hexdump 48 * 49 * Simple hex dump display function. Displays nbytes of buffer in hex and 50 * printable format. Non-printing characters are shown as '.'. It is safe 51 * to pass a null pointer. Each line begins with the offset. If nbytes is 52 * 0, the line will be blank except for the offset. Example output: 53 * 54 * 00000000 54 68 69 73 20 69 73 20 61 20 70 72 6F 67 72 61 This is a progra 55 * 00000010 6D 20 74 65 73 74 2E 00 m test.. 56 * 57 */ 58 void 59 hexdump_offset(unsigned char *buffer, int nbytes, unsigned long *start, int log) 60 { 61 static char *hex = "0123456789ABCDEF"; 62 int i, count; 63 int offset; 64 unsigned char *p; 65 char ascbuf[64]; 66 char hexbuf[64]; 67 char *ap = ascbuf; 68 char *hp = hexbuf; 69 70 if ((p = buffer) == 0) { 71 if (log) 72 syslog(LOG_DEBUG, "hexdump: (null)"); 73 else 74 (void) printf("hexdump: (null)\n"); 75 return; 76 } 77 78 offset = *start; 79 80 *ap = '\0'; 81 *hp = '\0'; 82 count = 0; 83 84 for (i = 0; i < nbytes; ++i) { 85 if (i && (i % 16) == 0) { 86 if (log) 87 syslog(LOG_DEBUG, 88 "%06X %s %s", offset, hexbuf, ascbuf); 89 else 90 (void) printf("%06X %s %s\n", 91 offset, hexbuf, ascbuf); 92 ap = ascbuf; 93 hp = hexbuf; 94 count = 0; 95 offset += 16; 96 } 97 98 ap += sprintf(ap, "%c", 99 (*p >= 0x20 && *p < 0x7F) ? *p : '.'); 100 hp += sprintf(hp, " %c%c", 101 hex[(*p >> 4) & 0x0F], hex[(*p & 0x0F)]); 102 ++p; 103 ++count; 104 } 105 106 if (count) { 107 if (log) 108 syslog(LOG_DEBUG, 109 "%06X %-48s %s", offset, hexbuf, ascbuf); 110 else 111 (void) printf("%06X %-48s %s\n", 112 offset, hexbuf, ascbuf); 113 114 offset += count; 115 } 116 117 *start = offset; 118 } 119 120 void 121 hexdump(unsigned char *buffer, int nbytes) 122 { 123 unsigned long start = 0; 124 125 hexdump_offset(buffer, nbytes, &start, 1); 126 } 127 128 /* 129 * bintohex 130 * 131 * Converts the given binary data (srcbuf) to 132 * its equivalent hex chars (hexbuf). 133 * 134 * hexlen should be at least twice as srclen. 135 * if hexbuf is not big enough returns 0. 136 * otherwise returns number of valid chars in 137 * hexbuf which is srclen * 2. 138 */ 139 size_t 140 bintohex(const char *srcbuf, size_t srclen, 141 char *hexbuf, size_t hexlen) 142 { 143 size_t outlen; 144 char c; 145 146 outlen = srclen << 1; 147 148 if (hexlen < outlen) 149 return (0); 150 151 while (srclen-- > 0) { 152 c = *srcbuf++; 153 *hexbuf++ = C2H(c & 0xF); 154 *hexbuf++ = C2H((c >> 4) & 0xF); 155 } 156 157 return (outlen); 158 } 159 160 /* 161 * hextobin 162 * 163 * Converts hex to binary. 164 * 165 * Assuming hexbuf only contains hex digits (chars) 166 * this function convert every two bytes of hexbuf 167 * to one byte and put it in dstbuf. 168 * 169 * hexlen should be an even number. 170 * dstlen should be at least half of hexlen. 171 * 172 * Returns 0 if sizes are not correct, otherwise 173 * returns the number of converted bytes in dstbuf 174 * which is half of hexlen. 175 */ 176 size_t 177 hextobin(const char *hexbuf, size_t hexlen, 178 char *dstbuf, size_t dstlen) 179 { 180 size_t outlen; 181 182 if ((hexlen % 2) != 0) 183 return (0); 184 185 outlen = hexlen >> 1; 186 if (dstlen < outlen) 187 return (0); 188 189 while (hexlen > 0) { 190 *dstbuf = H2C(*hexbuf) & 0x0F; 191 hexbuf++; 192 *dstbuf++ |= (H2C(*hexbuf) << 4) & 0xF0; 193 hexbuf++; 194 195 hexlen -= 2; 196 } 197 198 return (outlen); 199 } 200 201 /* 202 * trim_whitespace 203 * 204 * Trim leading and trailing whitespace chars (as defined by isspace) 205 * from a buffer. Example; if the input buffer contained " text ", 206 * it will contain "text", when we return. We assume that the buffer 207 * contains a null terminated string. A pointer to the buffer is 208 * returned. 209 */ 210 char * 211 trim_whitespace(char *buf) 212 { 213 char *p = buf; 214 char *q = buf; 215 216 if (buf == 0) 217 return (0); 218 219 while (*p && isspace(*p)) 220 ++p; 221 222 while ((*q = *p++) != 0) 223 ++q; 224 225 if (q != buf) { 226 while ((--q, isspace(*q)) != 0) 227 *q = '\0'; 228 } 229 230 return (buf); 231 } 232 233 /* 234 * randomize 235 * 236 * Randomize the contents of the specified buffer. 237 */ 238 void 239 randomize(char *data, unsigned len) 240 { 241 unsigned dwlen = len / 4; 242 unsigned remlen = len % 4; 243 unsigned tmp; 244 unsigned i; /*LINTED E_BAD_PTR_CAST_ALIGN*/ 245 unsigned *p = (unsigned *)data; 246 247 for (i = 0; i < dwlen; ++i) 248 *p++ = random(); 249 250 if (remlen) { 251 tmp = random(); 252 (void) memcpy(p, &tmp, remlen); 253 } 254 } 255 256 /* 257 * This is the hash mechanism used to encrypt passwords for commands like 258 * SamrSetUserInformation. It uses a 256 byte s-box. 259 */ 260 void 261 rand_hash( 262 unsigned char *data, 263 size_t datalen, 264 unsigned char *key, 265 size_t keylen) 266 { 267 unsigned char sbox[DEFAULT_SBOX_SIZE]; 268 unsigned char tmp; 269 unsigned char index_i = 0; 270 unsigned char index_j = 0; 271 unsigned char j = 0; 272 int i; 273 274 for (i = 0; i < DEFAULT_SBOX_SIZE; ++i) 275 sbox[i] = (unsigned char)i; 276 277 for (i = 0; i < DEFAULT_SBOX_SIZE; ++i) { 278 j += (sbox[i] + key[i % keylen]); 279 280 tmp = sbox[i]; 281 sbox[i] = sbox[j]; 282 sbox[j] = tmp; 283 } 284 285 for (i = 0; i < datalen; ++i) { 286 index_i++; 287 index_j += sbox[index_i]; 288 289 tmp = sbox[index_i]; 290 sbox[index_i] = sbox[index_j]; 291 sbox[index_j] = tmp; 292 293 tmp = sbox[index_i] + sbox[index_j]; 294 data[i] = data[i] ^ sbox[tmp]; 295 } 296 } 297 298 /* 299 * strsep 300 * 301 * The strsep() function locates, in the string referenced by *stringp, the 302 * first occurrence of any character in the string delim (or the terminating 303 * `\0' character) and replaces it with a `\0'. The location of the next 304 * character after the delimiter character (or NULL, if the end of the 305 * string was reached) is stored in *stringp. The original value of 306 * *stringp is returned. 307 * 308 * If *stringp is initially NULL, strsep() returns NULL. 309 */ 310 char * 311 strsep(char **stringp, const char *delim) 312 { 313 char *s; 314 const char *spanp; 315 int c, sc; 316 char *tok; 317 318 if ((s = *stringp) == NULL) 319 return (NULL); 320 321 for (tok = s; ; ) { 322 c = *s++; 323 spanp = delim; 324 do { 325 if ((sc = *spanp++) == c) { 326 if (c == 0) 327 s = NULL; 328 else 329 s[-1] = 0; 330 *stringp = s; 331 return (tok); 332 } 333 } while (sc != 0); 334 } 335 /* NOTREACHED */ 336 } 337