Re-order header file inclusion order to be alphabetic.

Print out the version number of the openpgpsdk library when showing the
version string.

Parse the existing ~/.gnupg/gpg.conf to get the default user id, if any.

Use the actual size of the arrays in snprintf(), rather than a size which
may or may not be accurate.

Get rid of an unused 8K array on the stack - it's not needed.
This commit is contained in:
agc 2009-02-07 05:36:51 +00:00
parent 02ebfd8cdc
commit 6aef23c4e0
1 changed files with 71 additions and 41 deletions

View File

@ -23,11 +23,12 @@
\file Command line program to perform openpgp operations
*/
#include <getopt.h>
#include <libgen.h>
#include <regex.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
#include <libgen.h>
#include <unistd.h>
#include <openpgpsdk/openpgpsdk.h>
@ -58,7 +59,7 @@ enum optdefs {
CLEARSIGN,
VERIFY,
LIST_PACKETS,
VERSION,
VERSION_CMD,
/* options */
KEYRING,
@ -96,7 +97,7 @@ static struct option long_options[] = {
{"list-packets", no_argument, NULL, LIST_PACKETS},
{"version", no_argument, NULL, VERSION},
{"version", no_argument, NULL, VERSION_CMD},
/* options */
{"keyring", required_argument, NULL, KEYRING},
@ -142,6 +143,39 @@ print_usage(const char *usagemsg, char *progname)
(void) fprintf(stderr, usagemsg, basename(progname));
}
#ifndef MIN
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
#endif
/* read any gpg config file */
static int
conf_file(prog_t *p, char *homedir)
{
regmatch_t matchv[10];
regex_t r;
char buf[BUFSIZ];
FILE *fp;
(void) snprintf(buf, sizeof(buf), "%s/gpg.conf", homedir);
if ((fp = fopen(buf, "r")) == NULL) {
return 0;
}
(void) regcomp(&r, "^[ \t]*default-key[ \t]+([0-9a-zA-F]+)",
REG_EXTENDED);
while (fgets(buf, sizeof(buf), fp) != NULL) {
if (regexec(&r, buf, 10, matchv, 0) == 0) {
(void) memcpy(p->userid, &buf[(int)matchv[1].rm_so],
MIN(matchv[1].rm_eo - matchv[1].rm_so,
sizeof(p->userid)));
printf("setting default key to \"%.*s\"\n",
(int)(matchv[1].rm_eo - matchv[1].rm_so),
&buf[(int)matchv[1].rm_so]);
}
}
(void) fclose(fp);
return 1;
}
/* wrapper to get a pass phrase from the user */
static void
get_pass_phrase(char *phrase, size_t size)
@ -192,7 +226,7 @@ psuccess(char *f, ops_validate_result_t * results, ops_keyring_t *pubring)
/* do a command once for a specified file 'f' */
static void
openpgp(prog_t * p, char *f)
openpgp(prog_t *p, char *f)
{
const ops_keydata_t *keydata;
ops_validate_result_t *validate_result;
@ -202,7 +236,7 @@ openpgp(prog_t * p, char *f)
ops_secret_key_t *skey;
ops_user_id_t uid;
const char *suffix;
char outputfilename[MAXBUF + 1];
char outname[MAXBUF + 1];
int fd;
(void) memset(&uid, 0x0, sizeof(uid));
@ -304,11 +338,9 @@ openpgp(prog_t * p, char *f)
p->userid);
exit(EXIT_ERROR);
}
/* outputfilename */
(void) snprintf(outputfilename, MAXBUF, "%s%s", f, suffix);
(void) snprintf(outname, sizeof(outname), "%s%s", f, suffix);
p->overwrite = true;
ops_encrypt_file(f, outputfilename, keydata, p->armour,
p->overwrite);
ops_encrypt_file(f, outname, keydata, p->armour, p->overwrite);
break;
case DECRYPT:
@ -334,10 +366,12 @@ openpgp(prog_t * p, char *f)
ops_print_public_keydata(keydata);
/* get the passphrase */
if (p->passphrase[0] == 0x0) {
get_pass_phrase(p->passphrase, sizeof(p->passphrase));
get_pass_phrase(p->passphrase,
sizeof(p->passphrase));
}
/* now decrypt key */
skey = ops_decrypt_secret_key_from_data(keydata, p->passphrase);
skey = ops_decrypt_secret_key_from_data(keydata,
p->passphrase);
if (skey == NULL) {
(void) fprintf(stderr, "Bad passphrase\n");
p->passphrase[0] = 0x0;
@ -384,13 +418,12 @@ openpgp(prog_t * p, char *f)
break;
case VERIFY:
validate_result = calloc(1, sizeof(ops_validate_result_t));
if (ops_validate_file(validate_result, f, p->armour, p->pubring) == true) {
if (ops_validate_file(validate_result, f, p->armour,
p->pubring) == true) {
psuccess(f, validate_result, p->pubring);
} else {
printf("\"%s\": verification failure: %d invalid signatures, %d unknown signatures\n", f, validate_result->invalid_count, validate_result->unknown_signer_count);
(void) fprintf(stderr, "\"%s\": verification failure: %d invalid signatures, %d unknown signatures\n", f, validate_result->invalid_count, validate_result->unknown_signer_count);
p->ex = EXIT_FAILURE;
}
ops_validate_result_free(validate_result);
@ -412,8 +445,6 @@ main(int argc, char **argv)
{
prog_t p;
char homedir[MAXBUF + 1];
char default_homedir[MAXBUF + 1];
char *dir;
int zeroargs;
int optindex = 0;
int ch = 0;
@ -429,7 +460,15 @@ main(int argc, char **argv)
print_usage(usage, pname);
exit(EXIT_ERROR);
}
/* what does the user want to do? */
/* set default homedir */
(void) snprintf(homedir, sizeof(homedir), "%s/.gnupg", getenv("HOME"));
if (ops_get_debug_level(__FILE__)) {
printf("homedir: %s\n", homedir);
}
/* read any settings in the conf file */
(void) conf_file(&p, homedir);
while ((ch = getopt_long(argc, argv, "", long_options, &optindex)) != -1) {
@ -454,18 +493,19 @@ main(int argc, char **argv)
p.cmd = long_options[optindex].val;
break;
case VERSION:
printf("%s version: %s\n", *argv, ops_get_version());
case VERSION_CMD:
printf("%s version: %s using %s\n",
*argv, ops_get_version(),
OPS_VERSION_STRING);
exit(EXIT_SUCCESS);
/* option */
/* options */
case KEYRING:
if (optarg == NULL) {
(void) fprintf(stderr, "No keyring argument provided\n");
exit(EXIT_ERROR);
}
snprintf(p.keyring, MAXBUF, "%s", optarg);
snprintf(p.keyring, sizeof(p.keyring), "%s", optarg);
break;
case USERID:
@ -476,7 +516,7 @@ main(int argc, char **argv)
if (ops_get_debug_level(__FILE__)) {
(void) fprintf(stderr, "user_id is '%s'\n", optarg);
}
snprintf(p.userid, MAXBUF, "%s", optarg);
snprintf(p.userid, sizeof(p.userid), "%s", optarg);
break;
case PASSPHRASE:
@ -484,7 +524,7 @@ main(int argc, char **argv)
(void) fprintf(stderr, "No passphrase argument provided\n");
exit(EXIT_ERROR);
}
snprintf(p.passphrase, MAXBUF, "%s", optarg);
snprintf(p.passphrase, sizeof(p.passphrase), "%s", optarg);
break;
case ARMOUR:
@ -496,7 +536,8 @@ main(int argc, char **argv)
(void) fprintf(stderr, "No home directory argument provided\n");
exit(EXIT_ERROR);
}
snprintf(homedir, MAXBUF, "%s", optarg);
(void) snprintf(homedir, sizeof(homedir), "%s", optarg);
conf_file(&p, homedir);
break;
@ -527,31 +568,20 @@ main(int argc, char **argv)
* We will then have variables pubring, secring and myring.
*/
if (homedir[0]) {
dir = homedir;
} else {
(void) snprintf(default_homedir, MAXBUF, "%s/.gnupg",
getenv("HOME"));
if (ops_get_debug_level(__FILE__)) {
printf("dir: %s\n", default_homedir);
}
dir = default_homedir;
}
(void) snprintf(p.pubring_name, MAXBUF, "%s/pubring.gpg", dir);
(void) snprintf(p.pubring_name, sizeof(p.pubring_name), "%s/pubring.gpg", homedir);
p.pubring = calloc(1, sizeof(*p.pubring));
if (!ops_keyring_read_from_file(p.pubring, false, p.pubring_name)) {
fprintf(stderr, "Cannot read keyring %s\n", p.pubring_name);
exit(EXIT_ERROR);
}
snprintf(p.secring_name, MAXBUF, "%s/secring.gpg", dir);
snprintf(p.secring_name, sizeof(p.secring_name), "%s/secring.gpg", homedir);
p.secring = calloc(1, sizeof(*p.secring));
if (!ops_keyring_read_from_file(p.secring, false, p.secring_name)) {
fprintf(stderr, "Cannot read keyring %s\n", p.secring_name);
exit(EXIT_ERROR);
}
if (p.keyring[0] != 0x0) {
snprintf(p.myring_name, MAXBUF, "%s/%s", homedir, p.keyring);
snprintf(p.myring_name, sizeof(p.myring_name), "%s/%s", homedir, p.keyring);
p.myring = calloc(1, sizeof(*p.myring));
if (!ops_keyring_read_from_file(p.myring, false, p.myring_name)) {
fprintf(stderr, "Cannot read keyring %s\n", p.myring_name);