date and time created 91/02/28 22:01:27 by dab
authorDave A. Borman <dab@ucbvax.Berkeley.EDU>
Fri, 1 Mar 1991 14:01:27 +0000 (06:01 -0800)
committerDave A. Borman <dab@ucbvax.Berkeley.EDU>
Fri, 1 Mar 1991 14:01:27 +0000 (06:01 -0800)
SCCS-vsn: lib/libtelnet/auth-proto.h 5.1
SCCS-vsn: lib/libtelnet/auth.c 5.1
SCCS-vsn: lib/libtelnet/auth.h 5.1

usr/src/lib/libtelnet/auth-proto.h [new file with mode: 0644]
usr/src/lib/libtelnet/auth.c [new file with mode: 0644]
usr/src/lib/libtelnet/auth.h [new file with mode: 0644]

diff --git a/usr/src/lib/libtelnet/auth-proto.h b/usr/src/lib/libtelnet/auth-proto.h
new file mode 100644 (file)
index 0000000..20d8f84
--- /dev/null
@@ -0,0 +1,77 @@
+/*-
+ * Copyright (c) 1991 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * %sccs.include.redist.c%
+ *
+ *     @(#)auth-proto.h        5.1 (Berkeley) %G%
+ */
+
+/*
+ * Copyright (C) 1990 by the Massachusetts Institute of Technology
+ *
+ * Export of this software from the United States of America is assumed
+ * to require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ * 
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, 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 of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission.  M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is" without express
+ * or implied warranty.
+ */
+
+#if    !defined(P)
+#ifdef __STDC__
+#define        P(x)    x
+#else
+#define        P(x)    ()
+#endif
+#endif
+
+#if    defined(AUTHENTICATE)
+Authenticator *findauthenticator P((int, int));
+
+void auth_init P((char *, int));
+int auth_cmd P((int, char **));
+void auth_request P((void));
+void auth_send P((unsigned char *, int));
+void auth_send_retry P((void));
+void auth_is P((unsigned char *, int));
+void auth_reply P((unsigned char *, int));
+void auth_finished P((Authenticator *, int));
+int auth_wait P((char *));
+void auth_disable_name P((char *));
+void auth_gen_printsub P((unsigned char *, int, unsigned char *, int));
+
+#ifdef SIMPLE_AUTH
+int simple_auth_init P((Authenticator *, int));
+int simple_auth_send P((Authenticator *));
+void simple_auth_is_reply P((Authenticator *, unsigned char *, int));
+void simple_auth_printsub P((unsigned char *, int, unsigned char *, int));
+#endif
+
+#ifdef KRB4
+int kerberos4_init P((Authenticator *, int));
+int kerberos4_send P((Authenticator *));
+void kerberos4_is P((Authenticator *, unsigned char *, int));
+void kerberos4_reply P((Authenticator *, unsigned char *, int));
+int kerberos4_status P((Authenticator *, char *, int));
+void kerberos4_printsub P((unsigned char *, int, unsigned char *, int));
+#endif
+
+#ifdef KRB5
+int kerberos5_init P((Authenticator *, int));
+int kerberos5_send P((Authenticator *));
+void kerberos5_is P((Authenticator *, unsigned char *, int));
+void kerberos5_reply P((Authenticator *, unsigned char *, int));
+int kerberos5_status P((Authenticator *, char *, int));
+void kerberos5_printsub P((unsigned char *, int, unsigned char *, int));
+#endif
+#endif
diff --git a/usr/src/lib/libtelnet/auth.c b/usr/src/lib/libtelnet/auth.c
new file mode 100644 (file)
index 0000000..6ca1eb8
--- /dev/null
@@ -0,0 +1,512 @@
+/*-
+ * Copyright (c) 1991 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * %sccs.include.redist.c%
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)auth.c     5.1 (Berkeley) %G%";
+#endif /* not lint */
+
+/*
+ * Copyright (C) 1990 by the Massachusetts Institute of Technology
+ *
+ * Export of this software from the United States of America is assumed
+ * to require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, 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 of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission.  M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is" without express
+ * or implied warranty.
+ */
+
+
+#if    defined(AUTHENTICATE)
+#include <stdio.h>
+#include <sys/types.h>
+#include <signal.h>
+#define        AUTH_NAMES
+#include <arpa/telnet.h>
+#ifdef __STDC__
+#include <stdlib.h>
+#endif
+#ifdef NO_STRING_H
+#include <strings.h>
+#else
+#include <string.h>
+#endif
+
+#include "encrypt.h"
+#include "auth.h"
+#include "misc-proto.h"
+#include "auth-proto.h"
+
+#define        typemask(x)             (1<<((x)-1))
+
+int auth_debug_mode = 0;
+static         char    *Name = "Noname";
+static int     Server = 0;
+static Authenticator   *authenticated = 0;
+static int     authenticating = 0;
+static int     validuser = 0;
+static char    valid_name[256];
+static unsigned char   _auth_send_data[256];
+static unsigned char   *auth_send_data;
+static int     auth_send_cnt = 0;
+
+/*
+ * Authentication types supported.  Plese note that these are stored
+ * in priority order, i.e. try the first one first.
+ */
+Authenticator authenticators[] = {
+#ifdef KRB5
+       { AUTHTYPE_KERBEROS_V5, AUTH_WHO_CLIENT|AUTH_HOW_ONE_WAY,
+                               kerberos5_init,
+                               kerberos5_send,
+                               kerberos5_is,
+                               kerberos5_reply,
+                               kerberos5_status,
+                               kerberos5_printsub },
+#endif
+#ifdef KRB4
+       { AUTHTYPE_KERBEROS_V4, AUTH_WHO_CLIENT|AUTH_HOW_ONE_WAY,
+                               kerberos4_init,
+                               kerberos4_send,
+                               kerberos4_is,
+                               kerberos4_reply,
+                               kerberos4_status,
+                               kerberos4_printsub },
+#endif
+#ifdef SIMPLE_AUTH
+       { AUTHTYPE_TEST,        AUTH_WHO_CLIENT|AUTH_HOW_ONE_WAY,
+                               simple_auth_init,
+                               simple_auth_send,
+                               simple_auth_is_reply,
+                               simple_auth_is_reply,
+                               0,
+                               simple_auth_printsub },
+#endif
+       { 0, },
+};
+
+static Authenticator NoAuth = { 0 };
+
+static int     i_support = 0;
+static int     i_wont_support = 0;
+
+       Authenticator *
+findauthenticator(type, way)
+       int type;
+       int way;
+{
+       Authenticator *ap = authenticators;
+
+       while (ap->type && (ap->type != type || ap->way != way))
+               ++ap;
+       return(ap->type ? ap : 0);
+}
+
+       void
+auth_init(name, server)
+       char *name;
+       int server;
+{
+       Authenticator *ap = authenticators;
+
+       Server = server;
+       Name = name;
+
+       i_support = 0;
+       authenticated = 0;
+       authenticating = 0;
+       while (ap->type) {
+               if (!ap->init || (*ap->init)(ap, server)) {
+                       i_support |= typemask(ap->type);
+                       if (auth_debug_mode)
+                               printf(">>>%s: I support auth type %d\r\n",
+                                       Name,
+                                       ap->type);
+               }
+               ++ap;
+       }
+}
+
+       void
+auth_disable_name(name)
+       char *name;
+{
+       int x;
+       for (x = 0; x < AUTHTYPE_CNT; ++x) {
+               if (!strcasecmp(name, AUTHTYPE_NAME(x))) {
+                       i_wont_support |= typemask(x);
+                       break;
+               }
+       }
+}
+
+       int
+getauthmask(type, maskp)
+       char *type;
+       int *maskp;
+{
+       register int x;
+
+       if (strcasecmp(type, AUTHTYPE_NAME(0))) {
+               *maskp = -1;
+               return(1);
+       }
+
+       for (x = 1; x < AUTHTYPE_CNT; ++x) {
+               if (!strcasecmp(type, AUTHTYPE_NAME(x))) {
+                       *maskp = typemask(x);
+                       return(1);
+               }
+       }
+       return(0);
+}
+
+       int
+auth_enable(type)
+       int type;
+{
+       return(auth_onoff(type, 1));
+}
+
+       int
+auth_disable(type)
+       int type;
+{
+       return(auth_onoff(type, 0));
+}
+
+       int
+auth_onoff(type, on)
+       char *type;
+       int on;
+{
+       int mask = -1;
+       Authenticator *ap;
+
+       if (!strcasecmp(type, "?") || !strcasecmp(type, "help")) {
+                printf("auth %s 'type'\n", on ? "enable" : "disable");
+               printf("Where 'type' is one of:\n");
+               printf("\t%s\n", AUTHTYPE_NAME(0));
+               for (ap = authenticators; ap->type; ap++)
+                       printf("\t%s\n", AUTHTYPE_NAME(ap->type));
+               return(0);
+       }
+
+       if (!getauthmask(type, &mask)) {
+               printf("%s: invalid authentication type\n", type);
+               return(0);
+       }
+       mask = getauthmask(type, &mask);
+       if (on)
+               i_wont_support &= ~mask;
+       else
+               i_wont_support |= mask;
+       return(1);
+}
+
+       int
+auth_togdebug()
+{
+       auth_debug_mode ^= 1;
+       printf("auth debugging %s\n", auth_debug_mode ? "enabled" : "disabled");
+       return(1);
+}
+
+       int
+auth_status()
+{
+       Authenticator *ap;
+
+       if (i_wont_support == -1)
+               printf("Authentication disabled\n");
+       else
+               printf("Authentication enabled\n");
+
+       for (ap = authenticators; ap->type; ap++)
+               printf("%s: %s\n", AUTHTYPE_NAME(ap->type),
+                       (i_wont_support & typemask(ap->type)) ?
+                                       "disabled" : "enabled");
+       return(1);
+}
+
+/*
+ * This routine is called by the server to start authentication
+ * negotiation.
+ */
+       void
+auth_request()
+{
+       static unsigned char str_request[64] = { IAC, SB,
+                                                TELOPT_AUTHENTICATION,
+                                                TELQUAL_SEND, };
+       Authenticator *ap = authenticators;
+       unsigned char *e = str_request + 4;
+
+       if (!authenticating) {
+               authenticating = 1;
+               while (ap->type) {
+                       if (i_support & ~i_wont_support & typemask(ap->type)) {
+                               if (auth_debug_mode) {
+                                       printf(">>>%s: Sending type %d\r\n",
+                                               Name, ap->type);
+                               }
+                               *e++ = ap->type;
+                               *e++ = ap->way;
+                       }
+                       ++ap;
+               }
+               *e++ = IAC;
+               *e++ = SE;
+               net_write(str_request, e - str_request);
+               printsub('>', &str_request[2], e - str_request - 2);
+       }
+}
+
+/*
+ * This is called when an AUTH SEND is received.
+ * It should never arrive on the server side (as only the server can
+ * send an AUTH SEND).
+ * You should probably respond to it if you can...
+ *
+ * If you want to respond to the types out of order (i.e. even
+ * if he sends  LOGIN KERBEROS and you support both, you respond
+ * with KERBEROS instead of LOGIN (which is against what the
+ * protocol says)) you will have to hack this code...
+ */
+       void
+auth_send(data, cnt)
+       unsigned char *data;
+       int cnt;
+{
+       Authenticator *ap;
+       static unsigned char str_none[] = { IAC, SB, TELOPT_AUTHENTICATION,
+                                           TELQUAL_IS, AUTHTYPE_NULL, 0,
+                                           IAC, SE };
+       if (Server) {
+               if (auth_debug_mode) {
+                       printf(">>>%s: auth_send called!\r\n", Name);
+               }
+               return;
+       }
+
+       if (auth_debug_mode) {
+               printf(">>>%s: auth_send got:", Name);
+               printd(data, cnt); printf("\r\n");
+       }
+
+       /*
+        * Save the data, if it is new, so that we can continue looking
+        * at it if the authorization we try doesn't work
+        */
+       if (data < _auth_send_data ||
+           data > _auth_send_data + sizeof(_auth_send_data)) {
+               auth_send_cnt = cnt > sizeof(_auth_send_data)
+                                       ? sizeof(_auth_send_data)
+                                       : cnt;
+               bcopy((void *)data, (void *)_auth_send_data, auth_send_cnt);
+               auth_send_data = _auth_send_data;
+       } else {
+               /*
+                * This is probably a no-op, but we just make sure
+                */
+               auth_send_data = data;
+               auth_send_cnt = cnt;
+       }
+       while ((auth_send_cnt -= 2) >= 0) {
+               if (auth_debug_mode)
+                       printf(">>>%s: He supports %d\r\n",
+                               Name, *auth_send_data);
+               if ((i_support & ~i_wont_support) & typemask(*auth_send_data)) {
+                       ap = findauthenticator(auth_send_data[0],
+                                              auth_send_data[1]);
+                       if (!ap) {
+                               printf("Internal state error: cannot find authentication type %d a second time\r\n", *auth_send_data);
+                       } else if (ap->send) {
+                               if (auth_debug_mode)
+                                       printf(">>>%s: Trying %d\r\n",
+                                               Name, *auth_send_data);
+                               if ((*ap->send)(ap)) {
+                                       /*
+                                        * Okay, we found one we like
+                                        * and did it.
+                                        * we can go home now.
+                                        */
+                                       if (auth_debug_mode)
+                                               printf(">>>%s: Using type %d\r\n",
+                                                       Name, *auth_send_data);
+                                       auth_send_data += 2;
+                                       return;
+                               }
+                       }
+                       /* else
+                        *      just continue on and look for the
+                        *      next one if we didn't do anything.
+                        */
+               }
+               auth_send_data += 2;
+       }
+       net_write(str_none, sizeof(str_none));
+       printsub('>', &str_none[2], sizeof(str_none) - 2);
+       if (auth_debug_mode)
+               printf(">>>%s: Sent failure message\r\n", Name);
+       auth_finished(0, AUTH_REJECT);
+}
+
+       void
+auth_send_retry()
+{
+       /*
+        * if auth_send_cnt <= 0 then auth_send will end up rejecting
+        * the authentication and informing the other side of this.
+        */
+       auth_send(auth_send_data, auth_send_cnt);
+}
+
+       void
+auth_is(data, cnt)
+       unsigned char *data;
+       int cnt;
+{
+       Authenticator *ap;
+
+       if (cnt < 2)
+               return;
+
+       if (data[0] == AUTHTYPE_NULL) {
+               auth_finished(0, AUTH_REJECT);
+               return;
+       }
+
+       if (ap = findauthenticator(data[0], data[1])) {
+               if (ap->is)
+                       (*ap->is)(ap, data+2, cnt-2);
+       } else if (auth_debug_mode)
+               printf(">>>%s: Invalid authentication in IS: %d\r\n",
+                       Name, *data);
+}
+
+       void
+auth_reply(data, cnt)
+       unsigned char *data;
+       int cnt;
+{
+       Authenticator *ap;
+
+       if (cnt < 2)
+               return;
+
+       if (ap = findauthenticator(data[0], data[1])) {
+               if (ap->reply)
+                       (*ap->reply)(ap, data+2, cnt-2);
+       } else if (auth_debug_mode)
+               printf(">>>%s: Invalid authentication in SEND: %d\r\n",
+                       Name, *data);
+}
+
+       void
+auth_finished(ap, result)
+       Authenticator *ap;
+       int result;
+{
+       if (!(authenticated = ap))
+               authenticated = &NoAuth;
+       validuser = result;
+}
+
+       /* ARGSUSED */
+       static void
+auth_intr(sig)
+       int sig;
+{
+       auth_finished(0, AUTH_REJECT);
+}
+
+       int
+auth_wait(name)
+       char *name;
+{
+       if (auth_debug_mode)
+               printf(">>>%s: in auth_wait.\r\n", Name);
+
+       if (Server && !authenticating)
+               return(0);
+
+       (void) signal(SIGALRM, auth_intr);
+       alarm(30);
+       while (!authenticated)
+               if (telnet_spin())
+                       break;
+       alarm(0);
+       (void) signal(SIGALRM, SIG_DFL);
+
+       /*
+        * Now check to see if the user is valid or not
+        */
+       if (!authenticated || authenticated == &NoAuth)
+               return(AUTH_REJECT);
+
+       if (validuser == AUTH_VALID)
+               validuser = AUTH_USER;
+
+       if (authenticated->status)
+               validuser = (*authenticated->status)(authenticated,
+                                                    name, validuser);
+       return(validuser);
+}
+
+       void
+auth_debug(mode)
+       int mode;
+{
+       auth_debug_mode = mode;
+}
+
+       void
+auth_printsub(data, cnt, buf, buflen)
+       unsigned char *data, *buf;
+       int cnt, buflen;
+{
+       Authenticator *ap;
+
+       if ((ap = findauthenticator(data[1], data[2])) && ap->printsub)
+               (*ap->printsub)(data, cnt, buf, buflen);
+       else
+               auth_gen_printsub(data, cnt, buf, buflen);
+}
+
+       void
+auth_gen_printsub(data, cnt, buf, buflen)
+       unsigned char *data, *buf;
+       int cnt, buflen;
+{
+       register unsigned char *cp;
+       unsigned char tbuf[16];
+
+       cnt -= 3;
+       data += 3;
+       buf[buflen-1] = '\0';
+       buf[buflen-2] = '*';
+       buflen -= 2;
+       for (; cnt > 0; cnt--, data++) {
+               sprintf((char *)tbuf, " %d", *data);
+               for (cp = tbuf; *cp && buflen > 0; --buflen)
+                       *buf++ = *cp++;
+               if (buflen <= 0)
+                       return;
+       }
+       *buf = '\0';
+}
+#endif
diff --git a/usr/src/lib/libtelnet/auth.h b/usr/src/lib/libtelnet/auth.h
new file mode 100644 (file)
index 0000000..2e15638
--- /dev/null
@@ -0,0 +1,61 @@
+/*-
+ * Copyright (c) 1991 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * %sccs.include.redist.c%
+ *
+ *     @(#)auth.h      5.1 (Berkeley) %G%
+ */
+
+/*
+ * Copyright (C) 1990 by the Massachusetts Institute of Technology
+ *
+ * Export of this software from the United States of America is assumed
+ * to require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, 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 of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission.  M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is" without express
+ * or implied warranty.
+ */
+
+#ifndef        __AUTH__
+#define        __AUTH__
+
+#define        AUTH_REJECT     0       /* Rejected */
+#define        AUTH_UNKNOWN    1       /* We don't know who he is, but he's okay */
+#define        AUTH_OTHER      2       /* We know him, but not his name */
+#define        AUTH_USER       3       /* We know he name */
+#define        AUTH_VALID      4       /* We know him, and he needs no password */
+
+#if    !defined(P)
+#ifdef __STDC__
+#define P(x)   x
+#else
+#define P(x)   ()
+#endif
+#endif
+
+typedef struct XauthP {
+       int     type;
+       int     way;
+       int     (*init) P((struct XauthP *, int));
+       int     (*send) P((struct XauthP *));
+       void    (*is) P((struct XauthP *, unsigned char *, int));
+       void    (*reply) P((struct XauthP *, unsigned char *, int));
+       int     (*status) P((struct XauthP *, char *, int));
+       void    (*printsub) P((unsigned char *, int, unsigned char *, int));
+} Authenticator;
+
+#include "auth-proto.h"
+
+extern auth_debug_mode;
+#endif