/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* Copyright (c) 1988 AT&T */ /* All Rights Reserved */ #pragma weak _run_setkey = run_setkey #pragma weak _run_crypt = run_crypt #pragma weak _crypt_close = crypt_close #pragma weak _makekey = makekey #include #include #include #include #include #include #include #include #include #include "des_soft.h" #include "lib_gen.h" #define READER 0 #define WRITER 1 #define KSIZE 8 /* Global Variables */ static char key[KSIZE+1]; struct header { long offset; unsigned int count; }; static mutex_t lock = DEFAULTMUTEX; static int cryptopen(); static int writekey(); void _exit(); int run_setkey(int *p, const char *keyparam) { (void) mutex_lock(&lock); if (cryptopen(p) == -1) { (void) mutex_unlock(&lock); return (-1); } (void) strncpy(key, keyparam, KSIZE); if (*key == 0) { (void) crypt_close_nolock(p); (void) mutex_unlock(&lock); return (0); } if (writekey(p, key) == -1) { (void) mutex_unlock(&lock); return (-1); } (void) mutex_unlock(&lock); return (1); } static char cmd[] = "exec /usr/bin/crypt -p 2>/dev/null"; static int cryptopen(int p[2]) { char c; if (__p2open(cmd, p) < 0) return (-1); if (read(p[WRITER], &c, 1) != 1) { /* check that crypt is working on */ /* other end */ (void) crypt_close(p); /* remove defunct process */ return (-1); } return (1); } static int writekey(int p[2], char *keyarg) { void (*pstat) (); pstat = signal(SIGPIPE, SIG_IGN); /* don't want pipe errors to cause */ /* death */ if (write(p[READER], keyarg, KSIZE) != KSIZE) { (void) crypt_close(p); /* remove defunct process */ (void) signal(SIGPIPE, pstat); return (-1); } (void) signal(SIGPIPE, pstat); return (1); } int run_crypt(long offset, char *buffer, unsigned int count, int *p) { struct header header; void (*pstat) (); (void) mutex_lock(&lock); header.count = count; header.offset = offset; pstat = signal(SIGPIPE, SIG_IGN); if (write(p[READER], (char *)&header, sizeof (header)) != sizeof (header)) { (void) crypt_close_nolock(p); (void) signal(SIGPIPE, pstat); (void) mutex_unlock(&lock); return (-1); } if (write(p[READER], buffer, count) < count) { (void) crypt_close_nolock(p); (void) signal(SIGPIPE, pstat); (void) mutex_unlock(&lock); return (-1); } if (read(p[WRITER], buffer, count) < count) { (void) crypt_close_nolock(p); (void) signal(SIGPIPE, pstat); (void) mutex_unlock(&lock); return (-1); } (void) signal(SIGPIPE, pstat); (void) mutex_unlock(&lock); return (0); } int makekey(int b[2]) { int i; long gorp; char tempbuf[KSIZE], *a, *temp; (void) mutex_lock(&lock); a = key; temp = tempbuf; for (i = 0; i < KSIZE; i++) temp[i] = *a++; gorp = getuid() + getgid(); for (i = 0; i < 4; i++) temp[i] ^= (char)((gorp>>(8*i))&0377); if (cryptopen(b) == -1) { (void) mutex_unlock(&lock); return (-1); } if (writekey(b, temp) == -1) { (void) mutex_unlock(&lock); return (-1); } (void) mutex_unlock(&lock); return (0); } int crypt_close_nolock(int p[2]) { if (p[0] == 0 && p[1] == 0 || p[0] < 0 || p[1] < 0) { return (-1); } return (__p2close(p, NULL, SIGKILL)); } int crypt_close(int *p) { (void) mutex_lock(&lock); (void) crypt_close_nolock(p); (void) mutex_unlock(&lock); return (0); }