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] = t2[(t3[(t1[(str[i]+n1)&MASK]+n2)&MASK]-n2)&MASK]-n1; 173 i++; 174 n1++; 175 if (n1 == ROTORSIZE) { 176 n1 = 0; 177 n2++; 178 if (n2 == ROTORSIZE) n2 = 0; 179 } 180 } 181 s[i] = '\0'; 182 if (mod_len != NULL) 183 *mod_len = i; 184 } 185 return (s); 186 } 187 188 189 char * 190 evalue(char *ptr) 191 { 192 char *modv, *str, *ev; 193 int modv_len; 194 size_t len; 195 196 /* 197 * if not cleartext, return a copy of what ptr 198 * points to as that is what evalue does below. 199 */ 200 if (FALSE == is_cleartext(ptr)) { 201 str = strdup(ptr); 202 return (str); 203 } 204 205 modv = modvalue(ptr, strlen(ptr), &modv_len); 206 str = hex2ascii(modv, modv_len); 207 free(modv); 208 modv = NULL; 209 len = strlen(str) + strlen(CRYPTMARK) + 1; 210 ev = malloc(len); 211 if (ev == NULL) { 212 free(str); 213 return (NULL); 214 } 215 (void) snprintf(ev, len, CRYPTMARK "%s", str); 216 free(str); 217 str = NULL; 218 return (ev); 219 } 220 221 222 char * 223 dvalue(char *ptr) 224 { 225 char *modv, *str, *sb; 226 int len; 227 228 /* if cleartext return NULL (error!) */ 229 if (TRUE == is_cleartext(ptr)) 230 return (NULL); 231 232 sb = strchr(ptr, '}'); 233 sb++; 234 len = strlen(sb); 235 str = ascii2hex(sb, &len); 236 modv = modvalue(str, len, NULL); 237 free(str); 238 str = NULL; 239 return (modv); 240 } 241