diff options
author | markm <markm@FreeBSD.org> | 1997-09-04 06:04:33 +0000 |
---|---|---|
committer | markm <markm@FreeBSD.org> | 1997-09-04 06:04:33 +0000 |
commit | a8a89cfaf983bc64f4b42f7c35209a5a36dd0fe8 (patch) | |
tree | 0b84977f19022a965f8c6145f067f951173f6290 /crypto/kerberosIV/slave | |
download | FreeBSD-src-a8a89cfaf983bc64f4b42f7c35209a5a36dd0fe8.zip FreeBSD-src-a8a89cfaf983bc64f4b42f7c35209a5a36dd0fe8.tar.gz |
Initial import of KTH eBones. This has been cleaned up to only include
the "core" Kerberos functionality. The rest of the userland will get their
own changes later.
Diffstat (limited to 'crypto/kerberosIV/slave')
-rw-r--r-- | crypto/kerberosIV/slave/Makefile.in | 82 | ||||
-rw-r--r-- | crypto/kerberosIV/slave/kprop.c | 530 | ||||
-rw-r--r-- | crypto/kerberosIV/slave/kprop.h | 19 | ||||
-rw-r--r-- | crypto/kerberosIV/slave/kpropd.c | 301 | ||||
-rw-r--r-- | crypto/kerberosIV/slave/slav_locl.h | 101 |
5 files changed, 1033 insertions, 0 deletions
diff --git a/crypto/kerberosIV/slave/Makefile.in b/crypto/kerberosIV/slave/Makefile.in new file mode 100644 index 0000000..ce35546 --- /dev/null +++ b/crypto/kerberosIV/slave/Makefile.in @@ -0,0 +1,82 @@ +# $Id: Makefile.in,v 1.27 1997/05/04 04:16:28 assar Exp $ + +SHELL = /bin/sh + +srcdir = @srcdir@ +VPATH = @srcdir@ + +CC = @CC@ +AR = ar +RANLIB = @RANLIB@ +DEFS = @DEFS@ -DSBINDIR=\"$(sbindir)\" +CFLAGS = @CFLAGS@ +LD_FLAGS = @LD_FLAGS@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +LIBS = @LIBS@ +MKINSTALLDIRS = @top_srcdir@/mkinstalldirs + +prefix = @prefix@ +exec_prefix = @exec_prefix@ +libdir = @libdir@ +libexecdir = @libexecdir@ +sbindir = @sbindir@ +transform=@program_transform_name@ +EXECSUFFIX=@EXECSUFFIX@ + +PROGS = kpropd$(EXECSUFFIX) \ + kprop$(EXECSUFFIX) + +SOURCES = kpropd.c kprop.c + +OBJECTS = kpropd.o kprop.o + +all: $(PROGS) + +Wall: + make CFLAGS="-g -Wall -Wno-comment -Wmissing-prototypes -Wmissing-declarations -D__USE_FIXED_PROTOTYPES__" + +.c.o: + $(CC) -c $(CPPFLAGS) $(DEFS) -I../include -I$(srcdir) $(CFLAGS) $< + +install: all + $(MKINSTALLDIRS) $(libexecdir) + for x in $(PROGS); do \ + $(INSTALL_PROGRAM) $$x $(libexecdir)/`echo $$x | sed '$(transform)'`; \ + done + +uninstall: + for x in $(PROGS); do \ + rm -f $(libexecdir)/`echo $$x | sed '$(transform)'`; \ + done + +TAGS: $(SOURCES) + etags $(SOURCES) + +check: + +clean: + rm -f *.a *.o $(PROGS) + +mostlyclean: clean + +distclean: clean + rm -f Makefile *.tab.c *~ + +realclean: distclean + rm -f TAGS + +dist: $(DISTFILES) + for file in $(DISTFILES); do \ + ln $$file ../`cat ../.fname`/lib \ + || cp -p $$file ../`cat ../.fname`/lib; \ + done + +kprop$(EXECSUFFIX): kprop.o + $(CC) $(LD_FLAGS) $(LDFLAGS) -o $@ kprop.o -L../lib/krb -lkrb -L../lib/des -ldes -L../lib/roken -lroken $(LIBS) -lroken + +kpropd$(EXECSUFFIX): kpropd.o + $(CC) $(LD_FLAGS) $(LDFLAGS) -o $@ kpropd.o -L../lib/krb -lkrb -L../lib/des -ldes -L../lib/roken -lroken $(LIBS) -lroken + +$(OBJECTS): ../include/config.h diff --git a/crypto/kerberosIV/slave/kprop.c b/crypto/kerberosIV/slave/kprop.c new file mode 100644 index 0000000..8901121 --- /dev/null +++ b/crypto/kerberosIV/slave/kprop.c @@ -0,0 +1,530 @@ +/* + +Copyright 1987, 1988 by the Student Information Processing Board + of the Massachusetts Institute of Technology + +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 names of M.I.T. and the M.I.T. S.I.P.B. not be +used in advertising or publicity pertaining to distribution +of the software without specific, written prior permission. +M.I.T. and the M.I.T. S.I.P.B. make no representations about +the suitability of this software for any purpose. It is +provided "as is" without express or implied warranty. + +*/ + +#include "slav_locl.h" + +RCSID("$Id: kprop.c,v 1.29 1997/05/25 02:43:54 joda Exp $"); + +#include "kprop.h" + +static char kprop_version[KPROP_PROT_VERSION_LEN] = KPROP_PROT_VERSION; + +int debug = 0; + +char my_realm[REALM_SZ]; +int princ_data_size = 3 * sizeof(int32_t) + 3 * sizeof(unsigned char); +short transfer_mode, net_transfer_mode; +int force_flag; +static char ok[] = ".dump_ok"; + +struct slave_host { + u_int32_t net_addr; + char *name; + char *instance; + char *realm; + int not_time_yet; + int succeeded; + struct slave_host *next; +}; + +static +int get_slaves(struct slave_host **psl, char *file, time_t ok_mtime) +{ + FILE *fin; + char namebuf[128], *inst; + char *pc; + struct hostent *host; + struct slave_host **th; + char path[256]; + char *ppath; + struct stat stbuf; + + if ((fin = fopen(file, "r")) == NULL) + err (1, "open(%s)", file); + strcpy(path, file); + if ((ppath = strrchr(path, '/'))) { + ppath += 1; + } else { + ppath = path; + } + th = psl; + while(fgets(namebuf, sizeof(namebuf), fin)){ + if ((pc = strchr(namebuf, '\n'))) { + *pc = '\0'; + } else { + if(strlen(namebuf) == sizeof(namebuf) - 1){ + warnx ("Hostname too long (>= %d chars) in '%s'.", + (int) sizeof(namebuf), file); + do{ + if(fgets(namebuf, sizeof(namebuf), fin) == NULL) + break; + }while(strchr(namebuf, '\n') == NULL); + continue; + } + } + if(namebuf[0] == 0 || namebuf[0] == '#') + continue; + host = gethostbyname(namebuf); + if (host == NULL) { + warnx ("Ignoring host '%s' in '%s': %s", + namebuf, file, +#ifdef HAVE_H_ERRNO + hstrerror(h_errno) +#else + "unknown error" +#endif + ); + continue; + } + (*th) = (struct slave_host *) malloc(sizeof(struct slave_host)); + if (!*th) + errx (1, "No memory reading host list from '%s'.", + file); + memset(*th, 0, sizeof(struct slave_host)); + (*th)->name = strdup(namebuf); + if ((*th)->name == NULL) + errx (1, "No memory reading host list from '%s'.", + file); + /* get kerberos cannonical instance name */ + inst = krb_get_phost ((*th)->name); + (*th)->instance = strdup(inst); + if ((*th)->instance == NULL) + errx (1, "No memory reading host list from '%s'.", + file); + /* what a concept, slave servers in different realms! */ + (*th)->realm = my_realm; + memcpy(&(*th)->net_addr, host->h_addr, sizeof((*th)->net_addr)); + (*th)->not_time_yet = 0; + (*th)->succeeded = 0; + (*th)->next = NULL; + strcat(strcpy(ppath, (*th)->name), "-last-prop"); + if (!force_flag && !stat(path, &stbuf) && stbuf.st_mtime > ok_mtime) { + (*th)->not_time_yet = 1; + (*th)->succeeded = 1; /* no change since last success */ + } + th = &(*th)->next; + } + fclose(fin); + return (1); +} + +/* The master -> slave protocol looks like this: + 1) 8 byte version string + 2) 2 bytes of "transfer mode" (net byte order of course) + 3) ticket/authentication send by sendauth + 4) 4 bytes of "block" length (u_int32_t) + 5) data + + 4 and 5 repeat til EOF ... +*/ + +static int +prop_to_slaves(struct slave_host *sl, int fd, char *fslv) +{ + u_char buf[KPROP_BUFSIZ]; + u_char obuf[KPROP_BUFSIZ + 64]; /* leave room for private msg overhead */ + struct sockaddr_in sin, my_sin; + int i, n, s; + struct slave_host *cs; /* current slave */ + char path[256], my_host_name[MaxHostNameLen], *p_my_host_name; + char kprop_service_instance[INST_SZ]; + char *pc; + u_int32_t cksum; + u_int32_t length, nlength; + long kerror; + KTEXT_ST ticket; + CREDENTIALS cred; + MSG_DAT msg_dat; + static char tkstring[] = "/tmp/kproptktXXXXXX"; + + des_key_schedule session_sched; + + close(mkstemp(tkstring)); + krb_set_tkt_string(tkstring); + + memset(&sin, 0, sizeof sin); + sin.sin_family = AF_INET; + sin.sin_port = k_getportbyname ("krb_prop", "tcp", htons(KPROP_PORT)); + sin.sin_addr.s_addr = INADDR_ANY; + + strcpy(path, fslv); + if ((pc = strrchr(path, '/'))) { + pc += 1; + } else { + pc = path; + } + + for (i = 0; i < 5; i++) { /* try each slave five times max */ + for (cs = sl; cs; cs = cs->next) { + if (!cs->succeeded) { + if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) + err (1, "socket"); + memcpy(&sin.sin_addr, &cs->net_addr, + sizeof cs->net_addr); + + if (connect(s, (struct sockaddr *) &sin, sizeof sin) < 0) { + warn ("connect(%s)", cs->name); + close(s); + continue; /*** NEXT SLAVE ***/ + } + + /* for krb_mk_{priv, safe} */ + memset(&my_sin, 0, sizeof my_sin); + n = sizeof my_sin; + if (getsockname (s, (struct sockaddr *) &my_sin, &n) != 0) { + warn ("getsockname(%s)", cs->name); + close (s); + continue; /*** NEXT SLAVE ***/ + } + if (n != sizeof (my_sin)) { + warnx ("can't get socketname %s length", cs->name); + close (s); + continue; /*** NEXT SLAVE ***/ + } + + /* Get ticket */ + kerror = krb_mk_req (&ticket, KPROP_SERVICE_NAME, + cs->instance, cs->realm, (u_int32_t) 0); + /* if ticket has expired try to get a new one, but + * first get a TGT ... + */ + if (kerror != MK_AP_OK) { + if (k_gethostname (my_host_name, sizeof(my_host_name)) != 0) { + warnx ("gethostname(%s): %s", + my_host_name, +#ifdef HAVE_H_ERRNO + hstrerror(h_errno) +#else + "unknown error" +#endif + ); + close (s); + break; /* next one can't work either! */ + } + /* get canonical kerberos service instance name */ + p_my_host_name = krb_get_phost (my_host_name); + /* copy it to make sure gethostbyname static doesn't + * screw us. */ + strcpy (kprop_service_instance, p_my_host_name); + kerror = krb_get_svc_in_tkt (KPROP_SERVICE_NAME, +#if 0 + kprop_service_instance, +#else + KRB_MASTER, +#endif + my_realm, + KRB_TICKET_GRANTING_TICKET, + my_realm, + 96, + KPROP_SRVTAB); + if (kerror != INTK_OK) { + warnx ("%s: %s. While getting initial ticket\n", + cs->name, krb_get_err_text(kerror)); + close (s); + goto punt; + } + kerror = krb_mk_req (&ticket, KPROP_SERVICE_NAME, + cs->instance, cs->realm, (u_int32_t) 0); + } + if (kerror != MK_AP_OK) { + warnx ("%s: krb_mk_req: %s", + cs->name, krb_get_err_text(kerror)); + close (s); + continue; /*** NEXT SLAVE ***/ + } + + if (write(s, kprop_version, sizeof(kprop_version)) + != sizeof(kprop_version)) { + warn ("%s", cs->name); + close (s); + continue; /*** NEXT SLAVE ***/ + } + + net_transfer_mode = htons (transfer_mode); + if (write(s, &net_transfer_mode, sizeof(net_transfer_mode)) + != sizeof(net_transfer_mode)) { + warn ("write(%s)", cs->name); + close (s); + continue; /*** NEXT SLAVE ***/ + } + + kerror = krb_get_cred (KPROP_SERVICE_NAME, cs->instance, + cs->realm, &cred); + if (kerror != KSUCCESS) { + warnx ("%s: %s. Getting session key.", + cs->name, krb_get_err_text(kerror)); + close (s); + continue; /*** NEXT SLAVE ***/ + } +#ifdef NOENCRYPTION + memset(session_sched, 0, sizeof(session_sched)); +#else + if (des_key_sched (&cred.session, session_sched)) { + warnx ("%s: can't make key schedule.", + cs->name); + close (s); + continue; /*** NEXT SLAVE ***/ + } +#endif + /* SAFE (quad_cksum) and CLEAR are just not good enough */ + cksum = 0; +#ifdef not_working_yet + if (transfer_mode != KPROP_TRANSFER_PRIVATE) { + cksum = get_data_checksum(fd, session_sched); + lseek(fd, 0L, 0); + } + else +#endif + { + struct stat st; + fstat (fd, &st); + cksum = st.st_size; + } + kerror = krb_sendauth(KOPT_DO_MUTUAL, + s, + &ticket, + KPROP_SERVICE_NAME, + cs->instance, + cs->realm, + cksum, + &msg_dat, + &cred, + session_sched, + &my_sin, + &sin, + KPROP_PROT_VERSION); + if (kerror != KSUCCESS) { + warnx ("%s: krb_sendauth: %s.", + cs->name, krb_get_err_text(kerror)); + close (s); + continue; /*** NEXT SLAVE ***/ + } + + lseek(fd, 0L, SEEK_SET); /* Rewind file before rereading it. */ + while ((n = read(fd, buf, sizeof buf))) { + if (n < 0) + err (1, "read"); + switch (transfer_mode) { + case KPROP_TRANSFER_PRIVATE: + case KPROP_TRANSFER_SAFE: + if (transfer_mode == KPROP_TRANSFER_PRIVATE) + length = krb_mk_priv (buf, obuf, n, + session_sched, &cred.session, + &my_sin, &sin); + else + length = krb_mk_safe (buf, obuf, n, + &cred.session, + &my_sin, &sin); + if (length == -1) { + warnx ("%s: %s failed.", + cs->name, + (transfer_mode == KPROP_TRANSFER_PRIVATE) + ? "krb_rd_priv" : "krb_rd_safe"); + close (s); + continue; /*** NEXT SLAVE ***/ + } + nlength = htonl(length); + if (write(s, &nlength, sizeof nlength) + != sizeof nlength) { + warn ("write(%s)", cs->name); + close (s); + continue; /*** NEXT SLAVE ***/ + } + if (write(s, obuf, length) != length) { + warn ("write(%s)", cs->name); + close(s); + continue; /*** NEXT SLAVE ***/ + } + break; + case KPROP_TRANSFER_CLEAR: + if (write(s, buf, n) != n) { + warn ("write(%s)", cs->name); + close(s); + continue; /*** NEXT SLAVE ***/ + } + break; + } + } + close(s); + cs->succeeded = 1; + fprintf(stderr, "%s: success.\n", cs->name); + strcat(strcpy(pc, cs->name), "-last-prop"); + unlink(path); + close(creat(path, 0600)); + } + } + } +punt: + + dest_tkt(); + for (cs = sl; cs; cs = cs->next) { + if (!cs->succeeded) + return (0); /* didn't get this slave */ + } + return (1); +} + +static void +usage() +{ + /* already got floc and fslv, what is this? */ + fprintf(stderr, + "\nUsage: kprop [-force] [-realm realm] [-private" +#ifdef not_safe_yet + "|-safe|-clear" +#endif + "] [data_file [slaves_file]]\n\n"); + exit(1); +} + + +int +main(int argc, char **argv) +{ + int fd, i; + char *floc, *floc_ok; + char *fslv; + struct stat stbuf, stbuf_ok; + time_t l_init, l_final; + char *pc; + int l_diff; + static struct slave_host *slave_host_list = NULL; + struct slave_host *sh; + + set_progname (argv[0]); + + transfer_mode = KPROP_TRANSFER_PRIVATE; + + time(&l_init); + pc = ctime(&l_init); + pc[strlen(pc) - 1] = '\0'; + printf("\nStart slave propagation: %s\n", pc); + + floc = NULL; + fslv = NULL; + + if (krb_get_lrealm(my_realm,1) != KSUCCESS) + errx (1, "Getting my kerberos realm. Check krb.conf"); + + for (i = 1; i < argc; i++) + switch (argv[i][0]) { + case '-': + if (strcmp (argv[i], "-private") == 0) + transfer_mode = KPROP_TRANSFER_PRIVATE; +#ifdef not_safe_yet + else if (strcmp (argv[i], "-safe") == 0) + transfer_mode = KPROP_TRANSFER_SAFE; + else if (strcmp (argv[i], "-clear") == 0) + transfer_mode = KPROP_TRANSFER_CLEAR; +#endif + else if (strcmp (argv[i], "-realm") == 0) { + i++; + if (i < argc) + strcpy(my_realm, argv[i]); + else + usage(); + } else if (strcmp (argv[i], "-force") == 0) + force_flag++; + else { + warnx("unknown control argument %s.", argv[i]); + usage (); + } + break; + default: + /* positional arguments are marginal at best ... */ + if (floc == NULL) + floc = argv[i]; + else { + if (fslv == NULL) + fslv = argv[i]; + else + usage(); + } + } + if(floc == NULL) + floc = DB_DIR "/slave_dump"; + if(fslv == NULL) + fslv = DB_DIR "/slaves"; + + asprintf (&floc_ok, "%s%s", floc, ok); + if (floc_ok == NULL) + errx (1, "out of memory in copying %s", floc); + + if ((fd = open(floc, O_RDONLY)) < 0) + err (1, "open(%s)", floc); + if (k_flock(fd, K_LOCK_SH | K_LOCK_NB)) + err (1, "flock(%s)", floc); + if (stat(floc, &stbuf)) + err (1, "stat(%s)", floc); + if (stat(floc_ok, &stbuf_ok)) + err (1, "stat(%s)", floc_ok); + if (stbuf.st_mtime > stbuf_ok.st_mtime) + errx (1, "'%s' more recent than '%s'.", floc, floc_ok); + if (!get_slaves(&slave_host_list, fslv, stbuf_ok.st_mtime)) + errx (1, "can't read slave host file '%s'.", fslv); +#ifdef KPROP_DBG + { + struct slave_host *sh; + int i; + fprintf(stderr, "\n\n"); + fflush(stderr); + for (sh = slave_host_list; sh; sh = sh->next) { + fprintf(stderr, "slave %d: %s, %s", i++, sh->name, + inet_ntoa(sh->net_addr)); + fflush(stderr); + } + } +#endif /* KPROP_DBG */ + + if (!prop_to_slaves(slave_host_list, fd, fslv)) + errx (1, "propagation failed."); + if (k_flock(fd, K_LOCK_UN)) + err (1, "flock(%s, LOCK_UN)", floc); + fprintf(stderr, "\n\n"); + for (sh = slave_host_list; sh; sh = sh->next) { + fprintf(stderr, "%s:\t\t%s\n", sh->name, + (sh->not_time_yet? "Not time yet" : (sh->succeeded ? "Succeeded" : "FAILED"))); + } + + time(&l_final); + l_diff = l_final - l_init; + printf("propagation finished, %d:%02d:%02d elapsed\n", + l_diff / 3600, (l_diff % 3600) / 60, l_diff % 60); + + exit(0); +} + +#ifdef doesnt_work_yet +u_long get_data_checksum(fd, key_sched) + int fd; + des_key_schedule key_sched; +{ + u_int32_t cksum = 0; + int n; + char buf[BUFSIZ]; + u_int32_t obuf[2]; + + while (n = read(fd, buf, sizeof buf)) { + if (n < 0) + err (1, "read"); + cksum = cbc_cksum(buf, obuf, n, key_sched, key_sched); + } + return cksum; +} +#endif diff --git a/crypto/kerberosIV/slave/kprop.h b/crypto/kerberosIV/slave/kprop.h new file mode 100644 index 0000000..d66f63f --- /dev/null +++ b/crypto/kerberosIV/slave/kprop.h @@ -0,0 +1,19 @@ +/* + * Copyright 1987 by the Massachusetts Institute of Technology. + * + * For copying and distribution information, + * please see the file <mit-copyright.h>. + * + * $Id: kprop.h,v 1.5 1997/02/07 21:39:52 assar Exp $ + * + */ + +#define KPROP_SERVICE_NAME "rcmd" +#define KPROP_SRVTAB "/etc/srvtab" +#define KPROP_PROT_VERSION_LEN 8 +#define KPROP_PROT_VERSION "kprop01" +#define KPROP_TRANSFER_PRIVATE 1 +#define KPROP_TRANSFER_SAFE 2 +#define KPROP_TRANSFER_CLEAR 3 +#define KPROP_BUFSIZ 32768 +#define KPROP_PORT 754 diff --git a/crypto/kerberosIV/slave/kpropd.c b/crypto/kerberosIV/slave/kpropd.c new file mode 100644 index 0000000..e2b5f0a --- /dev/null +++ b/crypto/kerberosIV/slave/kpropd.c @@ -0,0 +1,301 @@ +/* + * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the Kungliga Tekniska + * Högskolan and its contributors. + * + * 4. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "slav_locl.h" + +#include "kprop.h" + +RCSID("$Id: kpropd.c,v 2.21 1997/05/02 17:52:13 assar Exp $"); + +#ifndef SBINDIR +#define SBINDIR "/usr/athena/sbin" +#endif + +struct sockaddr_in master, slave; + +char *database = DBM_FILE; + +char *lockfile = DB_DIR "/slave_propagation"; + +char *logfile = K_LOGFIL; + +char *kdb_util = SBINDIR "/kdb_util"; + +char *kdb_util_command = "load"; + +char *srvtab = ""; + +char realm[REALM_SZ]; + +static +int +copy_data(int from, int to, des_cblock *session, des_key_schedule schedule) +{ + unsigned char tmp[4]; + char buf[KPROP_BUFSIZ + 26]; + u_int32_t length; + int n; + + int kerr; + MSG_DAT m; + + while(1){ + n = krb_net_read(from, tmp, 4); + if(n == 0) + break; + if(n < 0){ + klog(L_KRB_PERR, "krb_net_read: %s", strerror(errno)); + return -1; + } + if(n != 4){ + klog(L_KRB_PERR, "Premature end of data"); + return -1; + } + length = (tmp[0] << 24) | (tmp[1] << 16) | (tmp[2] << 8) | tmp[3]; + if(length > sizeof(buf)){ + klog(L_KRB_PERR, "Giant packet received: %d", length); + return -1; + } + if(krb_net_read(from, buf, length) != length){ + klog(L_KRB_PERR, "Premature end of data"); + return -1; + } + kerr = krb_rd_priv (buf, length, schedule, session, &master, &slave, &m); + if(kerr != KSUCCESS){ + klog(L_KRB_PERR, "Kerberos error: %s", krb_get_err_text(kerr)); + return -1; + } + write(to, m.app_data, m.app_length); + } + return 0; +} + + +static +int +kprop(int s) +{ + char buf[128]; + int n; + KTEXT_ST ticket; + AUTH_DAT ad; + char sinst[INST_SZ]; + char command[1024]; + des_key_schedule schedule; + int mode; + int kerr; + int lock; + + n = sizeof(master); + if(getpeername(s, (struct sockaddr*)&master, &n) < 0){ + klog(L_KRB_PERR, "getpeername: %s", strerror(errno)); + return 1; + } + + n = sizeof(slave); + if(getsockname(s, (struct sockaddr*)&slave, &n) < 0){ + klog(L_KRB_PERR, "getsockname: %s", strerror(errno)); + return 1; + } + + klog(L_KRB_PERR, "Connection from %s", inet_ntoa(master.sin_addr)); + + n = krb_net_read(s, buf, KPROP_PROT_VERSION_LEN + 2); + if(n < KPROP_PROT_VERSION_LEN + 2){ + klog(L_KRB_PERR, "Premature end of data"); + return 1; + } + if(memcmp(buf, KPROP_PROT_VERSION, KPROP_PROT_VERSION_LEN) != 0){ + klog(L_KRB_PERR, "Bad protocol version string received"); + return 1; + } + mode = (buf[n-2] << 8) | buf[n-1]; + if(mode != KPROP_TRANSFER_PRIVATE){ + klog(L_KRB_PERR, "Bad transfer mode received: %d", mode); + return 1; + } + k_getsockinst(s, sinst, sizeof(sinst)); + kerr = krb_recvauth(KOPT_DO_MUTUAL, s, &ticket, + KPROP_SERVICE_NAME, sinst, + &master, &slave, + &ad, srvtab, schedule, + buf); + if(kerr != KSUCCESS){ + klog(L_KRB_PERR, "Kerberos error: %s", krb_get_err_text(kerr)); + return 1; + } + des_set_key(&ad.session, schedule); + + lock = open(lockfile, O_WRONLY|O_CREAT, 0600); + if(lock < 0){ + klog(L_KRB_PERR, "Failed to open file: %s", strerror(errno)); + return 1; + } + if(k_flock(lock, K_LOCK_EX | K_LOCK_NB)){ + close(lock); + klog(L_KRB_PERR, "Failed to lock file: %s", strerror(errno)); + return 1; + } + + if(ftruncate(lock, 0) < 0){ + close(lock); + klog(L_KRB_PERR, "Failed to lock file: %s", strerror(errno)); + return 1; + } + + if(copy_data(s, lock, &ad.session, schedule)){ + close(lock); + return 1; + } + close(lock); + snprintf(command, sizeof(command), + "%s %s %s %s", kdb_util, kdb_util_command, + lockfile, database); + if(system(command) == 0){ + klog(L_KRB_PERR, "Propagation finished successfully"); + return 0; + } + klog(L_KRB_PERR, "*** Propagation failed ***"); + return 1; +} + +static int +doit(void) +{ + return kprop(0); +} + +static int +doit_interactive(void) +{ + struct sockaddr_in sa; + int salen; + int s, s2; + int ret; + + s = socket(AF_INET, SOCK_STREAM, 0); + if(s < 0){ + klog(L_KRB_PERR, "socket: %s", strerror(errno)); + return 1; + } + memset(&sa, 0, sizeof(sa)); + sa.sin_family = AF_INET; + sa.sin_port = k_getportbyname ("krb_prop", "tcp", htons(KPROP_PORT)); + ret = bind(s, (struct sockaddr*)&sa, sizeof(sa)); + if (ret < 0) { + klog(L_KRB_PERR, "bind: %s", strerror(errno)); + return 1; + } + ret = listen(s, SOMAXCONN); + if (ret < 0) { + klog(L_KRB_PERR, "listen: %s", strerror(errno)); + return 1; + } + for(;;) { + salen = sizeof(sa); + s2 = accept(s, (struct sockaddr*)&sa, &salen); + switch(fork()){ + case -1: + klog(L_KRB_PERR, "fork: %s", strerror(errno)); + return 1; + case 0: + close(s); + kprop(s2); + return 1; + default: { + int status; + close(s2); + wait(&status); + } + } + } +} + +static void +usage (void) +{ + fprintf (stderr, + "Usage: kpropd [-i] [-d database] [-l log] [-m] [-[p|P] program]" + " [-r realm] [-s srvtab]\n"); + exit (1); +} + +int +main(int argc, char **argv) +{ + int opt; + int interactive = 0; + + krb_get_lrealm(realm, 1); + + while((opt = getopt(argc, argv, ":d:l:mp:P:r:s:i")) >= 0){ + switch(opt){ + case 'd': + database = optarg; + break; + case 'l': + logfile = optarg; + break; + case 'm': + kdb_util_command = "merge"; + break; + case 'p': + case 'P': + kdb_util = optarg; + break; + case 'r': + strcpy(realm, optarg); + break; + case 's': + srvtab = optarg; + break; + case 'i': + interactive = 1; + break; + default: + klog(L_KRB_PERR, "Bad option: -%c", optopt); + usage (); + exit(1); + } + } + kset_logfile(logfile); + if (interactive) + return doit_interactive (); + else + return doit (); +} diff --git a/crypto/kerberosIV/slave/slav_locl.h b/crypto/kerberosIV/slave/slav_locl.h new file mode 100644 index 0000000..760fb9d --- /dev/null +++ b/crypto/kerberosIV/slave/slav_locl.h @@ -0,0 +1,101 @@ +/* + * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the Kungliga Tekniska + * Högskolan and its contributors. + * + * 4. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* $Id: slav_locl.h,v 1.11 1997/05/20 18:40:47 bg Exp $ */ + +#ifndef __slav_locl_h +#define __slav_locl_h + +#include "config.h" +#include "protos.h" + +#include <stdio.h> +#include <stdarg.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> + +#include <errno.h> +#include <unistd.h> + +#ifdef HAVE_SYS_TYPES_H +#include <sys/types.h> +#endif +#ifdef HAVE_SYS_STAT_H +#include <sys/stat.h> +#endif +#ifdef HAVE_FCNTL_H +#include <fcntl.h> +#endif +#include <time.h> +#ifdef HAVE_SYS_FILE_H +#include <sys/file.h> +#endif +#ifdef HAVE_SYS_WAIT_H +#include <sys/wait.h> +#endif + +#ifdef HAVE_NETINET_IN_H +#include <netinet/in.h> +#endif +#ifdef HAVE_ARPA_INET_H +#include <arpa/inet.h> +#endif +#ifdef HAVE_SYS_SOCKET_H +#include <sys/socket.h> +#endif +#ifdef HAVE_NETDB_H +#include <netdb.h> +#endif +#include <err.h> + +#ifdef SOCKS +#include <socks.h> +#endif + +#include <roken.h> + +#include <krb.h> +#include <krb_db.h> +#include <klog.h> +#include <prot.h> +#include <kdc.h> + +#include "kprop.h" + +#endif /* __slav_locl_h */ |