diff options
| -rw-r--r-- | Makefile.am | 15 | ||||
| -rwxr-xr-x | autogen | 8 | ||||
| -rw-r--r-- | configure.ac | 36 | ||||
| -rw-r--r-- | kasetkey/README | 15 | ||||
| -rw-r--r-- | kasetkey/kasetkey.c | 332 | 
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 @@ -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); +} + | 
