diff options
author | gibbs <gibbs@FreeBSD.org> | 1995-09-15 06:09:30 +0000 |
---|---|---|
committer | gibbs <gibbs@FreeBSD.org> | 1995-09-15 06:09:30 +0000 |
commit | 3796a8e4581e3ab171ddac0d5818e0add5272118 (patch) | |
tree | 7ac6883caac399f1a7d4bcbb12e4d8a52a73c654 | |
parent | 109eb67c2a4c6318c0f2cb71db786f785b7bcc1c (diff) | |
download | FreeBSD-src-3796a8e4581e3ab171ddac0d5818e0add5272118.zip FreeBSD-src-3796a8e4581e3ab171ddac0d5818e0add5272118.tar.gz |
MIT's librkinit. Part of the rkinit suite. Rkinit allows you to forward
tickets to other kerberos hosts safely in one easy step.
-rw-r--r-- | eBones/lib/librkinit/Makefile | 19 | ||||
-rw-r--r-- | eBones/lib/librkinit/rk_krb.c | 316 | ||||
-rw-r--r-- | eBones/lib/librkinit/rk_lib.c | 100 | ||||
-rw-r--r-- | eBones/lib/librkinit/rk_rpc.c | 387 | ||||
-rw-r--r-- | eBones/lib/librkinit/rk_util.c | 214 | ||||
-rw-r--r-- | eBones/lib/librkinit/rkinit.3 | 167 | ||||
-rw-r--r-- | eBones/lib/librkinit/rkinit_err.et | 32 |
7 files changed, 1235 insertions, 0 deletions
diff --git a/eBones/lib/librkinit/Makefile b/eBones/lib/librkinit/Makefile new file mode 100644 index 0000000..7d4b4ca --- /dev/null +++ b/eBones/lib/librkinit/Makefile @@ -0,0 +1,19 @@ +# @(#)Makefile 8.1 (Berkeley) 6/4/93 + +LIB= rkinit +CFLAGS+=-DKERBEROS -DCRYPT -DDEBUG -I${RKINITOBJDIR} +SRCS= rkinit_err.c rk_lib.c rk_rpc.c rk_util.c rk_krb.c rkinit_err.c + +LDADD+= -lcom_err + +beforeinstall: + -cd ${.OBJDIR}; cmp -s rkinit_err.h \ + ${DESTDIR}/usr/include/kerberosIV/rkinit_err.h || \ + install -c -o ${BINOWN} -g ${BINGRP} -m 444 rkinit_err.h \ + ${DESTDIR}/usr/include/kerberosIV + +MAN3= rkinit.3 + +.include <bsd.lib.mk> + +rkinit_err.c: ${RKINITOBJDIR}/rkinit_err.h diff --git a/eBones/lib/librkinit/rk_krb.c b/eBones/lib/librkinit/rk_krb.c new file mode 100644 index 0000000..ad8a653 --- /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); +} diff --git a/eBones/lib/librkinit/rk_lib.c b/eBones/lib/librkinit/rk_lib.c new file mode 100644 index 0000000..06b8f39 --- /dev/null +++ b/eBones/lib/librkinit/rk_lib.c @@ -0,0 +1,100 @@ +/* + * $Id: rk_lib.c,v 1.1 1993/12/10 19:32:01 dglo Exp gibbs $ + * $Source: /usr/src/eBones/librkinit/RCS/rk_lib.c,v $ + * $Author: dglo $ + * + * This file contains the non-rpc top-level rkinit library routines. + * The routines in the rkinit library that should be called from clients + * are exactly those defined in this file. + * + * The naming convetions used within the rkinit library are as follows: + * Functions intended for general client use start with rkinit_ + * Functions intended for use only inside the library or server start with + * rki_ + * Functions that do network communcation start with rki_rpc_ + * Static functions can be named in any fashion. + */ + +#if !defined(lint) && !defined(SABER) && !defined(LOCORE) && defined(RCS_HDRS) +static char *rcsid = "$Id: rk_lib.c,v 1.1 1993/12/10 19:32:01 dglo Exp gibbs $"; +#endif /* lint || SABER || LOCORE || RCS_HDRS */ + +#include <stdio.h> +#include <unistd.h> +#include <string.h> +#include <setjmp.h> +#include <krb.h> + +#include <rkinit.h> +#include <rkinit_private.h> +#include <rkinit_err.h> + +#ifdef __STDC__ +char *rkinit_errmsg(char *string) +#else +char *rkinit_errmsg(string) + char *string; +#endif /* __STDC__ */ +{ + static char errmsg[BUFSIZ]; + + if (string) { + BCLEAR(errmsg); + strncpy(errmsg, string, sizeof(errmsg) - 1); + } + + return(errmsg); +} + +#ifdef __STDC__ +int rkinit(char *host, char *r_krealm, rkinit_info *info, int timeout) +#else +int rkinit(host, r_krealm, info, timeout) + char *host; + char *r_krealm; + rkinit_info *info; + int timeout; +#endif /* __STDC__ */ +{ + int status = RKINIT_SUCCESS; + int version = 0; + char phost[MAXHOSTNAMELEN]; + jmp_buf timeout_env; + void (*old_alrm)(int) = NULL; + char origtktfilename[MAXPATHLEN]; /* original ticket file name */ + char tktfilename[MAXPATHLEN]; /* temporary client ticket file */ + + BCLEAR(phost); + BCLEAR(origtktfilename); + BCLEAR(tktfilename); + BCLEAR(timeout_env); + + init_rkin_err_tbl(); + + if ((status = rki_setup_rpc(host))) + return(status); + + if (timeout) + old_alrm = rki_setup_timer(timeout_env); + + /* The alarm handler longjmps us to here. */ + if ((status = setjmp(timeout_env)) == 0) { + + strcpy(origtktfilename, tkt_string()); + sprintf(tktfilename, "/tmp/tkt_rkinit.%ld", getpid()); + krb_set_tkt_string(tktfilename); + + if ((status = rki_choose_version(&version)) == RKINIT_SUCCESS) + status = rki_get_tickets(version, host, r_krealm, info); + } + + if (timeout) + rki_restore_timer(old_alrm); + + dest_tkt(); + krb_set_tkt_string(origtktfilename); + + rki_cleanup_rpc(); + + return(status); +} diff --git a/eBones/lib/librkinit/rk_rpc.c b/eBones/lib/librkinit/rk_rpc.c new file mode 100644 index 0000000..dd61327 --- /dev/null +++ b/eBones/lib/librkinit/rk_rpc.c @@ -0,0 +1,387 @@ +/* + * $Id: rk_rpc.c,v 1.1 1993/12/10 19:36:09 dglo Exp gibbs $ + * $Source: /usr/src/eBones/librkinit/RCS/rk_rpc.c,v $ + * $Author: dglo $ + * + * This file contains functions that are used for network communication. + * 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_rpc.c,v 1.1 1993/12/10 19:36:09 dglo Exp gibbs $"; +#endif /* lint || SABER || LOCORE || RCS_HDRS */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include <sys/uio.h> +#include <unistd.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <netdb.h> +#include <errno.h> + +#include <rkinit.h> +#include <rkinit_err.h> +#include <rkinit_private.h> + +extern int errno; + +static int sock; +struct sockaddr_in saddr; + +static char errbuf[BUFSIZ]; + +char *calloc(); + +#ifdef __STDC__ +int rki_send_packet(int sock, char type, u_int32_t length, const char *data) +#else +int rki_send_packet(sock, type, length, data) + int sock; + char type; + u_int32_t length; + const char *data; +#endif /* __STDC__ */ +{ + int len; + u_char *packet; + u_int32_t pkt_len; + u_int32_t net_pkt_len; + + pkt_len = length + PKT_DATA; + + if ((packet = (u_char *)calloc(pkt_len, sizeof(u_char))) == NULL) { + sprintf(errbuf, "rki_send_packet: failure allocating %d bytes", + pkt_len * sizeof(u_char)); + rkinit_errmsg(errbuf); + return(RKINIT_MEMORY); + } + + net_pkt_len = htonl(pkt_len); + + packet[PKT_TYPE] = type; + bcopy((char *)&net_pkt_len, packet + PKT_LEN, sizeof(u_int32_t)); + bcopy(data, packet + PKT_DATA, length); + + if ((len = write(sock, packet, pkt_len)) != pkt_len) { + if (len == -1) + sprintf(errbuf, "write: %s", sys_errlist[errno]); + else + sprintf(errbuf, "write: %d bytes written; %d bytes actually sent", + pkt_len, len); + rkinit_errmsg(errbuf); + free(packet); + return(RKINIT_WRITE); + } + + free(packet); + return(RKINIT_SUCCESS); +} + +#ifdef __STDC__ +int rki_get_packet(int sock, u_char type, u_int32_t *length, char *data) +#else +int rki_get_packet(sock, type, length, data) + int sock; + u_char type; + u_int32_t *length; + char *data; +#endif /* __STDC__ */ +{ + int len; + int len_sofar = 0; + u_int32_t expected_length = 0; + int got_full_packet = FALSE; + int tries = 0; + u_char *packet; + + u_int32_t max_pkt_len; + + max_pkt_len = *length + PKT_DATA; + + if ((packet = (u_char *)calloc(max_pkt_len, sizeof(u_char))) == NULL) { + sprintf(errbuf, "rki_get_packet: failure allocating %d bytes", + max_pkt_len * sizeof(u_char)); + rkinit_errmsg(errbuf); + return(RKINIT_MEMORY); + } + + /* Read the packet type and length */ + while ((len_sofar < PKT_DATA) && (tries < RETRIES)) { + if ((len = read(sock, packet + len_sofar, PKT_DATA - len_sofar)) < 0) { + sprintf(errbuf, "read: %s", sys_errlist[errno]); + rkinit_errmsg(errbuf); + return(RKINIT_READ); + } + len_sofar += len; + tries++; + } + if (len_sofar < PKT_DATA) { + sprintf(errbuf, + "read: expected to receive at least %d bytes; received %d", + PKT_DATA, len_sofar); + rkinit_errmsg(errbuf); + return(RKINIT_PACKET); + } + bcopy(packet + PKT_LEN, (char *)&expected_length, sizeof(u_int32_t)); + expected_length = ntohl(expected_length); + if (expected_length > max_pkt_len) { + sprintf(errbuf, "%s %d %s %d", + "rki_get_packet: incoming message of size", + expected_length, + "is larger than message buffer of size", + max_pkt_len); + rkinit_errmsg(errbuf); + return(RKINIT_PACKET); + } + tries = 0; + while (!got_full_packet && (tries < RETRIES)) { + if ((len = read(sock, packet + len_sofar, + expected_length - len_sofar)) < 0) { + sprintf(errbuf, "read: %s", sys_errlist[errno]); + rkinit_errmsg(errbuf); + return(RKINIT_READ); + } + len_sofar += len; + if (expected_length == len_sofar) + got_full_packet = TRUE; + } + if (len_sofar < expected_length) { + sprintf(errbuf, + "read: expected to receive at least %d bytes; received %d", + expected_length, len_sofar); + rkinit_errmsg(errbuf); + return(RKINIT_PACKET); + } + if (packet[PKT_TYPE] == MT_DROP) { + BCLEAR(errbuf); + rkinit_errmsg(errbuf); + return(RKINIT_DROPPED); + } + + if (packet[PKT_TYPE] != type) { + sprintf(errbuf, "Expected packet type of %s; got %s", + rki_mt_to_string(type), + rki_mt_to_string(packet[PKT_TYPE])); + rkinit_errmsg(errbuf); + return(RKINIT_PACKET); + } + + *length = len_sofar - PKT_DATA; + bcopy(packet + PKT_DATA, data, *length); + + free(packet); + + return(RKINIT_SUCCESS); +} + +#ifdef __STDC__ +int rki_setup_rpc(char *host) +#else +int rki_setup_rpc(host) + char *host; +#endif /* __STDC__ */ +{ + struct hostent *hp; + struct servent *sp; + int port; + + SBCLEAR(saddr); + SBCLEAR(hp); + SBCLEAR(sp); + + if ((hp = gethostbyname(host)) == NULL) { + sprintf(errbuf, "%s: unknown host.", host); + rkinit_errmsg(errbuf); + return(RKINIT_HOST); + } + + if ((sp = getservbyname(SERVENT, "tcp"))) + port = sp->s_port; + else + /* Fall back on known port number */ + port = htons(PORT); + + saddr.sin_family = hp->h_addrtype; + bcopy(hp->h_addr, (char *)&saddr.sin_addr, hp->h_length); + saddr.sin_port = port; + + if ((sock = socket(hp->h_addrtype, SOCK_STREAM, IPPROTO_IP)) < 0) { + sprintf(errbuf, "socket: %s", sys_errlist[errno]); + rkinit_errmsg(errbuf); + return(RKINIT_SOCKET); + } + + if (connect(sock, (struct sockaddr *)&saddr, sizeof (saddr)) < 0) { + sprintf(errbuf, "connect: %s", sys_errlist[errno]); + rkinit_errmsg(errbuf); + close(sock); + return(RKINIT_CONNECT); + } + + return(RKINIT_SUCCESS); +} + +#ifdef __STDC__ +int rki_rpc_exchange_version_info(int c_lversion, int c_hversion, + int *s_lversion, int *s_hversion) +#else +int rki_rpc_exchange_version_info(c_lversion, c_hversion, + s_lversion, s_hversion) + int c_lversion; + int c_hversion; + int *s_lversion; + int *s_hversion; +#endif /* __STDC__ */ +{ + int status = RKINIT_SUCCESS; + u_char version_info[VERSION_INFO_SIZE]; + u_int32_t length = sizeof(version_info); + + version_info[0] = (u_char) c_lversion; + version_info[1] = (u_char) c_hversion; + + if ((status = rki_send_packet(sock, MT_CVERSION, length, + (char *)version_info)) != RKINIT_SUCCESS) + return(status); + + if ((status = rki_get_packet(sock, MT_SVERSION, &length, + (char *)version_info)) != RKINIT_SUCCESS) + return(status); + + *s_lversion = (int) version_info[0]; + *s_hversion = (int) version_info[1]; + + return(RKINIT_SUCCESS); +} + +#ifdef __STDC__ +int rki_rpc_send_rkinit_info(rkinit_info *info) +#else +int rki_rpc_send_rkinit_info(info) + rkinit_info *info; +#endif /* __STDC__ */ +{ + rkinit_info info_copy; + + bcopy(info, &info_copy, sizeof(rkinit_info)); + info_copy.lifetime = htonl(info_copy.lifetime); + return(rki_send_packet(sock, MT_RKINIT_INFO, sizeof(rkinit_info), + (char *)&info_copy)); +} + +#ifdef __STDC__ +int rki_rpc_get_status(void) +#else +int rki_rpc_get_status() +#endif /* __STDC__ */ +{ + char msg[BUFSIZ]; + int status = RKINIT_SUCCESS; + u_int32_t length = sizeof(msg); + + if ((status = rki_get_packet(sock, MT_STATUS, &length, msg))) + return(status); + + if (length == 0) + return(RKINIT_SUCCESS); + else { + rkinit_errmsg(msg); + return(RKINIT_DAEMON); + } +} + +#ifdef __STDC__ +int rki_rpc_get_ktext(int sock, KTEXT auth, u_char type) +#else +int rki_rpc_get_ktext(sock, auth, type) + int sock; + KTEXT auth; + u_char type; +#endif /* __STDC__ */ +{ + int status = RKINIT_SUCCESS; + u_int32_t length = MAX_KTXT_LEN; + + if ((status = rki_get_packet(sock, type, &length, (char *)auth->dat))) + return(status); + + auth->length = length; + + return(RKINIT_SUCCESS); +} + +#ifdef __STDC__ +int rki_rpc_sendauth(KTEXT auth) +#else +int rki_rpc_sendauth(auth) + KTEXT auth; +#endif /* __STDC__ */ +{ + return(rki_send_packet(sock, MT_AUTH, auth->length, (char *)auth->dat)); +} + + +#ifdef __STDC__ +int rki_rpc_get_skdc(KTEXT scip) +#else +int rki_rpc_get_skdc(scip) + KTEXT scip; +#endif /* __STDC__ */ +{ + return(rki_rpc_get_ktext(sock, scip, MT_SKDC)); +} + +#ifdef __STDC__ +int rki_rpc_send_ckdc(MSG_DAT *scip) +#else +int rki_rpc_send_ckdc(scip) + MSG_DAT *scip; +#endif /* __STDC__ */ +{ + return(rki_send_packet(sock, MT_CKDC, scip->app_length, + (char *)scip->app_data)); +} + +#ifdef __STDC__ +int rki_get_csaddr(struct sockaddr_in *caddrp, struct sockaddr_in *saddrp) +#else +int rki_get_csaddr(caddrp, saddrp) + struct sockaddr_in *caddrp; + struct sockaddr_in *saddrp; +#endif /* __STDC__ */ +{ + int addrlen = sizeof(struct sockaddr_in); + + bcopy((char *)&saddr, (char *)saddrp, addrlen); + + if (getsockname(sock, (struct sockaddr *)caddrp, &addrlen) < 0) { + sprintf(errbuf, "getsockname: %s", sys_errlist[errno]); + rkinit_errmsg(errbuf); + return(RKINIT_GETSOCK); + } + + return(RKINIT_SUCCESS); +} + +#ifdef __STDC__ +void rki_drop_server(void) +#else +void rki_drop_server() +#endif /* __STDC__ */ +{ + (void) rki_send_packet(sock, MT_DROP, 0, ""); +} + +#ifdef __STDC__ +void rki_cleanup_rpc(void) +#else +void rki_cleanup_rpc() +#endif /* __STDC__ */ +{ + rki_drop_server(); + (void) close(sock); +} diff --git a/eBones/lib/librkinit/rk_util.c b/eBones/lib/librkinit/rk_util.c new file mode 100644 index 0000000..4333d38 --- /dev/null +++ b/eBones/lib/librkinit/rk_util.c @@ -0,0 +1,214 @@ +/* + * $Id: rk_util.c,v 1.1 1993/12/10 19:36:09 dglo Exp gibbs $ + * $Source: /usr/src/eBones/librkinit/RCS/rk_util.c,v $ + * $Author: dglo $ + * + * This file contains internal routines for general use by the rkinit + * library and server. + * + * 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_util.c,v 1.1 1993/12/10 19:36:09 dglo Exp gibbs $"; +#endif /* lint || SABER || LOCORE || RCS_HDRS */ + +#include <stdio.h> +#include <sys/types.h> +#include <string.h> +#include <setjmp.h> +#include <signal.h> +#include <sys/time.h> + +#ifdef DEBUG +#include <syslog.h> +#endif /* DEBUG */ + +#include <rkinit.h> +#include <rkinit_private.h> +#include <rkinit_err.h> + +#define RKINIT_TIMEOUTVAL 60 + +static char errbuf[BUFSIZ]; +static jmp_buf timeout_env; + +#ifdef DEBUG +static int _rkinit_server_ = FALSE; + +#ifdef __STDC__ +void rki_dmsg(char *string) +#else +void rki_dmsg(string) + char *string; +#endif /* __STDC__ */ +{ + if (_rkinit_server_) + syslog(LOG_NOTICE, string); + else + printf("%s\n", string); +} + +#ifdef __STDC__ +void rki_i_am_server(void) +#else +void rki_i_am_server() +#endif /* __STDC__ */ +{ + _rkinit_server_ = TRUE; +} +#else /* DEBUG */ +#ifdef __STDC__ +void rki_dmsg(char *string) +#else +void rki_dmsg(string) + char *string; +#endif /* __STDC__ */ +{ + return; +} + +#endif /* DEBUG */ + +#ifdef __STDC__ +const char *rki_mt_to_string(int mt) +#else +const char *rki_mt_to_string(mt) + int mt; +#endif /* __STDC__ */ +{ + char *string = 0; + + switch(mt) { + case MT_STATUS: + string = "Status message"; + break; + case MT_CVERSION: + string = "Client version"; + break; + case MT_SVERSION: + string = "Server version"; + break; + case MT_RKINIT_INFO: + string = "Rkinit information"; + break; + case MT_SKDC: + string = "Server kdc packet"; + break; + case MT_CKDC: + string = "Client kdc packet"; + break; + case MT_AUTH: + string = "Authenticator"; + break; + case MT_DROP: + string = "Drop server"; + break; + default: + string = "Unknown message type"; + break; + } + + return(string); +} + +#ifdef __STDC__ +int rki_choose_version(int *version) +#else +int rki_choose_version(version) + int *version; +#endif /* __STDC__ */ +{ + int s_lversion; /* lowest version number server supports */ + int s_hversion; /* highest version number server supports */ + int status = RKINIT_SUCCESS; + + if ((status = + rki_rpc_exchange_version_info(RKINIT_LVERSION, RKINIT_HVERSION, + &s_lversion, + &s_hversion)) != RKINIT_SUCCESS) + return(status); + + *version = min(RKINIT_HVERSION, s_hversion); + if (*version < max(RKINIT_LVERSION, s_lversion)) { + sprintf(errbuf, + "Can't run version %d client against version %d server.", + RKINIT_HVERSION, s_hversion); + rkinit_errmsg(errbuf); + status = RKINIT_VERSION; + } + + return(status); +} + +#ifdef __STDC__ +int rki_send_rkinit_info(int version, rkinit_info *info) +#else +int rki_send_rkinit_info(version, info) + int version; + rkinit_info *info; +#endif /* __STDC__ */ +{ + int status = 0; + + if ((status = rki_rpc_send_rkinit_info(info)) != RKINIT_SUCCESS) + return(status); + + return(rki_rpc_get_status()); +} + +#ifdef __STDC__ +static void rki_timeout(int signal) +#else +static void rki_timeout(signal) + int signal; +#endif /* __STDC__ */ +{ + sprintf(errbuf, "%d seconds exceeded.", RKINIT_TIMEOUTVAL); + rkinit_errmsg(errbuf); + longjmp(timeout_env, RKINIT_TIMEOUT); + return; +} + +#ifdef __STDC__ +static void set_timer(int secs) +#else +static void set_timer(secs) + int secs; +#endif /* __STDC__ */ +{ + struct itimerval timer; /* Time structure for timeout */ + + /* Set up an itimer structure to send an alarm signal after TIMEOUT + seconds. */ + timer.it_interval.tv_sec = secs; + timer.it_interval.tv_usec = 0; + timer.it_value = timer.it_interval; + + (void) setitimer (ITIMER_REAL, &timer, (struct itimerval *)0); +} + + +#ifdef __STDC__ +void (*rki_setup_timer(jmp_buf env))(int) +#else +void (*rki_setup_timer(env))(int) + jmp_buf env; +#endif /* __STDC__ */ +{ + bcopy((char *)env, (char *)timeout_env, sizeof(jmp_buf)); + set_timer(RKINIT_TIMEOUTVAL); + return(signal(SIGALRM, rki_timeout)); +} + +#ifdef __STDC__ +void rki_restore_timer(void (*old_alrm)(int)) +#else +void rki_restore_timer(old_alrm) + void (*old_alrm)(int); +#endif /* __STDC__ */ +{ + set_timer(0); + (void) signal(SIGALRM, old_alrm); +} diff --git a/eBones/lib/librkinit/rkinit.3 b/eBones/lib/librkinit/rkinit.3 new file mode 100644 index 0000000..fe6bdf7 --- /dev/null +++ b/eBones/lib/librkinit/rkinit.3 @@ -0,0 +1,167 @@ +.\" +.\" $Header: /local/cvsfiles/kerberos/src/appl/rkinit/man/rkinit.3,v 1.1 1991/12/03 23:21:29 eichin Exp $ +.\" $Source: /local/cvsfiles/kerberos/src/appl/rkinit/man/rkinit.3,v $ +.\" $Author: eichin $ +.\" +.\" +.TH RKINIT 3 "November 12, 1989" +.SH NAME +rkinit, rkinit_errmsg +.SH SYNOPSIS +.nf +.nj +.ft B +#include <rkinit.h> +#include <rkinit_err.h> +.PP +.ft B +int rkinit(host, r_krealm, info, timeout) + char *host; + char *r_krealm; + rkinit_info *info; + int timeout; +.PP +.ft B +char *rkinit_errmsg(string) + char *string; +.fi +.ft R +.SH DESCRIPTION +This library contains the calls necessary to interface with the +.I rkinit +system of remote ticket establishment. See +.IR rkinit (1) +for more information on +.I rkinit +.PP +.I rkinit.h +is the header file that contains information that all clients +will need to use. +.PP +.I rkinit_err.h +is the +.I com_err +error table header file. See +.IR com_err (3) +for more information about +.I com_err. +.PP +.IR rkinit () +takes as arguments the name of the host on which you wish to +establish tickets, the kerberos realm of the remote host, a +fully initialized rkinit_info structure, and a boolean value +telling +whether or not +.IR rkinit () +should time out if the transaction +fails to complete after a certain about of time. +This call does not know about about default values, so +something must be filled in for everything except for the ticket +filename in the rkinit_info structure described below. + +.nf +.nj +.ft B +This is the rkinit_info type: + +typedef struct { + char aname[ANAME_SZ + 1]; + char inst[INST_SZ + 1]; + char realm[REALM_SZ + 1]; + char sname[ANAME_SZ + 1]; + char sinst[INST_SZ + 1]; + char username[9]; /* max local name length + 1 */ + char tktfilename[MAXPATHLEN + 1]; + long lifetime; +} rkinit_info; +.fi +.ft R + +.I aname +is the name part of the kerberos principal for which tickets are +being requested. + +.I inst +is the instance part. + +.I realm +is the realm part. + +.I sname +is the service name of the key that will appear in the remote +initial ticket (for example, "krbtgt"). + +.I sname +is the service instance. + +.I username +is the name of the local user on the remote host who will own +the ticket file. + +.I tktfilename +is the name of the file on the remote host in which the +tickets will be stored. This is the only field in the structure +for which a blank value is filled in. If this value is left +blank, the server will figure out what to call the ticket file +by using the kerberos library default as determined by +.I TKT_FILE +as defined in +.IR krb.h . + +.I lifetime +is the lifetime of the tickets in the usual five minute +intervals. It is possible with this routine, as with +.IR krb_get_in_tkt (3) +to request tickets with zero lifetime. + +.IR rkinit (), +while it is running, opens a socket, changes the name +of the default kerberos ticket file, and changes the signal +handler for the ALRM signal (if timeout != 0). rkinit() +restores all these values when it exits whether it exits with +an error or not, so clients using the rkinit library need not +worry about this information. + +.IR rkinit_errmsg () +takes a string as its only argument. Passing +other than NULL to this routine should be done +by only the rkinit library and server. +Doing this sets the current rkinit +error message. Calling +.IR rkinit_errmsg () +with NULL as the argument returns the current rkinit error +message. +Although the rkinit library uses +.IR com_err (3) +for error handling, the error messages returned by +.IR com_err () +may not be specific enough. A client could report the error +message returned by rkinit as follows: + + +.nf +.nj +.ft B +if (status = rkinit(host, r_krealm, &info, timeout)) { + com_err(argv[0], status, "while obtaining remote tickets:"); + fprintf(stderr, "%s\\n", rkinit_errmsg(0)); + exit(1); +} +.fi +.ft R + +.SH SEE ALSO +kerberos(1), kerberos(3), rkinit(1), rkinitd(8) + +.SH DIAGNOSTICS +.IR rkinit () +is usually good about reporting error messages to the client. +It will probably not handle uninitialized variables well, +however. Make sure that things like the realm of the remote +host and the lifetime of the tickets have been properly +initialized before calling +.IR rkinit (). + + +.SH AUTHOR +Emanuel Jay Berkenbilt (MIT-Project Athena) diff --git a/eBones/lib/librkinit/rkinit_err.et b/eBones/lib/librkinit/rkinit_err.et new file mode 100644 index 0000000..d0ade5b --- /dev/null +++ b/eBones/lib/librkinit/rkinit_err.et @@ -0,0 +1,32 @@ +# +# $Header: /local/cvsfiles/kerberos/src/appl/rkinit/lib/rkinit_err.et,v 1.1 1991/12/03 23:20:58 eichin Exp $ +# $Source: /local/cvsfiles/kerberos/src/appl/rkinit/lib/rkinit_err.et,v $ +# $Author: eichin $ +# +# These error messages will probably not be printed by com_err. +# Instead, a better error message (with specific information) +# will be obtained by a call to rkinit_errmsg(). +# + +et rkin + +ec RKINIT_RCSID, "$Header: /local/cvsfiles/kerberos/src/appl/rkinit/lib/rkinit_err.et,v 1.1 1991/12/03 23:20:58 eichin Exp $" +ec RKINIT_VERSION, "Version mismatch" +ec RKINIT_HOST, "Failure getting host information" +ec RKINIT_SERV, "Failure getting service information (/etc/services)" +ec RKINIT_SOCKET, "Failure setting up socket" +ec RKINIT_CONNECT, "Failure connecting" +ec RKINIT_PACKET, "Bad packet type" +ec RKINIT_WRITE, "Failure writing" +ec RKINIT_READ, "Failure reading" +ec RKINIT_DAEMON, "Error reported by rkinitd" +ec RKINIT_KERBEROS, "Kerberos error" +ec RKINIT_DES, "Des error" +ec RKINIT_GETPEER, "Failure in getpeername" +ec RKINIT_GETSOCK, "Failure in getsockname" +ec RKINIT_MEMORY, "Out of memory" +ec RKINIT_TIMEOUT, "Timed out" +ec RKINIT_DROPPED, "Connection dropped" + +ec RKINIT_LAST, "Last error message" +end |