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 /* 24 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 25 * Use is subject to license terms. 26 */ 27 28 /* Copyright (c) 1988 AT&T */ 29 /* All Rights Reserved */ 30 31 32 33 #pragma ident "%Z%%M% %I% %E% SMI" 34 35 #pragma weak run_setkey = _run_setkey 36 #pragma weak run_crypt = _run_crypt 37 #pragma weak crypt_close = _crypt_close 38 #pragma weak makekey = _makekey 39 40 #include "des_synonyms.h" 41 #include <stdio.h> 42 #include <signal.h> 43 #include <fcntl.h> 44 #include <errno.h> 45 #include <thread.h> 46 #include <sys/types.h> 47 #include <unistd.h> 48 #include <strings.h> 49 #include <crypt.h> 50 #include "des_soft.h" 51 #include "lib_gen.h" 52 53 #define READER 0 54 #define WRITER 1 55 #define KSIZE 8 56 57 /* Global Variables */ 58 static char key[KSIZE+1]; 59 struct header { 60 long offset; 61 unsigned int count; 62 }; 63 64 static mutex_t lock = DEFAULTMUTEX; 65 66 static int cryptopen(); 67 static int writekey(); 68 69 void _exit(); 70 71 int 72 run_setkey(int p[2], const char *keyparam) 73 { 74 (void) mutex_lock(&lock); 75 if (cryptopen(p) == -1) { 76 (void) mutex_unlock(&lock); 77 return (-1); 78 } 79 (void) strncpy(key, keyparam, KSIZE); 80 if (*key == 0) { 81 (void) crypt_close_nolock(p); 82 (void) mutex_unlock(&lock); 83 return (0); 84 } 85 if (writekey(p, key) == -1) { 86 (void) mutex_unlock(&lock); 87 return (-1); 88 } 89 (void) mutex_unlock(&lock); 90 return (1); 91 } 92 93 static char cmd[] = "exec /usr/bin/crypt -p 2>/dev/null"; 94 static int 95 cryptopen(int p[2]) 96 { 97 char c; 98 99 if (__p2open(cmd, p) < 0) 100 return (-1); 101 if (read(p[WRITER], &c, 1) != 1) { /* check that crypt is working on */ 102 /* other end */ 103 (void) crypt_close(p); /* remove defunct process */ 104 return (-1); 105 } 106 return (1); 107 } 108 109 static int 110 writekey(int p[2], char *keyarg) 111 { 112 void (*pstat) (); 113 pstat = signal(SIGPIPE, SIG_IGN); /* don't want pipe errors to cause */ 114 /* death */ 115 if (write(p[READER], keyarg, KSIZE) != KSIZE) { 116 (void) crypt_close(p); /* remove defunct process */ 117 (void) signal(SIGPIPE, pstat); 118 return (-1); 119 } 120 (void) signal(SIGPIPE, pstat); 121 return (1); 122 } 123 124 125 int 126 run_crypt(long offset, char *buffer, unsigned int count, int p[2]) 127 { 128 struct header header; 129 void (*pstat) (); 130 131 (void) mutex_lock(&lock); 132 header.count = count; 133 header.offset = offset; 134 pstat = signal(SIGPIPE, SIG_IGN); 135 if (write(p[READER], (char *)&header, sizeof (header)) 136 != sizeof (header)) { 137 (void) crypt_close_nolock(p); 138 (void) signal(SIGPIPE, pstat); 139 (void) mutex_unlock(&lock); 140 return (-1); 141 } 142 if (write(p[READER], buffer, count) < count) { 143 (void) crypt_close_nolock(p); 144 (void) signal(SIGPIPE, pstat); 145 (void) mutex_unlock(&lock); 146 return (-1); 147 } 148 if (read(p[WRITER], buffer, count) < count) { 149 (void) crypt_close_nolock(p); 150 (void) signal(SIGPIPE, pstat); 151 (void) mutex_unlock(&lock); 152 return (-1); 153 } 154 (void) signal(SIGPIPE, pstat); 155 (void) mutex_unlock(&lock); 156 return (0); 157 } 158 159 int 160 makekey(int b[2]) 161 { 162 int i; 163 long gorp; 164 char tempbuf[KSIZE], *a, *temp; 165 166 (void) mutex_lock(&lock); 167 a = key; 168 temp = tempbuf; 169 for (i = 0; i < KSIZE; i++) 170 temp[i] = *a++; 171 gorp = getuid() + getgid(); 172 173 for (i = 0; i < 4; i++) 174 temp[i] ^= (char)((gorp>>(8*i))&0377); 175 176 if (cryptopen(b) == -1) { 177 (void) mutex_unlock(&lock); 178 return (-1); 179 } 180 if (writekey(b, temp) == -1) { 181 (void) mutex_unlock(&lock); 182 return (-1); 183 } 184 (void) mutex_unlock(&lock); 185 return (0); 186 } 187 188 int 189 crypt_close_nolock(int p[2]) 190 { 191 192 if (p[0] == 0 && p[1] == 0 || p[0] < 0 || p[1] < 0) { 193 return (-1); 194 } 195 196 return (__p2close(p, NULL, SIGKILL)); 197 } 198 199 int 200 crypt_close(int p[2]) 201 { 202 (void) mutex_lock(&lock); 203 (void) crypt_close_nolock(p); 204 (void) mutex_unlock(&lock); 205 return (0); 206 } 207