diff options
Diffstat (limited to 'client')
| -rw-r--r-- | client/internal.h | 9 | ||||
| -rw-r--r-- | client/keytab.c | 74 | ||||
| -rw-r--r-- | client/srvtab.c | 4 | ||||
| -rw-r--r-- | client/wallet.c | 75 | 
4 files changed, 131 insertions, 31 deletions
| diff --git a/client/internal.h b/client/internal.h index 186d83f..092240e 100644 --- a/client/internal.h +++ b/client/internal.h @@ -14,6 +14,9 @@  #include <sys/types.h>  #include <util/util.h> +/* Forward declarations to avoid unnecessary includes. */ +struct remctl; +  /* Temporary until we have some real configuration. */  #ifndef SERVER  # define SERVER "wallet.stanford.edu" @@ -24,6 +27,12 @@  BEGIN_DECLS +/* Given a remctl object, the type for the wallet interface, the name of a +   keytab object, and a file name, call the correct wallet commands to +   download a keytab and write it to that file. */ +void get_keytab(struct remctl *, const char *type, const char *name, +                const char *file); +  /* Given a filename, some data, and a length, write that data to the given     file safely and atomically by creating file.new, writing the data, linking     file to file.bak, and then renaming file.new to file. */ diff --git a/client/keytab.c b/client/keytab.c new file mode 100644 index 0000000..3450766 --- /dev/null +++ b/client/keytab.c @@ -0,0 +1,74 @@ +/*  $Id$ +** +**  Implementation of keytab handling for the wallet client. +** +**  Written by Russ Allbery <rra@stanford.edu> +**  Copyright 2007 Board of Trustees, Leland Stanford Jr. University +** +**  See README for licensing terms. +*/ + +#include <config.h> +#include <system.h> + +#include <remctl.h> + +#include <client/internal.h> +#include <util/util.h> + +/* +**  Given a remctl object, the name of a keytab object, and a file name, call +**  the correct wallet commands to download a keytab and write it to that +**  file. +*/ +void +get_keytab(struct remctl *r, const char *type, const char *name, +           const char *file) +{ +    const char *command[5]; +    struct remctl_output *output; +    char *data = NULL; +    size_t length = 0; +    int status = 255; + +    /* Run the command on the wallet server */ +    command[0] = type; +    command[1] = "get"; +    command[2] = "keytab"; +    command[3] = name; +    command[4] = NULL; +    if (!remctl_command(r, command)) +        die("%s", remctl_error(r)); + +    /* Retrieve the results. */ +    do { +        output = remctl_output(r); +        switch (output->type) { +        case REMCTL_OUT_OUTPUT: +            if (output->stream == 1) { +                data = xrealloc(data, length + output->length); +                memcpy(data + length, output->data, output->length); +                length += output->length; +            } else { +                fprintf(stderr, "wallet: "); +                fwrite(output->data, 1, output->length, stderr); +            } +            break; +        case REMCTL_OUT_STATUS: +            status = output->status; +            break; +        case REMCTL_OUT_ERROR: +            fprintf(stderr, "wallet: "); +            fwrite(output->data, 1, output->length, stderr); +            fputc('\n', stderr); +            exit(255); +        case REMCTL_OUT_DONE: +            break; +        } +    } while (output->type != REMCTL_OUT_DONE); +    if (status != 0) +        exit(status); + +    /* Okay, we now have the valid keytab data in data.  Write it out. */ +    write_file(file, data, length); +} diff --git a/client/srvtab.c b/client/srvtab.c index 68a2618..e6b9e0d 100644 --- a/client/srvtab.c +++ b/client/srvtab.c @@ -11,8 +11,6 @@  #include <config.h>  #include <system.h> -#include <errno.h> -#include <fcntl.h>  #include <krb5.h>  #include <client/internal.h> @@ -100,8 +98,6 @@ write_srvtab(const char *srvtab, const char *principal, const char *keytab)      krb5_keytab_entry entry;      krb5_error_code ret;      size_t length; -    int fd; -    ssize_t status;      char aname[ANAME_SZ + 1] = "";      char inst[INST_SZ + 1]   = "";      char realm[REALM_SZ + 1] = ""; diff --git a/client/wallet.c b/client/wallet.c index 998ec30..f0a0e4f 100644 --- a/client/wallet.c +++ b/client/wallet.c @@ -12,7 +12,6 @@  #include <system.h>  #include <errno.h> -#include <fcntl.h>  #include <remctl.h>  #include <client/internal.h> @@ -52,17 +51,16 @@ usage(int status)  int  main(int argc, char *argv[])  { -    int option, fd; -    ssize_t status; +    int option, i;      const char **command; -    struct remctl_result *result;      const char *type = "wallet";      const char *server = SERVER;      const char *principal = NULL;      unsigned short port = PORT;      const char *file = NULL;      const char *srvtab = NULL; -    int i; +    struct remctl *r; +    struct remctl_output *output;      long tmp;      char *end; @@ -120,31 +118,54 @@ main(int argc, char *argv[])              die("-S option requires -f also be used");      } -    /* Allocate space for the command to send to the server. */ -    command = xmalloc(sizeof(char *) * (argc + 2)); -    command[0] = type; -    for (i = 0; i < argc; i++) -        command[i + 1] = argv[i]; -    command[argc + 1] = NULL; - -    /* Run the command. */ -    result = remctl(server, port, principal, command); -    if (result == NULL) +    /* Open a remctl connection. */ +    r = remctl_new(); +    if (r == NULL)          sysdie("cannot allocate memory"); -    free(command); +    if (!remctl_open(r, server, port, principal)) +        die("%s", remctl_error(r)); -    /* Display the results. */ -    if (result->error != NULL) { -        fprintf(stderr, "wallet: %s\n", result->error); -    } else if (result->stderr_len > 0) { -        fprintf(stderr, "wallet: "); -        fwrite(result->stderr_buf, 1, result->stderr_len, stderr); -    } else if (file != NULL && strcmp(command[1], "get") == 0) { -        write_file(file, result->stdout_buf, result->stdout_len); +    /* Most commands, we handle ourselves, but keytab get commands with -f are +       special. */ +    if (strcmp(argv[0], "get") == 0 && strcmp(argv[1], "keytab") == 0) { +        if (argc > 3) +            die("too many arguments"); +        get_keytab(r, type, argv[2], file);          if (srvtab != NULL) -            write_srvtab(srvtab, command[3], file); +            write_srvtab(srvtab, argv[2], file); +        exit(0);      } else { -        fwrite(result->stdout_buf, 1, result->stdout_len, stdout); +        command = xmalloc(sizeof(char *) * (argc + 2)); +        command[0] = type; +        for (i = 0; i < argc; i++) +            command[i + 1] = argv[i]; +        command[argc + 1] = NULL; +        if (!remctl_command(r, command)) +            die("%s", remctl_error(r)); +        do { +            output = remctl_output(r); +            switch (output->type) { +            case REMCTL_OUT_OUTPUT: +                if (output->stream == 1) +                    fwrite(output->data, 1, output->length, stdout); +                else { +                    fprintf(stderr, "wallet: "); +                    fwrite(output->data, 1, output->length, stderr); +                } +                break; +            case REMCTL_OUT_STATUS: +                exit(output->status); +            case REMCTL_OUT_ERROR: +                fprintf(stderr, "wallet: "); +                fwrite(output->data, 1, output->length, stderr); +                fputc('\n', stderr); +                exit(255); +            case REMCTL_OUT_DONE: +                break; +            } +        } while (output->type != REMCTL_OUT_DONE);      } -    exit(result->status); + +    /* This should never be reached. */ +    die("invalid return from wallet server");  } | 
