2N/A/*
2N/A * CDDL HEADER START
2N/A *
2N/A * The contents of this file are subject to the terms of the
2N/A * Common Development and Distribution License, Version 1.0 only
2N/A * (the "License"). You may not use this file except in compliance
2N/A * with the License.
2N/A *
2N/A * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
2N/A * or http://www.opensolaris.org/os/licensing.
2N/A * See the License for the specific language governing permissions
2N/A * and limitations under the License.
2N/A *
2N/A * When distributing Covered Code, include this CDDL HEADER in each
2N/A * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
2N/A * If applicable, add the following below this CDDL HEADER, with the
2N/A * fields enclosed by brackets "[]" replaced with your own identifying
2N/A * information: Portions Copyright [yyyy] [name of copyright owner]
2N/A *
2N/A * CDDL HEADER END
2N/A */
2N/A/*
2N/A * Copyright 1999-2003 Sun Microsystems, Inc. All rights reserved.
2N/A * Use is subject to license terms.
2N/A */
2N/A
2N/A/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
2N/A/* All Rights Reserved */
2N/A
2N/A#pragma ident "%Z%%M% %I% %E% SMI"
2N/A
2N/A#include <stdlib.h>
2N/A#include <string.h>
2N/A#include <libintl.h>
2N/A#include <locale.h>
2N/A#include <errno.h>
2N/A#include <unistd.h>
2N/A#include <ctype.h>
2N/A#include <syslog.h>
2N/A#include <sys/time.h>
2N/A#include "ns_sldap.h"
2N/A#include "ns_internal.h"
2N/A/* EXPORT DELETE START */
2N/A#include <crypt.h>
2N/A
2N/A#define NS_DOMESTIC 1
2N/A
2N/Astatic char t1[ROTORSIZE];
2N/Astatic char t2[ROTORSIZE];
2N/Astatic char t3[ROTORSIZE];
2N/Astatic char hexdig[] = "0123456789abcdef";
2N/A
2N/Astatic mutex_t ns_crypt_lock = DEFAULTMUTEX;
2N/Astatic boolean_t crypt_inited = B_FALSE;
2N/A
2N/Astatic int
2N/Ais_cleartext(const char *pwd)
2N/A{
2N/A if (0 == strncmp(pwd, CRYPTMARK, strlen(CRYPTMARK)))
2N/A return (FALSE);
2N/A return (TRUE);
2N/A}
2N/A
2N/A
2N/Astatic char *
2N/Ahex2ascii(char *aString, int aLen)
2N/A{
2N/A char *res;
2N/A int i = 0;
2N/A
2N/A if ((res = (char *)calloc(aLen*2 + 1, 1)) == NULL) {
2N/A return (NULL);
2N/A }
2N/A for (;;) {
2N/A if (aLen < 1)
2N/A break;
2N/A res[i] = hexdig[(*aString & 0xf0) >> 4];
2N/A res[i + 1] = hexdig[*aString & 0x0f];
2N/A i += 2;
2N/A aLen--;
2N/A aString++;
2N/A }
2N/A return (res);
2N/A}
2N/A
2N/A
2N/Astatic int
2N/Aunhex(char c)
2N/A{
2N/A return (c >= '0' && c <= '9' ? c - '0'
2N/A : c >= 'A' && c <= 'F' ? c - 'A' + 10
2N/A : c - 'a' + 10);
2N/A}
2N/A
2N/A
2N/Astatic char *
2N/Aascii2hex(char *anHexaStr, int *aResLen)
2N/A{
2N/A int theLen = 0;
2N/A char *theRes = malloc(strlen(anHexaStr) /2 + 1);
2N/A
2N/A if (theRes == NULL)
2N/A return (NULL);
2N/A while (isxdigit(*anHexaStr)) {
2N/A theRes[theLen] = unhex(*anHexaStr) << 4;
2N/A if (++anHexaStr != '\0') {
2N/A theRes[theLen] += unhex(*anHexaStr);
2N/A anHexaStr++;
2N/A }
2N/A theLen++;
2N/A }
2N/A theRes[theLen] = '\0';
2N/A *aResLen = theLen;
2N/A return (theRes);
2N/A}
2N/A/* EXPORT DELETE END */
2N/A
2N/A
2N/Astatic void
2N/Ac_setup()
2N/A{
2N/A/* EXPORT DELETE START */
2N/A int ic, i, k, temp;
2N/A unsigned random;
2N/A char buf[13];
2N/A int seed;
2N/A
2N/A (void) mutex_lock(&ns_crypt_lock);
2N/A if (crypt_inited) {
2N/A (void) mutex_unlock(&ns_crypt_lock);
2N/A return;
2N/A }
2N/A (void) strcpy(buf, "Homer J");
2N/A buf[8] = buf[0];
2N/A buf[9] = buf[1];
2N/A (void) strncpy(buf, (char *)crypt(buf, &buf[8]), 13);
2N/A seed = 123;
2N/A for (i = 0; i < 13; i++)
2N/A seed = seed*buf[i] + i;
2N/A for (i = 0; i < ROTORSIZE; i++) {
2N/A t1[i] = i;
2N/A t3[i] = 0;
2N/A }
2N/A for (i = 0; i < ROTORSIZE; i++) {
2N/A seed = 5*seed + buf[i%13];
2N/A random = seed % 65521;
2N/A k = ROTORSIZE-1 - i;
2N/A ic = (random&MASK)%(k+1);
2N/A random >>= 8;
2N/A temp = t1[k];
2N/A t1[k] = t1[ic];
2N/A t1[ic] = temp;
2N/A if (t3[k] != 0) continue;
2N/A ic = (random&MASK) % k;
2N/A while (t3[ic] != 0) ic = (ic + 1) % k;
2N/A t3[k] = ic;
2N/A t3[ic] = k;
2N/A }
2N/A for (i = 0; i < ROTORSIZE; i++)
2N/A t2[t1[i]&MASK] = i;
2N/A crypt_inited = B_TRUE;
2N/A (void) mutex_unlock(&ns_crypt_lock);
2N/A}
2N/A
2N/A
2N/Astatic char *
2N/Amodvalue(char *str, int len, int *mod_len)
2N/A{
2N/A int i, n1, n2;
2N/A char *s;
2N/A
2N/A if (!crypt_inited)
2N/A c_setup();
2N/A i = 0;
2N/A n1 = 0;
2N/A n2 = 0;
2N/A if ((s = (char *)malloc(2 * len + 1)) != NULL) {
2N/A while (i < len) {
2N/A s[i] = t2[(t3[(t1[(str[i]+n1)&MASK]+n2)&MASK]-n2)&MASK]-n1;
2N/A i++;
2N/A n1++;
2N/A if (n1 == ROTORSIZE) {
2N/A n1 = 0;
2N/A n2++;
2N/A if (n2 == ROTORSIZE) n2 = 0;
2N/A }
2N/A }
2N/A s[i] = '\0';
2N/A if (mod_len != NULL)
2N/A *mod_len = i;
2N/A }
2N/A return (s);
2N/A/* EXPORT DELETE END */
2N/A}
2N/A
2N/A
2N/Achar *
2N/Aevalue(char *ptr)
2N/A{
2N/A/* EXPORT DELETE START */
2N/A char *modv, *str, *ev;
2N/A int modv_len;
2N/A size_t len;
2N/A
2N/A /*
2N/A * if not cleartext, return a copy of what ptr
2N/A * points to as that is what evalue does below.
2N/A */
2N/A if (FALSE == is_cleartext(ptr)) {
2N/A str = strdup(ptr);
2N/A return (str);
2N/A }
2N/A
2N/A modv = modvalue(ptr, strlen(ptr), &modv_len);
2N/A str = hex2ascii(modv, modv_len);
2N/A free(modv);
2N/A modv = NULL;
2N/A len = strlen(str) + strlen(CRYPTMARK) + 1;
2N/A ev = malloc(len);
2N/A if (ev == NULL) {
2N/A free(str);
2N/A return (NULL);
2N/A }
2N/A (void) snprintf(ev, len, CRYPTMARK "%s", str);
2N/A free(str);
2N/A str = NULL;
2N/A return (ev);
2N/A#ifndef NS_DOMESTIC
2N/A/* EXPORT DELETE END */
2N/A return (strdup(ptr));
2N/A/* EXPORT DELETE START */
2N/A#endif
2N/A/* EXPORT DELETE END */
2N/A}
2N/A
2N/A
2N/Achar *
2N/Advalue(char *ptr)
2N/A{
2N/A/* EXPORT DELETE START */
2N/A char *modv, *str, *sb;
2N/A int len;
2N/A
2N/A /* if cleartext return NULL (error!) */
2N/A if (TRUE == is_cleartext(ptr))
2N/A return (NULL);
2N/A
2N/A sb = strchr(ptr, '}');
2N/A sb++;
2N/A len = strlen(sb);
2N/A str = ascii2hex(sb, &len);
2N/A modv = modvalue(str, len, NULL);
2N/A free(str);
2N/A str = NULL;
2N/A return (modv);
2N/A#ifndef NS_DOMESTIC
2N/A/* EXPORT DELETE END */
2N/A return (strdup(ptr));
2N/A/* EXPORT DELETE START */
2N/A#endif
2N/A/* EXPORT DELETE END */
2N/A}