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, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 1999-2003 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 28 /* All Rights Reserved */ 29 30 #pragma ident "%Z%%M% %I% %E% SMI" 31 32 #include <stdlib.h> 33 #include <string.h> 34 #include <libintl.h> 35 #include <locale.h> 36 #include <errno.h> 37 #include <unistd.h> 38 #include <ctype.h> 39 #include <syslog.h> 40 #include <sys/time.h> 41 #include "ns_sldap.h" 42 #include "ns_internal.h" 43 #include <crypt.h> 44 45 static char t1[ROTORSIZE]; 46 static char t2[ROTORSIZE]; 47 static char t3[ROTORSIZE]; 48 static char hexdig[] = "0123456789abcdef"; 49 50 static mutex_t ns_crypt_lock = DEFAULTMUTEX; 51 static boolean_t crypt_inited = B_FALSE; 52 53 static int 54 is_cleartext(const char *pwd) 55 { 56 if (0 == strncmp(pwd, CRYPTMARK, strlen(CRYPTMARK))) 57 return (FALSE); 58 return (TRUE); 59 } 60 61 62 static char * 63 hex2ascii(char *aString, int aLen) 64 { 65 char *res; 66 int i = 0; 67 68 if ((res = (char *)calloc(aLen*2 + 1, 1)) == NULL) { 69 return (NULL); 70 } 71 for (;;) { 72 if (aLen < 1) 73 break; 74 res[i] = hexdig[(*aString & 0xf0) >> 4]; 75 res[i + 1] = hexdig[*aString & 0x0f]; 76 i += 2; 77 aLen--; 78 aString++; 79 } 80 return (res); 81 } 82 83 84 static int 85 unhex(char c) 86 { 87 return (c >= '0' && c <= '9' ? c - '0' 88 : c >= 'A' && c <= 'F' ? c - 'A' + 10 89 : c - 'a' + 10); 90 } 91 92 93 static char * 94 ascii2hex(char *anHexaStr, int *aResLen) 95 { 96 int theLen = 0; 97 char *theRes = malloc(strlen(anHexaStr) /2 + 1); 98 99 if (theRes == NULL) 100 return (NULL); 101 while (isxdigit(*anHexaStr)) { 102 theRes[theLen] = unhex(*anHexaStr) << 4; 103 if (++anHexaStr != '\0') { 104 theRes[theLen] += unhex(*anHexaStr); 105 anHexaStr++; 106 } 107 theLen++; 108 } 109 theRes[theLen] = '\0'; 110 *aResLen = theLen; 111 return (theRes); 112 } 113 114 115 static void 116 c_setup() 117 { 118 int ic, i, k, temp; 119 unsigned random; 120 char buf[13]; 121 int seed; 122 123 (void) mutex_lock(&ns_crypt_lock); 124 if (crypt_inited) { 125 (void) mutex_unlock(&ns_crypt_lock); 126 return; 127 } 128 (void) strcpy(buf, "Homer J"); 129 buf[8] = buf[0]; 130 buf[9] = buf[1]; 131 (void) strncpy(buf, (char *)crypt(buf, &buf[8]), 13); 132 seed = 123; 133 for (i = 0; i < 13; i++) 134 seed = seed*buf[i] + i; 135 for (i = 0; i < ROTORSIZE; i++) { 136 t1[i] = i; 137 t3[i] = 0; 138 } 139 for (i = 0; i < ROTORSIZE; i++) { 140 seed = 5*seed + buf[i%13]; 141 random = seed % 65521; 142 k = ROTORSIZE-1 - i; 143 ic = (random&MASK)%(k+1); 144 random >>= 8; 145 temp = t1[k]; 146 t1[k] = t1[ic]; 147 t1[ic] = temp; 148 if (t3[k] != 0) continue; 149 ic = (random&MASK) % k; 150 while (t3[ic] != 0) ic = (ic + 1) % k; 151 t3[k] = ic; 152 t3[ic] = k; 153 } 154 for (i = 0; i < ROTORSIZE; i++) 155 t2[t1[i]&MASK] = i; 156 crypt_inited = B_TRUE; 157 (void) mutex_unlock(&ns_crypt_lock); 158 } 159 160 161 static char * 162 modvalue(char *str, int len, int *mod_len) 163 { 164 int i, n1, n2; 165 char *s; 166 167 if (!crypt_inited) 168 c_setup(); 169 i = 0; 170 n1 = 0; 171 n2 = 0; 172 if ((s = (char *)malloc(2 * len + 1)) != NULL) { 173 while (i < len) { 174 s[i] = t2[(t3[(t1[(str[i]+n1)&MASK]+n2)&MASK]-n2)&MASK]-n1; 175 i++; 176 n1++; 177 if (n1 == ROTORSIZE) { 178 n1 = 0; 179 n2++; 180 if (n2 == ROTORSIZE) n2 = 0; 181 } 182 } 183 s[i] = '\0'; 184 if (mod_len != NULL) 185 *mod_len = i; 186 } 187 return (s); 188 } 189 190 191 char * 192 evalue(char *ptr) 193 { 194 char *modv, *str, *ev; 195 int modv_len; 196 size_t len; 197 198 /* 199 * if not cleartext, return a copy of what ptr 200 * points to as that is what evalue does below. 201 */ 202 if (FALSE == is_cleartext(ptr)) { 203 str = strdup(ptr); 204 return (str); 205 } 206 207 modv = modvalue(ptr, strlen(ptr), &modv_len); 208 str = hex2ascii(modv, modv_len); 209 free(modv); 210 modv = NULL; 211 len = strlen(str) + strlen(CRYPTMARK) + 1; 212 ev = malloc(len); 213 if (ev == NULL) { 214 free(str); 215 return (NULL); 216 } 217 (void) snprintf(ev, len, CRYPTMARK "%s", str); 218 free(str); 219 str = NULL; 220 return (ev); 221 } 222 223 224 char * 225 dvalue(char *ptr) 226 { 227 char *modv, *str, *sb; 228 int len; 229 230 /* if cleartext return NULL (error!) */ 231 if (TRUE == is_cleartext(ptr)) 232 return (NULL); 233 234 sb = strchr(ptr, '}'); 235 sb++; 236 len = strlen(sb); 237 str = ascii2hex(sb, &len); 238 modv = modvalue(str, len, NULL); 239 free(str); 240 str = NULL; 241 return (modv); 242 }