aboutsummaryrefslogtreecommitdiff
path: root/eBones/lib/librkinit/rk_krb.c
diff options
context:
space:
mode:
Diffstat (limited to 'eBones/lib/librkinit/rk_krb.c')
-rw-r--r--eBones/lib/librkinit/rk_krb.c316
1 files changed, 316 insertions, 0 deletions
diff --git a/eBones/lib/librkinit/rk_krb.c b/eBones/lib/librkinit/rk_krb.c
new file mode 100644
index 000000000000..ad8a6537b2d4
--- /dev/null
+++ b/eBones/lib/librkinit/rk_krb.c
@@ -0,0 +1,316 @@
+/*
+ * $Id: rk_krb.c,v 1.1 1993/12/10 19:36:09 dglo Exp gibbs $
+ * $Source: /usr/src/eBones/librkinit/RCS/rk_krb.c,v $
+ * $Author: dglo $
+ *
+ * This file contains the kerberos parts of the rkinit library.
+ * See the comment at the top of rk_lib.c for a description of the naming
+ * conventions used within the rkinit library.
+ */
+
+#if !defined(lint) && !defined(SABER) && !defined(LOCORE) && defined(RCS_HDRS)
+static char *rcsid = "$Id: rk_krb.c,v 1.1 1993/12/10 19:36:09 dglo Exp gibbs $";
+#endif /* lint || SABER || LOCORE || RCS_HDRS */
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <netinet/in.h>
+#include <krb.h>
+#include <des.h>
+
+#include <signal.h>
+#include <setjmp.h>
+
+#ifdef POSIX
+#include <termios.h>
+#else
+#include <sgtty.h>
+#endif
+
+#include <rkinit.h>
+#include <rkinit_err.h>
+#include <rkinit_private.h>
+
+static jmp_buf env;
+static void sig_restore();
+static void push_signals();
+static void pop_signals();
+
+/* Information to be passed around within client get_in_tkt */
+typedef struct {
+ KTEXT scip; /* Server KDC packet */
+ char *username;
+ char *host;
+} rkinit_intkt_info;
+
+static char errbuf[BUFSIZ];
+
+/* The compiler complains if this is declared static. */
+#ifdef __STDC__
+int rki_key_proc(char *user, char *instance, char *realm, char *arg,
+ des_cblock *key)
+#else
+int rki_key_proc(user, instance, realm, arg, key)
+ char *user;
+ char *instance;
+ char *realm;
+ char *arg;
+ des_cblock *key;
+#endif /* __STDC__ */
+
+{
+ rkinit_intkt_info *rii = (rkinit_intkt_info *)arg;
+ char password[BUFSIZ];
+ int ok = 0;
+#ifdef POSIX
+ struct termios ttyb;
+#else
+ struct sgttyb ttyb; /* For turning off echo */
+#endif
+
+ SBCLEAR(ttyb);
+ BCLEAR(password);
+
+ /*
+ * If the username does not match the aname in the ticket,
+ * we will print that too. Otherwise, we won't.
+ */
+
+ printf("Kerberos initialization (%s)", rii->host);
+ if (strcmp(rii->username, user))
+ printf(": tickets will be owned by %s", rii->username);
+
+ printf("\nPassword for %s%s%s@%s: ", user,
+ (instance[0]) ? "." : "", instance, realm);
+
+ fflush(stdout);
+
+ push_signals();
+ if (setjmp(env)) {
+ ok = -1;
+ goto lose;
+ }
+
+#ifndef POSIX
+ ioctl(0, TIOCGETP, &ttyb);
+ ttyb.sg_flags &= ~ECHO;
+ ioctl(0, TIOCSETP, &ttyb);
+#else
+ (void) tcgetattr(0, &ttyb);
+ ttyb.c_lflag &= ~ECHO;
+ (void) tcsetattr(0, TCSAFLUSH, &ttyb);
+#endif
+
+ bzero(password, sizeof(password));
+ if (read(0, password, sizeof(password)) == -1) {
+ perror("read");
+ ok = -1;
+ goto lose;
+ }
+
+ if (password[strlen(password)-1] == '\n')
+ password[strlen(password)-1] = 0;
+
+ /* Generate the key from the password and destroy the password */
+
+ des_string_to_key(password, key);
+
+lose:
+ BCLEAR(password);
+
+#ifndef POSIX
+ ttyb.sg_flags |= ECHO;
+ ioctl(0, TIOCSETP, &ttyb);
+#else
+ ttyb.c_lflag |= ECHO;
+ (void) tcsetattr(0, TCSAFLUSH, &ttyb);
+#endif
+
+ pop_signals();
+ printf("\n");
+
+ return(ok);
+}
+
+#ifdef __STDC__
+static int rki_decrypt_tkt(char *user, char *instance, char *realm,
+ char *arg, int (*key_proc)(), KTEXT *cipp)
+#else
+static int rki_decrypt_tkt(user, instance, realm, arg, key_proc, cipp)
+ char *user;
+ char *instance;
+ char *realm;
+ char *arg;
+ int (*key_proc)();
+ KTEXT *cipp;
+#endif /* __STDC__ */
+{
+ KTEXT cip = *cipp;
+ C_Block key; /* Key for decrypting cipher */
+ Key_schedule key_s;
+ KTEXT scip = 0; /* cipher from rkinit server */
+
+ rkinit_intkt_info *rii = (rkinit_intkt_info *)arg;
+
+ /* generate a key */
+ {
+ register int rc;
+ rc = (*key_proc)(user, instance, realm, arg, key);
+ if (rc)
+ return(rc);
+ }
+
+ des_key_sched(&key, key_s);
+
+ /* Decrypt information from KDC */
+ des_pcbc_encrypt((C_Block *)cip->dat,(C_Block *)cip->dat,
+ (long) cip->length, key_s, &key, 0);
+
+ /* DescrYPT rkinit server's information from KDC */
+ scip = rii->scip;
+ des_pcbc_encrypt((C_Block *)scip->dat,(C_Block *)scip->dat,
+ (long) scip->length, key_s, &key, 0);
+
+ /* Get rid of all traces of key */
+ bzero((char *)key, sizeof(key));
+ bzero((char *)key_s, sizeof(key_s));
+
+ return(0);
+}
+
+#ifdef __STDC__
+int rki_get_tickets(int version, char *host, char *r_krealm, rkinit_info *info)
+#else
+int rki_get_tickets(version, host, r_krealm, info)
+ int version;
+ char *host;
+ char *r_krealm;
+ rkinit_info *info;
+#endif /* __STDC__ */
+{
+ int status = RKINIT_SUCCESS;
+ KTEXT_ST auth;
+ char phost[MAXHOSTNAMELEN];
+ KTEXT_ST scip; /* server's KDC packet */
+ des_cblock key;
+ des_key_schedule sched;
+ struct sockaddr_in caddr;
+ struct sockaddr_in saddr;
+ CREDENTIALS cred;
+ MSG_DAT msg_data;
+ u_char enc_data[MAX_KTXT_LEN];
+
+ rkinit_intkt_info rii;
+
+ SBCLEAR(auth);
+ BCLEAR(phost);
+ SBCLEAR(rii);
+ SBCLEAR(scip);
+ SBCLEAR(caddr);
+ SBCLEAR(saddr);
+ SBCLEAR(cred);
+ SBCLEAR(msg_data);
+ BCLEAR(enc_data);
+
+ if ((status = rki_send_rkinit_info(version, info)) != RKINIT_SUCCESS)
+ return(status);
+
+ if ((status = rki_rpc_get_skdc(&scip)) != RKINIT_SUCCESS)
+ return(status);
+
+ rii.scip = &scip;
+ rii.host = host;
+ rii.username = info->username;
+
+ if ((status = krb_get_in_tkt(info->aname, info->inst, info->realm,
+ "krbtgt", info->realm, 1,
+ rki_key_proc, rki_decrypt_tkt, (char *)&rii))) {
+ strcpy(errbuf, krb_err_txt[status]);
+ rkinit_errmsg(errbuf);
+ return(RKINIT_KERBEROS);
+ }
+
+ /* Create an authenticator */
+ strcpy(phost, krb_get_phost(host));
+ if ((status = krb_mk_req(&auth, KEY, phost, r_krealm, 0))) {
+ sprintf(errbuf, "krb_mk_req: %s", krb_err_txt[status]);
+ rkinit_errmsg(errbuf);
+ return(RKINIT_KERBEROS);
+ }
+
+ /* Re-encrypt server KDC packet in session key */
+ /* Get credentials from ticket file */
+ if ((status = krb_get_cred(KEY, phost, r_krealm, &cred))) {
+ sprintf(errbuf, "krb_get_cred: %s", krb_err_txt[status]);
+ rkinit_errmsg(errbuf);
+ return(RKINIT_KERBEROS);
+ }
+
+ /* Exctract the session key and make the schedule */
+ bcopy(cred.session, key, sizeof(key));
+ if ((status = des_key_sched(&key, sched))) {
+ sprintf(errbuf, "des_key_sched: %s", krb_err_txt[status]);
+ rkinit_errmsg(errbuf);
+ return(RKINIT_DES);
+ }
+
+ /* Get client and server addresses */
+ if ((status = rki_get_csaddr(&caddr, &saddr)) != RKINIT_SUCCESS)
+ return(status);
+
+ /*
+ * scip was passed to krb_get_in_tkt, where it was decrypted.
+ * Now re-encrypt in the session key.
+ */
+
+ msg_data.app_data = enc_data;
+ if ((msg_data.app_length =
+ krb_mk_priv(scip.dat, msg_data.app_data, scip.length, sched, key,
+ &caddr, &saddr)) == -1) {
+ sprintf(errbuf, "krb_mk_priv failed.");
+ rkinit_errmsg(errbuf);
+ return(RKINIT_KERBEROS);
+ }
+
+ /* Destroy tickets, which we no longer need */
+ dest_tkt();
+
+ if ((status = rki_rpc_send_ckdc(&msg_data)) != RKINIT_SUCCESS)
+ return(status);
+
+ if ((status = rki_rpc_sendauth(&auth)) != RKINIT_SUCCESS)
+ return(status);
+
+ if ((status = rki_rpc_get_status()))
+ return(status);
+
+ return(RKINIT_SUCCESS);
+}
+
+
+static void (*old_sigfunc[NSIG])(int);
+
+static void push_signals()
+{
+ register i;
+ for (i = 0; i < NSIG; i++)
+ old_sigfunc[i] = signal(i,sig_restore);
+}
+
+static void pop_signals()
+{
+ register i;
+ for (i = 0; i < NSIG; i++)
+ signal(i,old_sigfunc[i]);
+}
+
+static void sig_restore(sig,code,scp)
+ int sig,code;
+ struct sigcontext *scp;
+{
+ longjmp(env,1);
+}