diff options
author | Russ Allbery <rra@stanford.edu> | 2008-01-19 01:20:38 +0000 |
---|---|---|
committer | Russ Allbery <rra@stanford.edu> | 2008-01-19 01:20:38 +0000 |
commit | cf71c7dac06561b14c8be3383fdb2ca4f3a318d9 (patch) | |
tree | d6b05a005c67710a6d2831abba193923f2070f93 /client | |
parent | b4f2b5bf10e32777b1fcfa8417aa190755247815 (diff) |
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.
Diffstat (limited to 'client')
-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 |
4 files changed, 90 insertions, 3 deletions
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/>. |