summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.am15
-rwxr-xr-xautogen8
-rw-r--r--configure.ac36
-rw-r--r--kasetkey/README15
-rw-r--r--kasetkey/kasetkey.c332
5 files changed, 406 insertions, 0 deletions
diff --git a/Makefile.am b/Makefile.am
new file mode 100644
index 0000000..6f82c4e
--- /dev/null
+++ b/Makefile.am
@@ -0,0 +1,15 @@
+# Makefile.am -- Top-level Automake makefile for wallet.
+# $Id$
+#
+# Written by Russ Allbery <rra@stanford.edu>
+# Copyright 2006 Board of Trustees, Leland Stanford Jr. University
+# See README for licensing terms.
+
+AUTOMAKE_OPTIONS = foreign subdir-objects
+EXTRA_DIST = doc/design-acl doc/design-api doc/design-schema doc/notes
+
+bin_PROGRAMS = kasetkey/kasetkey
+kasetkey_kasetkey_CPPFLAGS = @AFS_CPPFLAGS@
+kasetkey_kasetkey_LDFLAGS = @AFS_LDFLAGS@
+kasetkey_kasetkey_LDADD = -lkauth.krb -lprot -lubik -lauth -lrxkad -ldes \
+ -lrx -llwp -lcom_err -lafsutil -lsys
diff --git a/autogen b/autogen
new file mode 100755
index 0000000..366b452
--- /dev/null
+++ b/autogen
@@ -0,0 +1,8 @@
+#!/bin/sh
+# $Id$
+#
+# Run this shell script to bootstrap as necessary after a fresh checkout
+# from Subversion.
+
+autoreconf
+rm -rf autom4te.cache
diff --git a/configure.ac b/configure.ac
new file mode 100644
index 0000000..05f0298
--- /dev/null
+++ b/configure.ac
@@ -0,0 +1,36 @@
+dnl Process this file with Autoconf to produce a configure script.
+dnl $Id$
+dnl
+dnl Written by Russ Allbery <rra@stanford.edu>
+dnl Copyright 2006 Board of Trustees, Leland Stanford Jr. University
+dnl
+dnl See README for licensing terms.
+
+AC_REVISION($Revision$)
+AC_PREREQ(2.57)
+AC_INIT([wallet], [1.0], [rra@stanford.edu])
+AC_CONFIG_AUX_DIR([tools])
+AM_INIT_AUTOMAKE
+AM_MAINTAINER_MODE
+
+AFS_CPPFLAGS=
+AFS_LDFLAGS=
+AC_ARG_WITH([afs],
+ AC_HELP_STRING([--with-afs=DIR],
+ [Prefix for AFS headers and libraries (for kasetkey)]),
+ [if test x"$withval" != xno ; then
+ AFS_CPPFLAGS="-I${withval}/include"
+ AFS_LDFLAGS="-L${withval}/lib"
+ fi])
+AC_SUBST([AFS_CPPFLAGS])
+AC_SUBST([AFS_LDFLAGS])
+
+AC_PROG_CC
+AC_PROG_INSTALL
+AC_SEARCH_LIBS([gethostbyname], [nsl])
+AC_SEARCH_LIBS([socket], [socket], ,
+ [AC_CHECK_LIB([nsl], [socket],
+ [LIBS="-lnsl -lsocket $LIBS"], , [-lsocket])])
+
+AC_CONFIG_HEADER([config.h])
+AC_OUTPUT([Makefile])
diff --git a/kasetkey/README b/kasetkey/README
new file mode 100644
index 0000000..033caff
--- /dev/null
+++ b/kasetkey/README
@@ -0,0 +1,15 @@
+$Id$
+
+This program used to be called gen_srvtab and was the backend used by the
+old sysctl-based srvtab distribution system. It can either load a key
+from a srvtab and push it into the AFS kaserver or generate a random key,
+push it into the AFS kaserver, and then write it out as a srvtab. It has
+a lot of strange issues (such as deleting and then recreating keys rather
+than changing the key and incrementing the kvno), but it works.
+
+This program only works with the AFS kaserver and requires the AFS
+libraries to compile.
+
+I haven't yet done the work to make compilation optional based on whether
+one wants to build kaserver support (or worked out how that will be
+configured in general). That's for later.
diff --git a/kasetkey/kasetkey.c b/kasetkey/kasetkey.c
new file mode 100644
index 0000000..8e2e35a
--- /dev/null
+++ b/kasetkey/kasetkey.c
@@ -0,0 +1,332 @@
+/* $Id$
+**
+** Create or change a principal and/or generate a srvtab.
+**
+** Written by Roland Schemers <schemers@stanford.edu>
+** Updated by Russ Allbery <rra@stanford.edu>
+** Updated again by AAU, Anton Ushakov <antonu@stanford.edu>
+** Copyright 1994, 1998-2000, 2006
+** Board of Trustees, Leland Stanford Jr. University
+**
+** Sets the key of a principal in the AFS kaserver given a srvtab. This
+** program is now used for synchronization of K5 and K4 and nothing else.
+** It will no longer be used once K4 is retired.
+*/
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <strerror.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <afs/stds.h>
+#include <afs/kautils.h>
+#include <afs/cellconfig.h>
+
+void crash_and_burn(char *message);
+void errno_crash_and_burn(char *message);
+void usage(void);
+void do_init_key_file(void);
+void do_service(void);
+
+#ifndef SNAME_SZ
+# define SNAME_SZ 40
+# define INST_SZ 40
+# define REALM_SZ 40
+#endif
+
+#define VERSION "2.0"
+
+char *prog; /* duh */
+char *local_cell; /* duh^2 */
+int o_debug=0; /* turn on debugging */
+int o_init=0; /* intialize keyfile */
+int o_random=0; /* use random DES key */
+
+char *o_keyfile = NULL; /* name of DES key file to use */
+char *o_admin = NULL; /* name of ADMIN user to use */
+char *o_pass = NULL; /* password to use (else random or prompted) */
+char *o_srvtab = NULL; /* srvtab file to generate */
+char *o_service = NULL; /* service to create */
+char *o_k5srvtab = NULL; /* converted keytab from K5*/
+
+int
+main(int argc, char *argv[])
+{
+ long code;
+ int c;
+
+ /* initialize, get our local cell, etc */
+ prog = argv[0];
+ code = ka_Init(0);
+ local_cell = ka_LocalCell();
+ if (o_debug) fprintf(stdout,"cell: %s\n", local_cell);
+
+ if (!local_cell || code) crash_and_burn("can't initialize");
+
+ /* for production, remove the -d debugging option*/
+ while ((c = getopt(argc, argv, "a:hk:is:p:f:rdvc:")) != EOF) {
+ switch(c) {
+ case 'k': o_keyfile = optarg; break;
+ case 'i': o_init = 1; break;
+ case 'a': o_admin = optarg; break;
+ case 'r': o_random = 1; break;
+ case 'p': o_pass = optarg; break;
+ case 'f': o_srvtab = optarg; break;
+ case 's': o_service = optarg; break;
+ case 'd': o_debug = 1; break;
+ case 'c': o_k5srvtab = optarg; break;
+ case 'v': fprintf(stderr,"%s: version %s\n",prog,VERSION); exit(0);
+ case 'h':
+ default: usage(); /* usage doesn't return */
+ }
+ }
+
+ if (o_random && o_k5srvtab)
+ usage();
+
+ if (o_init) do_init_key_file();
+ else if (o_service) do_service();
+ else usage();
+
+ return 0;
+}
+
+void
+do_init_key_file(void)
+{
+ struct ktc_encryptionKey key;
+ char name[MAXKTCNAMELEN];
+ char inst[MAXKTCNAMELEN];
+ char cell[MAXKTCNAMELEN];
+ long code;
+ int kfd;
+
+ if (!o_keyfile) usage();
+
+ if (!o_admin) o_admin = (char*)getlogin();
+
+ code = ka_ParseLoginName(o_admin, name, inst, cell);
+ if (o_debug) printf("ka_ParseLoginName %ld\n",code);
+ if (code) crash_and_burn("can't parse admin name");
+ if (cell[0]=='\0') strcpy(cell, local_cell);
+
+ if (o_pass) {
+ ka_StringToKey(o_pass, cell, &key);
+ memset(o_pass, 0, strlen(o_pass));
+ } else {
+ char buffer[MAXKTCNAMELEN*3+40];
+ sprintf(buffer,"password for %s: ",o_admin);
+ code = ka_ReadPassword(buffer, 1, cell, &key);
+ if (code) crash_and_burn("can't read password");
+ }
+
+ unlink(o_keyfile); /* remove it if it exists */
+ kfd = open(o_keyfile, O_WRONLY | O_CREAT, 0600);
+ if (kfd == -1) errno_crash_and_burn("can't open keyfile");
+
+ if (write(kfd, &key, sizeof(key)) != sizeof(key)) {
+ errno_crash_and_burn("write keyfile");
+ }
+ if (close(kfd)!=0) errno_crash_and_burn("close keyfile");
+
+ exit(0);
+}
+
+void
+do_service(void)
+{
+ struct ktc_encryptionKey key;
+ struct ktc_token token;
+ struct ubik_client *conn;
+ long code;
+ char name[MAXKTCNAMELEN];
+ char inst[MAXKTCNAMELEN];
+ char cell[MAXKTCNAMELEN];
+
+ /*AAU:*/
+ char sbuf[SNAME_SZ * 4]; /* to read in the whole converted srvtab */
+ char* sbuf_ptr = sbuf; /* "reading" pointer for parsing the srvtab*/
+ char sname[SNAME_SZ]; /* name of service from converted srvtab*/
+ char sinst[INST_SZ]; /* instance of service from converted srvtab*/
+ char srealm[REALM_SZ]; /* realm of service from converted srvtab*/
+ unsigned char kvno; /* key version number from converted srvtab*/
+
+ if (!o_admin) o_admin = (char*)getlogin();
+
+ code = ka_ParseLoginName(o_admin, name, inst, cell);
+ if (o_debug) printf("ka_ParseLoginName %ld\n",code);
+ if (code) crash_and_burn("can't parse admin name");
+ if (cell[0]=='\0') strcpy(cell, local_cell);
+
+ if (o_keyfile) {
+ int kfd;
+ kfd = open(o_keyfile, O_RDONLY, 0);
+ if (kfd == -1) errno_crash_and_burn("can't open keyfile");
+ if (read(kfd, &key, sizeof(key)) != sizeof(key)) {
+ errno_crash_and_burn("can't read keyfile");
+ }
+ close(kfd);
+ } else {
+ char buffer[MAXKTCNAMELEN*3+40];
+ sprintf(buffer,"password for %s: ",o_admin);
+ code = ka_ReadPassword(buffer, 0, cell, &key);
+ if (code) crash_and_burn("can't read password");
+ }
+
+ code = ka_GetAdminToken(name, inst, cell, &key, 300, &token, 1);
+ memset((char*)&key, 0, sizeof(key));
+ if (o_debug) printf("ka_GetAdminToken %ld\n",code);
+ if (code) crash_and_burn("can't get admin token");
+
+ /* make connection to AuthServer */
+ code = ka_AuthServerConn(cell, KA_MAINTENANCE_SERVICE, &token, &conn);
+ if (o_debug) printf("ka_AuthServerConn %ld\n",code);
+ if (code) crash_and_burn("can't make connection to auth server");
+
+ /* do a similar dance on the service principal and key */
+
+ code = ka_ParseLoginName(o_service, name, inst, cell);
+ if (o_debug) printf("ka_ParseLoginName %ld\n",code);
+ if (code) crash_and_burn("can't parse service name");
+ if (cell[0]=='\0') strcpy(cell, local_cell);
+
+ /*read service principal key from a srvtab, converted from a K5 keytab. AAU*/
+ if (o_k5srvtab) {
+ FILE* ksfd;
+ ksfd = fopen(o_k5srvtab, "r");
+ if (!ksfd) errno_crash_and_burn("can't open converted srvtab");
+
+ /*must read whole string first: srvtab fields are separated by NULLs, all in one line*/
+ if (!(fgets(sbuf, sizeof(sbuf), ksfd)))
+ errno_crash_and_burn("can't read converted srvtab");
+ strncpy(sname, sbuf_ptr, SNAME_SZ -1);
+ sbuf_ptr = &sbuf_ptr[strlen(sbuf_ptr)+1];
+ strncpy(sinst, sbuf_ptr, INST_SZ -1);
+ sbuf_ptr = &sbuf_ptr[strlen(sbuf_ptr)+1];
+ strncpy(srealm, sbuf_ptr, REALM_SZ -1);
+ sbuf_ptr = &sbuf_ptr[strlen(sbuf_ptr)+1];
+ strncpy(&kvno, sbuf_ptr, sizeof(unsigned char));
+ strncpy(key.data, sbuf_ptr+sizeof(unsigned char), sizeof(key));
+
+ fclose(ksfd);
+ } else if (o_random) { /* get random key */
+ code = ubik_Call (KAM_GetRandomKey, conn, 0, &key);
+ if (o_debug) printf("ka_AuthServerConn %ld\n",code);
+ if (code) crash_and_burn("can't get random key");
+ } else {
+ code = ka_ReadPassword("service password: ", 1, cell, &key);
+ if (code) crash_and_burn("can't read password");
+ }
+
+ /* try to create principal */
+ code = ubik_Call (KAM_CreateUser, conn, 0, name, inst, key);
+ if (o_debug) printf("ubik_Call KAM_CreateUser %ld\n",code);
+
+ if (code == KAEXIST) { /* need to delete first */
+ code = ubik_Call (KAM_DeleteUser, conn, 0, name, inst);
+ if (o_debug) printf("ubik_Call KAM_DeleteUser %ld\n",code);
+ if (code) crash_and_burn("can't delete existing instance");
+ code = ubik_Call (KAM_CreateUser, conn, 0, name, inst, key);
+ if (o_debug) printf("ubik_Call KAM_CreateUser %ld\n",code);
+ if (code) crash_and_burn("can't create user");
+ } else if (code) {
+ crash_and_burn("can't create user");
+ }
+
+ code = ubik_ClientDestroy (conn);
+
+ /* create srvtab file */
+ if (o_srvtab && !o_k5srvtab) {
+ char realm[MAXKTCREALMLEN];
+ int local;
+ unsigned char kvno=0;
+ int sfd;
+ int nlen, ilen, rlen;
+
+ if (ka_CellToRealm(cell, realm, &local) == KANOCELL) {
+ crash_and_burn("unable to determine realm");
+ }
+ if (access(o_srvtab,F_OK)==0) {
+ char backup[MAXPATHLEN];
+ sprintf(backup,"%s.bak", o_srvtab);
+ if (rename(o_srvtab, backup)!=0) {
+ errno_crash_and_burn("can't create backup srvtab");
+ }
+ }
+
+ sfd = open(o_srvtab, O_WRONLY | O_CREAT, 0600);
+ if (sfd == -1) errno_crash_and_burn("can't open srvtab");
+
+ nlen = strlen(name)+1;
+ ilen = strlen(inst)+1;
+ rlen = strlen(realm)+1;
+
+ if (write(sfd, name, nlen) != nlen) {
+ errno_crash_and_burn("write srvtab name");
+ }
+ if (write(sfd, inst, ilen) != ilen) {
+ errno_crash_and_burn("write srvtab instance");
+ }
+ if (write(sfd, realm, rlen) != rlen) {
+ errno_crash_and_burn("write srvtab realm");
+ }
+ if (write(sfd, &kvno, sizeof(kvno)) != sizeof(kvno)) {
+ errno_crash_and_burn("write srvtab kvno");
+ }
+ if (write(sfd, &key, sizeof(key)) != sizeof(key)) {
+ errno_crash_and_burn("write srvtab key");
+ }
+ if (close(sfd)!=0) errno_crash_and_burn("close srvtab");
+ }
+ memset((char*)&key, 0, sizeof(key));
+ memset((char*)&sbuf, 0, sizeof(sbuf));
+ exit(0);
+}
+
+void
+crash_and_burn(char *message)
+{
+ fprintf(stderr,"%s: %s\n", prog, message);
+ exit(1);
+}
+
+
+void
+errno_crash_and_burn(char *message)
+{
+ fprintf(stderr,"%s: %s: %s\n", prog, message, strerror(errno));
+ exit(1);
+}
+
+void
+usage()
+{
+ fprintf(stderr,"usage: %s [options]\n",prog);
+ fprintf(stderr," -k keyfile file containing admin's DES key\n");
+ fprintf(stderr," -i initialize DES key file\n");
+ fprintf(stderr," -a adminuser admin user\n");
+ fprintf(stderr," -r use random key\n");
+ fprintf(stderr," -p password use given password to create key\n");
+ fprintf(stderr," -c input_srvtab use the key from the given srvtab (for sync w/ K5)\n");
+ fprintf(stderr," -f srvtabfile name of srvtab file to create\n");
+ fprintf(stderr," -s service name of service to create\n");
+ fprintf(stderr," -h this help\n");
+ fprintf(stderr," -d turn on debugging\n");
+ fprintf(stderr," -v version\n");
+ fprintf(stderr,"\n");
+ fprintf(stderr," To create a srvtab for rcmd.slapshot and be prompted \n");
+ fprintf(stderr," for the admin (i.e, your) password:\n");
+ fprintf(stderr,"\n");
+ fprintf(stderr," %s -f srvtab.rcmd.slapshot -s rcmd.slapshot -r\n",prog);
+ fprintf(stderr,"\n");
+ fprintf(stderr," To create a srvtab from within a script you must stash the DES key\n");
+ fprintf(stderr," someplace then do something like:\n");
+ fprintf(stderr,"\n");
+ fprintf(stderr," %s -k /.adminkey -a admin -r -f srvtab -s rcmd.slapshot\n",prog);
+ fprintf(stderr,"\n");
+ exit(1);
+}
+