summaryrefslogtreecommitdiff
path: root/client
diff options
context:
space:
mode:
authorRuss Allbery <rra@stanford.edu>2008-01-19 01:20:38 +0000
committerRuss Allbery <rra@stanford.edu>2008-01-19 01:20:38 +0000
commitcf71c7dac06561b14c8be3383fdb2ca4f3a318d9 (patch)
treed6b05a005c67710a6d2831abba193923f2070f93 /client
parentb4f2b5bf10e32777b1fcfa8417aa190755247815 (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.h5
-rw-r--r--client/krb5.c64
-rw-r--r--client/wallet.c11
-rw-r--r--client/wallet.pod13
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/>.