=== modified file 'plugins.d/mandosclient.c' --- plugins.d/mandosclient.c 2008-08-03 20:35:01 +0000 +++ plugins.d/mandosclient.c 2008-08-04 16:05:01 +0000 @@ -65,25 +65,22 @@ #include /* inet_pton() */ #include /* not */ #include /* IF_NAMESIZE */ - +#include /* struct argp_option, + struct argp_state, struct argp, + argp_parse() */ /* GPGME */ #include /* perror() */ #include -/* getopt_long */ -#include - #define BUFFER_SIZE 256 +bool debug = false; static const char *keydir = "/conf/conf.d/mandos"; -static const char *pubkeyfile = "pubkey.txt"; -static const char *seckeyfile = "seckey.txt"; - -bool debug = false; - -const char mandos_protocol_version[] = "1"; - -/* Used for passing in values through all the callback functions */ +const char *argp_program_version = "mandosclient 0.9"; +const char *argp_program_bug_address = ""; +static const char mandos_protocol_version[] = "1"; + +/* Used for passing in values through the Avahi callback functions */ typedef struct { AvahiSimplePoll *simple_poll; AvahiServer *server; @@ -93,6 +90,9 @@ const char *priority; } mandos_context; +/* Make room in "buffer" for at least BUFFER_SIZE additional bytes. + * "buffer_capacity" is how much is currently allocated, + * "buffer_length" is how much is already used. */ size_t adjustbuffer(char **buffer, size_t buffer_length, size_t buffer_capacity){ if (buffer_length + BUFFER_SIZE > buffer_capacity){ @@ -233,7 +233,8 @@ *plaintext = NULL; while(true){ - plaintext_capacity = adjustbuffer(plaintext, (size_t)plaintext_length, + plaintext_capacity = adjustbuffer(plaintext, + (size_t)plaintext_length, plaintext_capacity); if (plaintext_capacity == 0){ perror("adjustbuffer"); @@ -287,7 +288,9 @@ fprintf(stderr, "GnuTLS: %s", string); } -static int init_gnutls_global(mandos_context *mc){ +static int init_gnutls_global(mandos_context *mc, + const char *pubkeyfile, + const char *seckeyfile){ int ret; if(debug){ @@ -353,7 +356,8 @@ return 0; } -static int init_gnutls_session(mandos_context *mc, gnutls_session_t *session){ +static int init_gnutls_session(mandos_context *mc, + gnutls_session_t *session){ int ret; /* GnuTLS session creation */ ret = gnutls_init(session, GNUTLS_SERVER); @@ -399,7 +403,7 @@ AvahiIfIndex if_index, mandos_context *mc){ int ret, tcp_sd; - struct sockaddr_in6 to; + union { struct sockaddr in; struct sockaddr_in6 in6; } to; char *buffer = NULL; char *decrypted_buffer; size_t buffer_length = 0; @@ -409,7 +413,6 @@ int retval = 0; char interface[IF_NAMESIZE]; gnutls_session_t session; - gnutls_dh_params_t dh_params; ret = init_gnutls_session (mc, &session); if (ret != 0){ @@ -436,10 +439,10 @@ } memset(&to,0,sizeof(to)); /* Spurious warning */ - to.sin6_family = AF_INET6; + to.in6.sin6_family = AF_INET6; /* It would be nice to have a way to detect if we were passed an IPv4 address here. Now we assume an IPv6 address. */ - ret = inet_pton(AF_INET6, ip, &to.sin6_addr); + ret = inet_pton(AF_INET6, ip, &to.in6.sin6_addr); if (ret < 0 ){ perror("inet_pton"); return -1; @@ -448,14 +451,14 @@ fprintf(stderr, "Bad address: %s\n", ip); return -1; } - to.sin6_port = htons(port); /* Spurious warning */ + to.in6.sin6_port = htons(port); /* Spurious warning */ - to.sin6_scope_id = (uint32_t)if_index; + to.in6.sin6_scope_id = (uint32_t)if_index; if(debug){ fprintf(stderr, "Connection to: %s, port %d\n", ip, port); char addrstr[INET6_ADDRSTRLEN] = ""; - if(inet_ntop(to.sin6_family, &(to.sin6_addr), addrstr, + if(inet_ntop(to.in6.sin6_family, &(to.in6.sin6_addr), addrstr, sizeof(addrstr)) == NULL){ perror("inet_ntop"); } else { @@ -465,7 +468,7 @@ } } - ret = connect(tcp_sd, (struct sockaddr *) &to, sizeof(to)); + ret = connect(tcp_sd, &to.in, sizeof(to)); if (ret < 0){ perror("connect"); return -1; @@ -520,7 +523,8 @@ } while(true){ - buffer_capacity = adjustbuffer(&buffer, buffer_length, buffer_capacity); + buffer_capacity = adjustbuffer(&buffer, buffer_length, + buffer_capacity); if (buffer_capacity == 0){ perror("adjustbuffer"); retval = -1; @@ -731,72 +735,98 @@ gid_t gid; char *connect_to = NULL; AvahiIfIndex if_index = AVAHI_IF_UNSPEC; + const char *pubkeyfile = "pubkey.txt"; + const char *seckeyfile = "seckey.txt"; mandos_context mc = { .simple_poll = NULL, .server = NULL, .dh_bits = 1024, .priority = "SECURE256"}; { - /* Temporary int to get the address of for getopt_long */ - int debug_int = debug ? 1 : 0; - while (true){ - struct option long_options[] = { - {"debug", no_argument, &debug_int, 1}, - {"connect", required_argument, NULL, 'c'}, - {"interface", required_argument, NULL, 'i'}, - {"keydir", required_argument, NULL, 'd'}, - {"seckey", required_argument, NULL, 's'}, - {"pubkey", required_argument, NULL, 'p'}, - {"dh-bits", required_argument, NULL, 'D'}, - {"priority", required_argument, NULL, 'P'}, - {0, 0, 0, 0} }; - - int option_index = 0; - ret = getopt_long (argc, argv, "i:", long_options, - &option_index); - - if (ret == -1){ + struct argp_option options[] = { + { .name = "debug", .key = 128, + .doc = "Debug mode", .group = 3 }, + { .name = "connect", .key = 'c', + .arg = "IP", + .doc = "Connect directly to a sepcified mandos server", + .group = 1 }, + { .name = "interface", .key = 'i', + .arg = "INTERFACE", + .doc = "Interface that Avahi will conntect through", + .group = 1 }, + { .name = "keydir", .key = 'd', + .arg = "KEYDIR", + .doc = "Directory where the openpgp keyring is", + .group = 1 }, + { .name = "seckey", .key = 's', + .arg = "SECKEY", + .doc = "Secret openpgp key for gnutls authentication", + .group = 1 }, + { .name = "pubkey", .key = 'p', + .arg = "PUBKEY", + .doc = "Public openpgp key for gnutls authentication", + .group = 2 }, + { .name = "dh-bits", .key = 129, + .arg = "BITS", + .doc = "dh-bits to use in gnutls communication", + .group = 2 }, + { .name = "priority", .key = 130, + .arg = "PRIORITY", + .doc = "GNUTLS priority", .group = 1 }, + { .name = NULL } + }; + + + error_t parse_opt (int key, char *arg, + struct argp_state *state) { + /* Get the INPUT argument from `argp_parse', which we know is + a pointer to our plugin list pointer. */ + switch (key) { + case 128: + debug = true; break; - } - - switch(ret){ - case 0: + case 'c': + connect_to = arg; break; case 'i': - interface = optarg; - break; - case 'c': - connect_to = optarg; + interface = arg; break; case 'd': - keydir = optarg; + keydir = arg; + break; + case 's': + seckeyfile = arg; break; case 'p': - pubkeyfile = optarg; - break; - case 's': - seckeyfile = optarg; - break; - case 'D': + pubkeyfile = arg; + break; + case 129: errno = 0; - mc.dh_bits = (unsigned int) strtol(optarg, NULL, 10); + mc.dh_bits = (unsigned int) strtol(arg, NULL, 10); if (errno){ perror("strtol"); exit(EXIT_FAILURE); } break; - case 'P': - mc.priority = optarg; - break; - case '?': + case 130: + mc.priority = arg; + break; + case ARGP_KEY_ARG: + argp_usage (state); + break; + case ARGP_KEY_END: + break; default: - /* getopt_long() has already printed a message about the - unrcognized option, so just exit. */ - exit(EXIT_FAILURE); + return ARGP_ERR_UNKNOWN; } + return 0; } - /* Set the global debug flag from the temporary int */ - debug = debug_int ? true : false; + + struct argp argp = { .options = options, .parser = parse_opt, + .args_doc = "", + .doc = "Mandos client -- Get and decrypt" + " passwords from mandos server" }; + argp_parse (&argp, argc, argv, 0, 0, NULL); } - + pubkeyfile = combinepath(keydir, pubkeyfile); if (pubkeyfile == NULL){ perror("combinepath"); @@ -810,7 +840,7 @@ goto end; } - ret = init_gnutls_global(&mc); + ret = init_gnutls_global(&mc, pubkeyfile, seckeyfile); if (ret == -1){ fprintf(stderr, "init_gnutls_global\n"); goto end;