summaryrefslogtreecommitdiff
path: root/auth.c
diff options
context:
space:
mode:
Diffstat (limited to 'auth.c')
-rw-r--r--auth.c247
1 files changed, 247 insertions, 0 deletions
diff --git a/auth.c b/auth.c
new file mode 100644
index 0000000..7430b60
--- /dev/null
+++ b/auth.c
@@ -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;
+}