diff options
Diffstat (limited to 'client')
| -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 | 
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> | 
