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