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 #include <stdlib.h> 31 #include <string.h> 32 #include <libintl.h> 33 #include <locale.h> 34 #include <errno.h> 35 #include <unistd.h> 36 #include <ctype.h> 37 #include <syslog.h> 38 #include <sys/time.h> 39 #include "ns_sldap.h" 40 #include "ns_internal.h" 41 #include <crypt.h> 42 43 static char t1[ROTORSIZE]; 44 static char t2[ROTORSIZE]; 45 static char t3[ROTORSIZE]; 46 static char hexdig[] = "0123456789abcdef"; 47 48 static mutex_t ns_crypt_lock = DEFAULTMUTEX; 49 static boolean_t crypt_inited = B_FALSE; 50 51 static int 52 is_cleartext(const char *pwd) 53 { 54 if (0 == strncmp(pwd, CRYPTMARK, strlen(CRYPTMARK))) 55 return (FALSE); 56 return (TRUE); 57 } 58 59 60 static char * 61 hex2ascii(char *aString, int aLen) 62 { 63 char *res; 64 int i = 0; 65 66 if ((res = (char *)calloc(aLen*2 + 1, 1)) == NULL) { 67 return (NULL); 68 } 69 for (;;) { 70 if (aLen < 1) 71 break; 72 res[i] = hexdig[(*aString & 0xf0) >> 4]; 73 res[i + 1] = hexdig[*aString & 0x0f]; 74 i += 2; 75 aLen--; 76 aString++; 77 } 78 return (res); 79 } 80 81 82 static int 83 unhex(char c) 84 { 85 return (c >= '0' && c <= '9' ? c - '0' 86 : c >= 'A' && c <= 'F' ? c - 'A' + 10 87 : c - 'a' + 10); 88 } 89 90 91 static char * 92 ascii2hex(char *anHexaStr, int *aResLen) 93 { 94 int theLen = 0; 95 char *theRes = malloc(strlen(anHexaStr) /2 + 1); 96 97 if (theRes == NULL) 98 return (NULL); 99 while (isxdigit(*anHexaStr)) { 100 theRes[theLen] = unhex(*anHexaStr) << 4; 101 if (*(++anHexaStr) != '\0') { 102 theRes[theLen] += unhex(*anHexaStr); 103 anHexaStr++; 104 } 105 theLen++; 106 } 107 theRes[theLen] = '\0'; 108 *aResLen = theLen; 109 return (theRes); 110 } 111 112 113 static void 114 c_setup() 115 { 116 int ic, i, k, temp; 117 unsigned random; 118 char buf[13]; 119 int seed; 120 121 (void) mutex_lock(&ns_crypt_lock); 122 if (crypt_inited) { 123 (void) mutex_unlock(&ns_crypt_lock); 124 return; 125 } 126 (void) strcpy(buf, "Homer J"); 127 buf[8] = buf[0]; 128 buf[9] = buf[1]; 129 (void) strncpy(buf, (char *)crypt(buf, &buf[8]), 13); 130 seed = 123; 131 for (i = 0; i < 13; i++) 132 seed = seed*buf[i] + i; 133 for (i = 0; i < ROTORSIZE; i++) { 134 t1[i] = i; 135 t3[i] = 0; 136 } 137 for (i = 0; i < ROTORSIZE; i++) { 138 seed = 5*seed + buf[i%13]; 139 random = seed % 65521; 140 k = ROTORSIZE-1 - i; 141 ic = (random&MASK)%(k+1); 142 random >>= 8; 143 temp = t1[k]; 144 t1[k] = t1[ic]; 145 t1[ic] = temp; 146 if (t3[k] != 0) continue; 147 ic = (random&MASK) % k; 148 while (t3[ic] != 0) ic = (ic + 1) % k; 149 t3[k] = ic; 150 t3[ic] = k; 151 } 152 for (i = 0; i < ROTORSIZE; i++) 153 t2[t1[i]&MASK] = i; 154 crypt_inited = B_TRUE; 155 (void) mutex_unlock(&ns_crypt_lock); 156 } 157 158 159 static char * 160 modvalue(char *str, int len, int *mod_len) 161 { 162 int i, n1, n2; 163 char *s; 164 165 if (!crypt_inited) 166 c_setup(); 167 i = 0; 168 n1 = 0; 169 n2 = 0; 170 if ((s = (char *)malloc(2 * len + 1)) != NULL) { 171 while (i < len) { 172 s[i] = 173 t2[(t3[(t1[(str[i]+n1)&MASK]+n2)&MASK]-n2)&MASK]-n1; 174 i++; 175 n1++; 176 if (n1 == ROTORSIZE) { 177 n1 = 0; 178 n2++; 179 if (n2 == ROTORSIZE) 180 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 } 243