diff options
| -rw-r--r-- | Makefile.am | 4 | ||||
| -rw-r--r-- | NEWS | 4 | ||||
| -rw-r--r-- | TODO | 8 | ||||
| -rw-r--r-- | client/internal.h | 5 | ||||
| -rw-r--r-- | client/krb5.c | 64 | ||||
| -rw-r--r-- | client/wallet.c | 11 | ||||
| -rw-r--r-- | client/wallet.pod | 13 | 
7 files changed, 101 insertions, 8 deletions
| diff --git a/Makefile.am b/Makefile.am index 8cf0e21..cbc9dff 100644 --- a/Makefile.am +++ b/Makefile.am @@ -34,8 +34,8 @@ util_libutil_a_SOURCES = util/concat.c util/messages.c util/util.h \  bin_PROGRAMS = client/wallet  dist_sbin_SCRIPTS = server/keytab-backend server/wallet-backend  client_wallet_SOURCES = client/error.c client/file.c client/internal.h \ -	client/keytab.c client/remctl.c client/srvtab.c client/wallet.c \ -	system.h +	client/keytab.c client/krb5.c client/remctl.c client/srvtab.c \ +	client/wallet.c system.h  client_wallet_CPPFLAGS = $(REMCTL_CPPFLAGS)  client_wallet_LDFLAGS = $(REMCTL_LDFLAGS)  client_wallet_LDADD = util/libutil.a portable/libportable.a $(REMCTL_LIBS) \ @@ -19,6 +19,10 @@ wallet 0.6 (unreleased)      keytab keys into that file rather than moving aside the old keytab and      creating a new keytab with only the new keys. +    The wallet client now supports a -u option, saying to obtain Kerberos +    credentials for the given user and use those for authentication rather +    than using an existing ticket cache. +      Support enforcing a naming policy for wallet objects via a Perl      function in the wallet server configuration file. @@ -35,9 +35,7 @@ Release 1.0:  * Log failures in the wallet-backend properly, which also requires    catching all exceptions. -* Add support to the wallet client for getting Kerberos tickets, using the -  -u option similar to leland_srvtab.  Needs good error messages on -  Kerberos failures. +* Improve the error message for Kerberos authentication failures.  * Error messages from ACL operations should refer to the ACLs by name    instead of by ID. @@ -165,3 +163,7 @@ May or may not be good ideas:  * Remove the hard-coded ADMIN ACL in the server with something more    configurable, perhaps a global ACL table or something. + +* When obtaining tickets in the wallet client with -u, should we get a TGT +  as we do now or just directly obtain the service ticket we're going to +  use for remctl? diff --git a/client/internal.h b/client/internal.h index 8595412..88b0e24 100644 --- a/client/internal.h +++ b/client/internal.h @@ -29,6 +29,11 @@ struct remctl;  BEGIN_DECLS +/* Given a Kerberos context and a principal name, obtain Kerberos credentials +   for that principal and store them in a memory cache for use by later +   operations. */ +void kinit(krb5_context, const char *principal); +  /* Given a remctl object, run a remctl command.  If data is non-NULL, saves     the standard output from the command into data with the length in length.     Otherwise, prints it to standard output.  Either way, prints standard error diff --git a/client/krb5.c b/client/krb5.c new file mode 100644 index 0000000..606cbb9 --- /dev/null +++ b/client/krb5.c @@ -0,0 +1,64 @@ +/*  $Id$ +** +**  Kerberos support functions for the wallet client. +** +**  Currently, the only function here is one to obtain a ticket cache for a +**  given principal and store it in memory for use by the rest of the wallet +**  client. +** +**  Written by Russ Allbery <rra@stanford.edu> +**  Copyright 2007, 2008 Board of Trustees, Leland Stanford Jr. University +*/ + +#include <config.h> +#include <system.h> + +#include <krb5.h> + +#include <client/internal.h> +#include <util/util.h> + +/* The memory cache used for wallet authentication. */ +#define CACHE_NAME "MEMORY:wallet" + + +/* +**  Given a Kerberos context and a principal name, authenticate as that user +**  and store the TGT in a memory ticket cache for later use by remctl.  Dies +**  on failure. +*/ +void +kinit(krb5_context ctx, const char *principal) +{ +    krb5_principal princ; +    krb5_ccache ccache; +    krb5_creds creds; +    krb5_get_init_creds_opt opts; +    krb5_error_code status; + +    /* Obtain a TGT. */ +    status = krb5_parse_name(ctx, principal, &princ); +    if (status != 0) +        die_krb5(ctx, status, "invalid Kerberos principal %s", principal); +    krb5_get_init_creds_opt_init(&opts); +    memset(&creds, 0, sizeof(creds)); +    status = krb5_get_init_creds_password(ctx, &creds, princ, NULL, +                 krb5_prompter_posix, NULL, 0, NULL, &opts); +    if (status != 0) +        die_krb5(ctx, status, "authentication failed"); + +    /* Put the new credentials into a memory cache. */ +    status = krb5_cc_resolve(ctx, CACHE_NAME, &ccache); +    if (status != 0) +        die_krb5(ctx, status, "cannot create cache %s", CACHE_NAME); +    status = krb5_cc_initialize(ctx, ccache, princ); +    if (status != 0) +        die_krb5(ctx, status, "cannot initialize cache %s", CACHE_NAME); +    krb5_free_principal(ctx, princ); +    status = krb5_cc_store_cred(ctx, ccache, &creds); +    if (status != 0) +        die_krb5(ctx, status, "cannot store credentials"); +    krb5_cc_close(ctx, ccache); +    if (putenv((char *) "KRB5CCNAME=" CACHE_NAME) != 0) +        sysdie("cannot set KRB5CCNAME"); +} diff --git a/client/wallet.c b/client/wallet.c index 9dc97c2..8ce7ae0 100644 --- a/client/wallet.c +++ b/client/wallet.c @@ -26,6 +26,7 @@ struct options {      char *type;      char *server;      char *principal; +    char *user;      int port;  }; @@ -114,6 +115,7 @@ set_defaults(krb5_context ctx, struct options *options)      default_string(ctx, "wallet_server", WALLET_SERVER, &options->server);      default_string(ctx, "wallet_principal", NULL, &options->principal);      default_number(ctx, "wallet_port", WALLET_PORT, &options->port); +    options->user = NULL;  } @@ -144,7 +146,7 @@ main(int argc, char *argv[])          die_krb5(ctx, retval, "cannot initialize Kerberos");      set_defaults(ctx, &options); -    while ((option = getopt(argc, argv, "c:f:k:hp:S:s:v")) != EOF) { +    while ((option = getopt(argc, argv, "c:f:k:hp:S:s:u:v")) != EOF) {          switch (option) {          case 'c':              options.type = optarg; @@ -171,6 +173,9 @@ main(int argc, char *argv[])          case 's':              options.server = optarg;              break; +        case 'u': +            options.user = optarg; +            break;          case 'v':              printf("%s\n", PACKAGE_STRING);              exit(0); @@ -200,6 +205,10 @@ main(int argc, char *argv[])      if (options.server == NULL)          die("no server specified in krb5.conf or with -s"); +    /* If a user was specified, obtain Kerberos tickets. */ +    if (options.user != NULL) +        kinit(ctx, options.user); +      /* Open a remctl connection. */      r = remctl_new();      if (r == NULL) diff --git a/client/wallet.pod b/client/wallet.pod index 0a6f395..de20586 100644 --- a/client/wallet.pod +++ b/client/wallet.pod @@ -6,7 +6,7 @@ wallet - Client for retrieving secure data from a central server  B<wallet> [B<-hv>] [B<-c> I<command>] [B<-f> I<output>]  [B<-k> I<principal>] [B<-p> I<port>] [S<B<-s> I<server>>] [B<-S> I<srvtab>] -I<command> [I<arg> ...] +[B<-u> I<principal>] I<command> [I<arg> ...]  =head1 DESCRIPTION @@ -118,6 +118,15 @@ The wallet server to connect to.  The default may be set when compiling  the wallet client.  If it isn't, either B<-s> must be given or the server  must be set in F<krb5.conf>.  See L<CONFIGURATION> below. +=item B<-u> I<principal> + +Rather than using the user's existing ticket cache for authentication, +authenticate as I<principal> first and use those credentials for +authentication to the wallet server.  B<wallet> will prompt for the +password for I<principal>.  Non-password authentication methods such as +PKINIT aren't supported; to use those, run B<kinit> first and use an +existing ticket cache. +  =item B<-v>  Display the version of the B<wallet> client and exit.  All other valid @@ -418,7 +427,7 @@ overrides this setting.  =head1 SEE ALSO -krb5.conf(5), remctl(1), remctld(8) +kadmin(8), kinit(1), krb5.conf(5), remctl(1), remctld(8)  This program is part of the wallet system.  The current version is available  from L<http://www.eyrie.org/~eagle/software/wallet/>. | 
