diff options
-rw-r--r-- | NEWS | 5 | ||||
-rw-r--r-- | TODO | 7 | ||||
-rw-r--r-- | client/file.c | 52 | ||||
-rw-r--r-- | client/internal.h | 8 | ||||
-rw-r--r-- | client/wallet.c | 23 | ||||
-rw-r--r-- | client/wallet.pod | 44 | ||||
-rw-r--r-- | tests/client/basic-t.in | 30 | ||||
-rwxr-xr-x | tests/data/cmd-fake | 7 |
8 files changed, 148 insertions, 28 deletions
@@ -2,6 +2,11 @@ wallet 0.9 (unreleased) + The wallet command-line client now reads the data for store from a + file (using -f) or from standard input (if -f wasn't given) when the + data isn't specified on the command line. The data still must not + contain nul characters. + Add support for enabling and disabling principals (clearing or setting the NOTGS flag) and examining principals to kasetkey. This functionality isn't used by wallet (and probably won't be) but is @@ -41,10 +41,6 @@ Release 1.0: * On upgrades, support adding new object types and ACL verifiers to the class tables. -* Add an option to the wallet client to read the data from a file for - object store. The initial implementation, depending on the underlying - remctl support, may have to ban nul characters in the uploaded data. - * Write the LDAP entitlement ACL verifier. * Write the PTS ACL verifier. @@ -194,6 +190,9 @@ Future work: * Support authenticating with a keytab. +* Allow store data to contain nuls. Requires rewriting the command + processing for store to use iovecs. + May or may not be good ideas: * Consider using Class::Accessor to get rid of the scaffolding code to 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> diff --git a/tests/client/basic-t.in b/tests/client/basic-t.in index 3a9b2c3..f18c28e 100644 --- a/tests/client/basic-t.in +++ b/tests/client/basic-t.in @@ -12,7 +12,7 @@ . "@abs_top_srcdir@/tests/libtest.sh" # Print the number of tests. -total=31 +total=35 count=1 echo "$total" @@ -210,6 +210,34 @@ else fi rm -f keytab srvtab +# Test store from standard input. +echo "This is a test of store" | runsuccess "" "$wallet" store file fake-test +count=`expr $count + 1` +echo "file fake-test" > store-correct +echo "This is a test of store" >> store-correct +if cmp store-output store-correct >/dev/null 2>&1 ; then + printcount "ok" +else + printcount "not ok" + echo == store-output == + cat store-output + echo == store-correct == + cat store-correct +fi +rm -f store-output store-correct + +# Test store with -f. +echo "This is more store input" > store-input +echo "file fake-test" > store-correct +cat store-input >> store-correct +runsuccess "" "$wallet" -f store-input store file fake-test +if cmp store-output store-correct >/dev/null 2>&1 ; then + printcount "ok" +else + printcount "not ok" +fi +rm -f store-input store-output store-correct + # Test various other client functions and errors. runsuccess "This is a fake keytab." "$wallet" get keytab service/fake-output runsuccess "Some stuff about file fake-test" \ diff --git a/tests/data/cmd-fake b/tests/data/cmd-fake index d12f839..3ffd9cc 100755 --- a/tests/data/cmd-fake +++ b/tests/data/cmd-fake @@ -130,6 +130,13 @@ get) ;; esac ;; +store) + if [ -n "$3" ] ; then + echo "Too many arguments" >&2 + exit 1 + fi + printf "$type $1\n$2" > store-output + ;; show) if [ -n "$2" ] ; then echo "Too many arguments" >&2 |