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
is_cleartext(const char * pwd)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 *
hex2ascii(char * aString,int aLen)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
unhex(char c)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 *
ascii2hex(char * anHexaStr,int * aResLen)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
c_setup()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 *
modvalue(char * str,int len,int * mod_len)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 *
evalue(char * ptr)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 *
dvalue(char * ptr)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