diff options
Diffstat (limited to 'auth.c')
-rw-r--r-- | auth.c | 247 |
1 files changed, 247 insertions, 0 deletions
@@ -0,0 +1,247 @@ +/* $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. */ +/************************************************************************/ + +#include <stdio.h> +#include <X11/Xos.h> +#include <errno.h> +#ifndef X_NOT_STDC_ENV +#include <stdlib.h> +#else +extern int errno; +#endif +#include <ctype.h> + +extern char *expand(); +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; +} + +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; +} + +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; +} + +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; +} + +do_auth() +{ + 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; +} |