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 }