summaryrefslogtreecommitdiff
path: root/client
diff options
context:
space:
mode:
Diffstat (limited to 'client')
-rw-r--r--client/file.c52
-rw-r--r--client/internal.h8
-rw-r--r--client/wallet.c23
-rw-r--r--client/wallet.pod44
4 files changed, 104 insertions, 23 deletions
diff --git a/client/file.c b/client/file.c
index 7e0563e..c109bd5 100644
--- a/client/file.c
+++ b/client/file.c
@@ -11,7 +11,9 @@
#include <config.h>
#include <portable/system.h>
+#include <errno.h>
#include <fcntl.h>
+#include <sys/stat.h>
#include <client/internal.h>
#include <util/util.h>
@@ -109,3 +111,53 @@ get_file(struct remctl *r, const char *prefix, const char *type,
free(data);
return 0;
}
+
+
+/*
+ * Read all of a file into memory and return the contents as a newly allocated
+ * string. Handles a file name of "-" to mean standard input. Dies on any
+ * failure.
+ *
+ * This will need modification later when we want to handle nul characters.
+ */
+char *
+read_file(const char *name)
+{
+ char *contents;
+ size_t size, offset;
+ int fd;
+ struct stat st;
+ ssize_t status;
+
+ if (strcmp(name, "-") == 0) {
+ fd = fileno(stdin);
+ size = BUFSIZ;
+ contents = xmalloc(size);
+ } else {
+ fd = open(name, O_RDONLY);
+ if (fd < 0)
+ sysdie("cannot open file %s", name);
+ if (fstat(fd, &st) < 0)
+ sysdie("cannot stat file %s", name);
+ size = st.st_size + 1;
+ contents = xmalloc(size);
+ }
+ offset = 0;
+ do {
+ if (offset >= size - 1) {
+ size += BUFSIZ;
+ contents = xrealloc(contents, size);
+ }
+ do {
+ status = read(fd, contents + offset, size - offset - 1);
+ } while (status == -1 && errno == EINTR);
+ if (status < 0)
+ sysdie("cannot read from file");
+ offset += status;
+ } while (status > 0);
+ close(fd);
+ contents[offset] = '\0';
+ if (memchr(contents, '\0', offset) != NULL)
+ die("cannot yet handle file data containing nul characters");
+ return contents;
+}
diff --git a/client/internal.h b/client/internal.h
index 64fad04..e55f2b8 100644
--- a/client/internal.h
+++ b/client/internal.h
@@ -90,6 +90,14 @@ void write_file(const char *name, const void *data, size_t length);
void write_srvtab(krb5_context, const char *srvtab, const char *principal,
const char *keytab);
+/*
+ * Read all of a file into memory and return the contents as a newly allocated
+ * string. Handles a file name of "-" to mean standard input. Dies on any
+ * failure. This will need modification later when we want to handle nul
+ * characters.
+ */
+char *read_file(const char *);
+
END_DECLS
#endif /* !CLIENT_INTERNAL_H */
diff --git a/client/wallet.c b/client/wallet.c
index 2995cf6..5ee24f5 100644
--- a/client/wallet.c
+++ b/client/wallet.c
@@ -194,9 +194,10 @@ main(int argc, char *argv[])
if (argc < 3)
usage(1);
- /* -f is only supported for get and -S with get keytab. */
- if (file != NULL && strcmp(argv[0], "get") != 0)
- die("-f only supported for get");
+ /* -f is only supported for get and store and -S with get keytab. */
+ if (file != NULL)
+ if (strcmp(argv[0], "get") != 0 && strcmp(argv[0], "store") != 0)
+ die("-f only supported for get and store");
if (srvtab != NULL) {
if (strcmp(argv[0], "get") != 0 || strcmp(argv[1], "keytab") != 0)
die("-S only supported for get keytab");
@@ -239,11 +240,23 @@ main(int argc, char *argv[])
status = get_file(r, options.type, argv[1], argv[2], file);
}
} else {
- command = xmalloc(sizeof(char *) * (argc + 2));
+ if (strcmp(argv[0], "store") == 0) {
+ if (argc > 4)
+ die("too many arguments");
+ else if (argc == 4)
+ command = xmalloc(sizeof(char *) * (argc + 2));
+ else
+ command = xmalloc(sizeof(char *) * (argc + 3));
+ } else
+ command = xmalloc(sizeof(char *) * (argc + 2));
command[0] = options.type;
for (i = 0; i < argc; i++)
command[i + 1] = argv[i];
- command[argc + 1] = NULL;
+ if (strcmp(argv[0], "store") == 0 && argc < 4) {
+ command[argc + 1] = read_file(file == NULL ? "-" : file);
+ command[argc + 2] = NULL;
+ } else
+ command[argc + 1] = NULL;
status = run_command(r, command, NULL, NULL);
}
remctl_close(r);
diff --git a/client/wallet.pod b/client/wallet.pod
index b6e8ff4..657929b 100644
--- a/client/wallet.pod
+++ b/client/wallet.pod
@@ -4,9 +4,9 @@ wallet - Client for retrieving secure data from a central server
=head1 SYNOPSIS
-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>]
-[B<-u> I<principal>] I<command> [I<arg> ...]
+B<wallet> [B<-hv>] [B<-c> I<command>] [B<-f> I<file>]
+ [B<-k> I<principal>] [B<-p> I<port>] [S<B<-s> I<server>>]
+ [B<-S> I<srvtab>] [B<-u> I<principal>] I<command> [I<arg> ...]
=head1 DESCRIPTION
@@ -65,16 +65,17 @@ sometimes be useful to use a different prefix for testing a different
version of the wallet code on the server. This option can also be set in
F<krb5.conf>; see L<CONFIGURATION> below.
-=item B<-f> I<output>
+=item B<-f> I<file>
-This flag is only used in combination with the C<get> command. Rather
-than sending the secure data to standard output (the default), store the
-secure data in the file I<output>.
+This flag is only used in combination with the C<get> and C<store>
+commands. For C<get>, rather than sending the secure data to standard
+output (the default), the secure data will be stored in I<file>. For
+C<store>, the data to be stored will be read from I<file>.
-If the object being retrieved is not a keytab object, any current file
-named I<output> is renamed to F<I<outout>.bak> before the new file is
-created. F<I<outout>.new> is used as a temporary file and any existing
-file with that name will be deleted.
+With C<get>, if the object being retrieved is not a keytab object, any
+current file named I<output> is renamed to F<I<outout>.bak> before the new
+file is created. F<I<outout>.new> is used as a temporary file and any
+existing file with that name will be deleted.
If the object being retrieved is a keytab object and the file I<output>
already exists, the downloaded keys will be added to the existing keytab
@@ -83,6 +84,11 @@ ktremove> or an equivalent later to clean up old keys. F<I<output>.new>
is still used as a temporary file and any existing file with that name
will be deleted.
+C<store> does not yet support nul bytes in I<file> (or in any other way of
+specifying the data to be stored). To store binary files in the wallet,
+you will need to encode them with uuencode, base64, or some similar scheme
+and then decode them after retrieval.
+
=item B<-k> I<principal>
The service principal of the wallet server. The default is to use the
@@ -323,15 +329,17 @@ name, the owner, any specific ACLs set on the object, the expiration if
any, and the user, remote host, and time when the object was created, last
stored, and last downloaded.
-=item store <type> <name> <data>
+=item store <type> <name> [<data>]
Stores <data> for the object identified by <type> and <name> for later
-retrieval with C<get>. Not all object types support this.
-
-Currently, <data> is limited to not containing nul characters and may
-therefore not be binary data, and is limited by the maximum command line
-length of the operating system of the wallet server. These restrictions
-will be lifted in the future.
+retrieval with C<get>. Not all object types support this. If <data> is
+not specified on the command line, it will be read from the file specified
+with B<-f> (if given) or from standard input.
+
+Currently, the stored data must not contain nul characters and may
+therefore not be binary data. Its length is also limited by the maximum
+command line length of the operating system of the wallet server. These
+restrictions will be lifted in the future.
If an object with type <type> and name <name> does not already exist when
this command is issued (as checked with the check interface), B<wallet>