xenocara/app/rstart/auth.c
2006-11-25 20:07:29 +00:00

262 lines
5.6 KiB
C

/* $Xorg: auth.c,v 1.4 2000/08/17 19:54:01 cpqbld Exp $ */
/************************************************************************/
/* Copyright (c) 1993 Quarterdeck Office Systems */
/* */
/* Permission to use, copy, modify, distribute, and sell this software */
/* and software and its documentation for any purpose is hereby granted */
/* without fee, provided that the above copyright notice appear in all */
/* copies and that both that copyright notice and this permission */
/* notice appear in supporting documentation, and that the name */
/* Quarterdeck Office Systems, Inc. not be used in advertising or */
/* publicity pertaining to distribution of this software without */
/* specific, written prior permission. */
/* */
/* THIS SOFTWARE IS PROVIDED `AS-IS'. QUARTERDECK OFFICE SYSTEMS, */
/* INC., DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, */
/* INCLUDING WITHOUT LIMITATION ALL IMPLIED WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR */
/* NONINFRINGEMENT. IN NO EVENT SHALL QUARTERDECK OFFICE SYSTEMS, */
/* INC., BE LIABLE FOR ANY DAMAGES WHATSOEVER, INCLUDING SPECIAL, */
/* INCIDENTAL OR CONSEQUENTIAL DAMAGES, INCLUDING LOSS OF USE, DATA, OR */
/* PROFITS, EVEN IF ADVISED OF THE POSSIBILITY THEREOF, AND REGARDLESS */
/* OF WHETHER IN AN ACTION IN CONTRACT, TORT OR NEGLIGENCE, ARISING OUT */
/* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
/************************************************************************/
/* $XFree86: xc/programs/rstart/auth.c,v 1.4 2001/01/17 23:45:03 dawes Exp $ */
#include <stdio.h>
#include <X11/Xos.h>
#include <errno.h>
#include <stdlib.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/wait.h>
static char * Strupr ( char *s0 );
struct auth_info * find_or_create_auth ( char *s );
void key_auth ( int ac, char **av );
void key_internal_auth_program ( int ac, char **av );
void key_internal_auth_input ( int ac, char **av );
void do_auth ( void );
char * expand ( char *s, int ac, char **av );
/* server.c */
extern void nomem ( void );
extern char myname[];
struct list_of_argv {
struct list_of_argv *next;
int argc;
char **argv;
};
struct auth_info {
struct auth_info *next;
char *name;
struct list_of_argv *data;
char **program;
char **input;
};
struct auth_info *auth_schemes = NULL;
static char *
Strupr(s0)
char *s0;
{
char *s;
for(s = s0; *s; s++) {
if(islower(*s)) *s = toupper(*s);
}
return s0;
}
/* Argument "s" is overwritten and the memory used, so it must not be */
/* deallocated or subsequently used by the caller. */
struct auth_info *
find_or_create_auth(s)
char *s;
{
struct auth_info *auth;
Strupr(s);
for(auth = auth_schemes; auth; auth=auth->next) {
if(!strcmp(s, auth->name)) return auth;
}
auth = (struct auth_info *)malloc(sizeof(*auth));
if(!auth) nomem();
auth->next = auth_schemes;
auth->name = s;
auth->data = NULL;
auth->program = NULL;
auth->input = NULL;
auth_schemes = auth;
return auth;
}
void
key_auth(ac, av)
int ac;
char **av;
{
struct list_of_argv *lav;
struct auth_info *auth;
if(ac < 2) {
printf(
"%s: Failure: Malformed AUTH\n",myname);
exit(255);
}
auth = find_or_create_auth(av[1]);
lav = (struct list_of_argv *)malloc(sizeof(*lav));
if(!lav) nomem();
lav->next = auth->data;
lav->argc = ac-2;
lav->argv = av+2;
auth->data = lav;
}
void
key_internal_auth_program(ac, av)
int ac;
char **av;
{
struct auth_info *auth;
if(ac < 4) {
printf(
"%s: Failure: Malformed INTERNAL-AUTH-PROGRAM\n",myname);
exit(255);
}
auth = find_or_create_auth(av[1]);
auth->program = av + 2;
}
void
key_internal_auth_input(ac, av)
int ac;
char **av;
{
struct auth_info *auth;
if(ac < 2) {
printf(
"%s: Failure: Malformed INTERNAL-AUTH-INPUT\n",myname);
exit(255);
}
auth = find_or_create_auth(av[1]);
auth->input = av + 2;
}
void
do_auth(void)
{
struct auth_info *auth;
int p[2];
char **pp;
struct list_of_argv *lav;
char *s;
int pid;
int status;
for(auth = auth_schemes; auth; auth = auth->next) {
if(!auth->data) continue;
if(!auth->program) {
printf(
"%s: Warning: no %s authorization program specified in this context\n",myname,
auth->name);
continue;
}
if(pipe(p)) {
printf("%s: Error: pipe - %s\n",myname, strerror(errno));
exit(255);
}
fflush(stdout); /* Can't hurt. */
switch(pid = fork()) {
case -1:
printf("%s: Error: fork - %s\n",myname, strerror(errno));
exit(255);
case 0: /* kid */
close(0);
dup(p[0]);
close(p[0]);
close(p[1]);
execvp(auth->program[0], auth->program+1);
printf("%s: Error: %s - %s\n",myname, auth->program[0],
strerror(errno));
exit(255);
break;
default: /* parent */
close(p[0]);
for(lav = auth->data; lav; lav=lav->next) {
for(pp = auth->input; *pp; pp++) {
s = expand(*pp, lav->argc, lav->argv);
write(p[1], s, strlen(s));
write(p[1], "\n", 1);
}
}
close(p[1]);
while(wait(&status) != pid) /* LOOP */;
if(status) {
printf(
"%s: Warning: %s authorization setup failed\n",myname, auth->name);
}
break;
}
}
}
char *
expand(s, ac, av)
char *s;
int ac;
char **av;
{
static char buf[BUFSIZ];
char *p;
int i;
p = buf;
while(*s) {
if(*s == '$') {
s++;
if(*s == '$') {
*p++ = *s++;
continue;
}
if(!isdigit(*s)) {
printf(
"%s: Failure: bad $ in configuration: non-digit after $\n",myname);
exit(255);
}
i = (int)strtol(s, &s, 10);
if(i > ac) {
printf(
"%s: Failure: not enough arguments to AUTH\n",myname);
exit(255);
}
strcpy(p, av[i-1]);
p += strlen(p);
} else *p++ = *s++;
}
*p = '\0';
return buf;
}