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 (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* Copyright (c) 1988 AT&T */ 28 /* All Rights Reserved */ 29 30 #pragma weak _run_setkey = run_setkey 31 #pragma weak _run_crypt = run_crypt 32 #pragma weak _crypt_close = crypt_close 33 #pragma weak _makekey = makekey 34 35 #include <stdio.h> 36 #include <signal.h> 37 #include <fcntl.h> 38 #include <errno.h> 39 #include <thread.h> 40 #include <sys/types.h> 41 #include <unistd.h> 42 #include <strings.h> 43 #include <crypt.h> 44 #include "des_soft.h" 45 #include "lib_gen.h" 46 47 #define READER 0 48 #define WRITER 1 49 #define KSIZE 8 50 51 /* Global Variables */ 52 static char key[KSIZE+1]; 53 struct header { 54 long offset; 55 unsigned int count; 56 }; 57 58 static mutex_t lock = DEFAULTMUTEX; 59 60 static int cryptopen(); 61 static int writekey(); 62 63 void _exit(); 64 65 int 66 run_setkey(int *p, const char *keyparam) 67 { 68 (void) mutex_lock(&lock); 69 if (cryptopen(p) == -1) { 70 (void) mutex_unlock(&lock); 71 return (-1); 72 } 73 (void) strncpy(key, keyparam, KSIZE); 74 if (*key == 0) { 75 (void) crypt_close_nolock(p); 76 (void) mutex_unlock(&lock); 77 return (0); 78 } 79 if (writekey(p, key) == -1) { 80 (void) mutex_unlock(&lock); 81 return (-1); 82 } 83 (void) mutex_unlock(&lock); 84 return (1); 85 } 86 87 static char cmd[] = "exec /usr/bin/crypt -p 2>/dev/null"; 88 static int 89 cryptopen(int p[2]) 90 { 91 char c; 92 93 if (__p2open(cmd, p) < 0) 94 return (-1); 95 if (read(p[WRITER], &c, 1) != 1) { /* check that crypt is working on */ 96 /* other end */ 97 (void) crypt_close(p); /* remove defunct process */ 98 return (-1); 99 } 100 return (1); 101 } 102 103 static int 104 writekey(int p[2], char *keyarg) 105 { 106 void (*pstat) (); 107 pstat = signal(SIGPIPE, SIG_IGN); /* don't want pipe errors to cause */ 108 /* death */ 109 if (write(p[READER], keyarg, KSIZE) != KSIZE) { 110 (void) crypt_close(p); /* remove defunct process */ 111 (void) signal(SIGPIPE, pstat); 112 return (-1); 113 } 114 (void) signal(SIGPIPE, pstat); 115 return (1); 116 } 117 118 119 int 120 run_crypt(long offset, char *buffer, unsigned int count, int *p) 121 { 122 struct header header; 123 void (*pstat) (); 124 125 (void) mutex_lock(&lock); 126 header.count = count; 127 header.offset = offset; 128 pstat = signal(SIGPIPE, SIG_IGN); 129 if (write(p[READER], (char *)&header, sizeof (header)) 130 != sizeof (header)) { 131 (void) crypt_close_nolock(p); 132 (void) signal(SIGPIPE, pstat); 133 (void) mutex_unlock(&lock); 134 return (-1); 135 } 136 if (write(p[READER], buffer, count) < count) { 137 (void) crypt_close_nolock(p); 138 (void) signal(SIGPIPE, pstat); 139 (void) mutex_unlock(&lock); 140 return (-1); 141 } 142 if (read(p[WRITER], buffer, count) < count) { 143 (void) crypt_close_nolock(p); 144 (void) signal(SIGPIPE, pstat); 145 (void) mutex_unlock(&lock); 146 return (-1); 147 } 148 (void) signal(SIGPIPE, pstat); 149 (void) mutex_unlock(&lock); 150 return (0); 151 } 152 153 int 154 makekey(int b[2]) 155 { 156 int i; 157 long gorp; 158 char tempbuf[KSIZE], *a, *temp; 159 160 (void) mutex_lock(&lock); 161 a = key; 162 temp = tempbuf; 163 for (i = 0; i < KSIZE; i++) 164 temp[i] = *a++; 165 gorp = getuid() + getgid(); 166 167 for (i = 0; i < 4; i++) 168 temp[i] ^= (char)((gorp>>(8*i))&0377); 169 170 if (cryptopen(b) == -1) { 171 (void) mutex_unlock(&lock); 172 return (-1); 173 } 174 if (writekey(b, temp) == -1) { 175 (void) mutex_unlock(&lock); 176 return (-1); 177 } 178 (void) mutex_unlock(&lock); 179 return (0); 180 } 181 182 int 183 crypt_close_nolock(int p[2]) 184 { 185 186 if (p[0] == 0 && p[1] == 0 || p[0] < 0 || p[1] < 0) { 187 return (-1); 188 } 189 190 return (__p2close(p, NULL, SIGKILL)); 191 } 192 193 int 194 crypt_close(int *p) 195 { 196 (void) mutex_lock(&lock); 197 (void) crypt_close_nolock(p); 198 (void) mutex_unlock(&lock); 199 return (0); 200 } 201