Files
Arquivotheca.Solaris-2.5/lib/libcrypt/cryptio.c
seta75D 7c4988eac0 Init
2021-10-11 19:38:01 -03:00

326 lines
6.1 KiB
C
Executable File

/* Copyright (c) 1988 AT&T */
/* All Rights Reserved */
/* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */
/* The copyright notice above does not evidence any */
/* actual or intended publication of such source code. */
#ident "@(#)cryptio.c 1.11 95/05/03 SMI"
/* From: SVr4.0 libcrypt_x:cryptio.c 1.12 */
#pragma weak run_setkey = _run_setkey
#pragma weak run_crypt = _run_crypt
#pragma weak crypt_close = _crypt_close
#pragma weak makekey = _makekey
#include "synonyms.h"
#include <stdio.h>
#include <signal.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/types.h>
#include "mtlib.h"
#define READER 0
#define WRITER 1
#define KSIZE 8
/* Global Variables */
static pid_t popen_pid[256];
static char key[KSIZE+1];
static struct header {
long offset;
unsigned int count;
};
#ifdef _REENTRANT
static mutex_t lock = DEFAULTMUTEX;
#endif _REENTRANT
static int cryptopen();
static int writekey();
static int _cp2close(), _cp2open();
extern uid_t getuid();
extern gid_t getgid();
extern int read(), write();
extern int kill();
extern char *strncpy();
extern int close(),
execl(),
pipe();
extern pid_t fork();
void _exit();
int crypt_close();
int
run_setkey(p, keyparam)
int p[2];
/* const */ char *keyparam;
{
#ifdef _REENTRANT
mutex_lock(&lock);
#endif _REENTRANT
if (cryptopen(p) == -1) {
#ifdef _REENTRANT
mutex_unlock(&lock);
#endif _REENTRANT
return (-1);
}
(void) strncpy(key, keyparam, KSIZE);
if (*key == 0) {
(void) crypt_close_nolock(p);
#ifdef _REENTRANT
mutex_unlock(&lock);
#endif _REENTRANT
return (0);
}
if (writekey(p, key) == -1) {
#ifdef _REENTRANT
mutex_unlock(&lock);
#endif _REENTRANT
return (-1);
}
#ifdef _REENTRANT
mutex_unlock(&lock);
#endif _REENTRANT
return (1);
}
static char cmd[] = "exec /usr/bin/crypt -p 2>/dev/null";
static int
cryptopen(p)
int p[2];
{
char c;
if (_cp2open(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(p, keyarg)
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(offset, buffer, count, p)
long offset;
char *buffer;
unsigned int count;
int p[2];
{
struct header header;
void (*pstat) ();
#ifdef _REENTRANT
mutex_lock(&lock);
#endif _REENTRANT
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);
#ifdef _REENTRANT
mutex_unlock(&lock);
#endif _REENTRANT
return (-1);
}
if (write(p[READER], buffer, count) < count) {
(void) crypt_close_nolock(p);
(void) signal(SIGPIPE, pstat);
#ifdef _REENTRANT
mutex_unlock(&lock);
#endif _REENTRANT
return (-1);
}
if (read(p[WRITER], buffer, count) < count) {
(void) crypt_close_nolock(p);
(void) signal(SIGPIPE, pstat);
#ifdef _REENTRANT
mutex_unlock(&lock);
#endif _REENTRANT
return (-1);
}
(void) signal(SIGPIPE, pstat);
#ifdef _REENTRANT
mutex_unlock(&lock);
#endif _REENTRANT
return (0);
}
makekey(b)
int b[2];
{
register int i;
long gorp;
char tempbuf[KSIZE], *a, *temp;
#ifdef _REENTRANT
mutex_lock(&lock);
#endif _REENTRANT
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) {
#ifdef _REENTRANT
mutex_unlock(&lock);
#endif _REENTRANT
return (-1);
}
if (writekey(b, temp) == -1) {
#ifdef _REENTRANT
mutex_unlock(&lock);
#endif _REENTRANT
return (-1);
}
#ifdef _REENTRANT
mutex_unlock(&lock);
#endif _REENTRANT
return (0);
}
crypt_close_nolock(p)
int p[2];
{
pid_t pid;
int ret;
if (p[0] == 0 && p[1] == 0 || p[0] < 0 || p[1] < 0) {
ret = -1;
goto done;
}
pid = popen_pid[p[0]];
if (pid != popen_pid[p[1]]) {
ret = -1;
goto done;
}
if (!pid) {
ret = -1;
goto done;
}
(void) kill(pid, 9);
ret = _cp2close(p);
done:
return (ret);
}
crypt_close(p)
int p[2];
{
#ifdef _REENTRANT
mutex_lock(&lock);
#endif _REENTRANT
crypt_close_nolock(p);
#ifdef _REENTRANT
mutex_unlock(&lock);
#endif _REENTRANT
}
/*
Similar to popen(3S) but with pipe to cmd's stdin and from stdout.
*/
static int _cp2open(cmd, p)
/* const */ char *cmd;
int p[2]; /* file descriptor array to cmd stdin and stdout */
{
int tocmd[2];
int fromcmd[2];
register int pid;
if ((pipe(tocmd) < 0) || (pipe(fromcmd) < 0))
return (-1);
/* be consistent with stdio */
if (tocmd[1] >= 256 || fromcmd[0] >= 256) {
(void) close(tocmd[0]);
(void) close(tocmd[1]);
(void) close(fromcmd[0]);
(void) close(fromcmd[1]);
return (-1);
}
if ((pid = fork()) == 0) {
(void) close(tocmd[1]);
(void) close(0);
(void) fcntl(tocmd[0], F_DUPFD, 0);
(void) close(tocmd[0]);
(void) close(fromcmd[0]);
(void) close(1);
(void) fcntl(fromcmd[1], F_DUPFD, 1);
(void) close(fromcmd[1]);
(void) execl("/sbin/sh", "sh", "-c", cmd, 0);
_exit(1);
}
if (pid == -1)
return (-1);
popen_pid[ tocmd[1] ] = pid;
popen_pid[ fromcmd[0] ] = pid;
(void) close(tocmd[0]);
(void) close(fromcmd[1]);
p[0] = tocmd[1];
p[1] = fromcmd[0];
return (0);
}
static int
_cp2close(p)
int p[2];
{
register pid_t r;
int status;
pid_t waitpid();
void (*hstat)(),
(*istat)(),
(*qstat)();
pid_t pid;
if (p[0] < 0 || p[0] >= 256 || p[1] < 0 || p[1] >= 256)
return (-1);
pid = popen_pid[p[0]];
if (pid != popen_pid[p[1]])
return (-1);
(void) close(p[0]);
(void) close(p[1]);
istat = signal(SIGINT, SIG_IGN);
qstat = signal(SIGQUIT, SIG_IGN);
hstat = signal(SIGHUP, SIG_IGN);
while ((r = waitpid(pid, &status, 0)) == (pid_t)-1 && errno == EINTR)
;
if (r == (pid_t)-1)
status = -1;
(void) signal(SIGINT, istat);
(void) signal(SIGQUIT, qstat);
(void) signal(SIGHUP, hstat);
return (status);
}