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 /* EXPORT DELETE START */ 44 #include <crypt.h> 45 46 #define NS_DOMESTIC 1 47 48 static char t1[ROTORSIZE]; 49 static char t2[ROTORSIZE]; 50 static char t3[ROTORSIZE]; 51 static char hexdig[] = "0123456789abcdef"; 52 53 static mutex_t ns_crypt_lock = DEFAULTMUTEX; 54 static boolean_t crypt_inited = B_FALSE; 55 56 static int 57 is_cleartext(const char *pwd) 58 { 59 if (0 == strncmp(pwd, CRYPTMARK, strlen(CRYPTMARK))) 60 return (FALSE); 61 return (TRUE); 62 } 63 64 65 static char * 66 hex2ascii(char *aString, int aLen) 67 { 68 char *res; 69 int i = 0; 70 71 if ((res = (char *)calloc(aLen*2 + 1, 1)) == NULL) { 72 return (NULL); 73 } 74 for (;;) { 75 if (aLen < 1) 76 break; 77 res[i] = hexdig[(*aString & 0xf0) >> 4]; 78 res[i + 1] = hexdig[*aString & 0x0f]; 79 i += 2; 80 aLen--; 81 aString++; 82 } 83 return (res); 84 } 85 86 87 static int 88 unhex(char c) 89 { 90 return (c >= '0' && c <= '9' ? c - '0' 91 : c >= 'A' && c <= 'F' ? c - 'A' + 10 92 : c - 'a' + 10); 93 } 94 95 96 static char * 97 ascii2hex(char *anHexaStr, int *aResLen) 98 { 99 int theLen = 0; 100 char *theRes = malloc(strlen(anHexaStr) /2 + 1); 101 102 if (theRes == NULL) 103 return (NULL); 104 while (isxdigit(*anHexaStr)) { 105 theRes[theLen] = unhex(*anHexaStr) << 4; 106 if (++anHexaStr != '\0') { 107 theRes[theLen] += unhex(*anHexaStr); 108 anHexaStr++; 109 } 110 theLen++; 111 } 112 theRes[theLen] = '\0'; 113 *aResLen = theLen; 114 return (theRes); 115 } 116 /* EXPORT DELETE END */ 117 118 119 static void 120 c_setup() 121 { 122 /* EXPORT DELETE START */ 123 int ic, i, k, temp; 124 unsigned random; 125 char buf[13]; 126 int seed; 127 128 (void) mutex_lock(&ns_crypt_lock); 129 if (crypt_inited) { 130 (void) mutex_unlock(&ns_crypt_lock); 131 return; 132 } 133 (void) strcpy(buf, "Homer J"); 134 buf[8] = buf[0]; 135 buf[9] = buf[1]; 136 (void) strncpy(buf, (char *)crypt(buf, &buf[8]), 13); 137 seed = 123; 138 for (i = 0; i < 13; i++) 139 seed = seed*buf[i] + i; 140 for (i = 0; i < ROTORSIZE; i++) { 141 t1[i] = i; 142 t3[i] = 0; 143 } 144 for (i = 0; i < ROTORSIZE; i++) { 145 seed = 5*seed + buf[i%13]; 146 random = seed % 65521; 147 k = ROTORSIZE-1 - i; 148 ic = (random&MASK)%(k+1); 149 random >>= 8; 150 temp = t1[k]; 151 t1[k] = t1[ic]; 152 t1[ic] = temp; 153 if (t3[k] != 0) continue; 154 ic = (random&MASK) % k; 155 while (t3[ic] != 0) ic = (ic + 1) % k; 156 t3[k] = ic; 157 t3[ic] = k; 158 } 159 for (i = 0; i < ROTORSIZE; i++) 160 t2[t1[i]&MASK] = i; 161 crypt_inited = B_TRUE; 162 (void) mutex_unlock(&ns_crypt_lock); 163 } 164 165 166 static char * 167 modvalue(char *str, int len, int *mod_len) 168 { 169 int i, n1, n2; 170 char *s; 171 172 if (!crypt_inited) 173 c_setup(); 174 i = 0; 175 n1 = 0; 176 n2 = 0; 177 if ((s = (char *)malloc(2 * len + 1)) != NULL) { 178 while (i < len) { 179 s[i] = t2[(t3[(t1[(str[i]+n1)&MASK]+n2)&MASK]-n2)&MASK]-n1; 180 i++; 181 n1++; 182 if (n1 == ROTORSIZE) { 183 n1 = 0; 184 n2++; 185 if (n2 == ROTORSIZE) n2 = 0; 186 } 187 } 188 s[i] = '\0'; 189 if (mod_len != NULL) 190 *mod_len = i; 191 } 192 return (s); 193 /* EXPORT DELETE END */ 194 } 195 196 197 char * 198 evalue(char *ptr) 199 { 200 /* EXPORT DELETE START */ 201 char *modv, *str, *ev; 202 int modv_len; 203 size_t len; 204 205 /* 206 * if not cleartext, return a copy of what ptr 207 * points to as that is what evalue does below. 208 */ 209 if (FALSE == is_cleartext(ptr)) { 210 str = strdup(ptr); 211 return (str); 212 } 213 214 modv = modvalue(ptr, strlen(ptr), &modv_len); 215 str = hex2ascii(modv, modv_len); 216 free(modv); 217 modv = NULL; 218 len = strlen(str) + strlen(CRYPTMARK) + 1; 219 ev = malloc(len); 220 if (ev == NULL) { 221 free(str); 222 return (NULL); 223 } 224 (void) snprintf(ev, len, CRYPTMARK "%s", str); 225 free(str); 226 str = NULL; 227 return (ev); 228 #ifndef NS_DOMESTIC 229 /* EXPORT DELETE END */ 230 return (strdup(ptr)); 231 /* EXPORT DELETE START */ 232 #endif 233 /* EXPORT DELETE END */ 234 } 235 236 237 char * 238 dvalue(char *ptr) 239 { 240 /* EXPORT DELETE START */ 241 char *modv, *str, *sb; 242 int len; 243 244 /* if cleartext return NULL (error!) */ 245 if (TRUE == is_cleartext(ptr)) 246 return (NULL); 247 248 sb = strchr(ptr, '}'); 249 sb++; 250 len = strlen(sb); 251 str = ascii2hex(sb, &len); 252 modv = modvalue(str, len, NULL); 253 free(str); 254 str = NULL; 255 return (modv); 256 #ifndef NS_DOMESTIC 257 /* EXPORT DELETE END */ 258 return (strdup(ptr)); 259 /* EXPORT DELETE START */ 260 #endif 261 /* EXPORT DELETE END */ 262 } 263