summaryrefslogtreecommitdiffabout
path: root/src/gpg.c
authorSergey Poznyakoff <gray@gnu.org.ua>2013-01-01 11:25:55 (GMT)
committer Sergey Poznyakoff <gray@gnu.org.ua>2013-01-01 11:33:04 (GMT)
commit24e6dfa7cffceea0cac0f3cc349192788f040939 (patch) (side-by-side diff)
treec2bd53e9bc58873c8187e6bd622ae152b35d1d51 /src/gpg.c
parent2bdd70d698c63d32f25b4f1142e09f5eaef4812a (diff)
downloadwydawca-24e6dfa7cffceea0cac0f3cc349192788f040939.tar.gz
wydawca-24e6dfa7cffceea0cac0f3cc349192788f040939.tar.bz2
Update copyright years. Switch to a familiar style.
Diffstat (limited to 'src/gpg.c') (more/less context) (ignore whitespace changes)
-rw-r--r--src/gpg.c527
1 files changed, 255 insertions, 272 deletions
diff --git a/src/gpg.c b/src/gpg.c
index 814be6f..39df226 100644
--- a/src/gpg.c
+++ b/src/gpg.c
@@ -1,5 +1,5 @@
/* wydawca - automatic release submission daemon
- Copyright (C) 2007, 2010-2011 Sergey Poznyakoff
+ Copyright (C) 2007, 2010-2013 Sergey Poznyakoff
Wydawca is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
@@ -19,322 +19,305 @@
#include "wydawca.h"
#include <gpgme.h>
-#define fail_if_err(expr) \
- do \
- { \
- int a = expr; \
- if (a) \
- { \
- logmsg (LOG_ERR, _("%s: GPGME error: %s"), #expr, \
- gpgme_strerror (a)); \
- return 1; \
- } \
- } \
- while (0)
+#define fail_if_err(expr) do { \
+ int a = expr; \
+ if (a) { \
+ logmsg(LOG_ERR, _("%s: GPGME error: %s"), #expr, \
+ gpgme_strerror(a)); \
+ return 1; \
+ } \
+ } while (0)
char *temp_homedir;
-static int rmdir_r (const char *name);
+static int rmdir_r(const char *name);
/* Auxiliary function: change to directory NAME and recursively remove
everything under it. */
static int
-recursive_rmdir (const char *name)
+recursive_rmdir(const char *name)
{
- int rc;
- DIR *dir;
- struct dirent *ent;
-
- if (chdir (name))
- {
- logmsg (LOG_ERR, _("cannot change to directory %s: %s"),
- name, strerror (errno));
- return 1;
- }
-
- dir = opendir (".");
- if (!dir)
- {
- logmsg (LOG_ERR, _("cannot open directory %s: %s"),
- name, strerror (errno));
- return 1;
- }
-
- for (rc = 0; rc == 0 && (ent = readdir (dir));)
- {
- struct stat st;
-
- if (strcmp (ent->d_name, ".") == 0
- || strcmp (ent->d_name, "..") == 0)
- continue;
-
- if (stat (ent->d_name, &st) && errno != ENOENT)
- {
- logmsg (LOG_ERR, _("cannot stat file `%s': %s"),
- name, strerror (errno));
- rc = 1;
+ int rc;
+ DIR *dir;
+ struct dirent *ent;
+
+ if (chdir(name)) {
+ logmsg(LOG_ERR, _("cannot change to directory %s: %s"),
+ name, strerror(errno));
+ return 1;
}
- else if (S_ISDIR (st.st_mode))
- rc = rmdir_r (ent->d_name);
- else if ((rc = unlink (ent->d_name)) != 0 && errno != ENOENT)
- logmsg (LOG_ERR, _("cannot unlink %s: %s"),
- ent->d_name, strerror (errno));
- }
- closedir (dir);
- return rc;
+
+ dir = opendir(".");
+ if (!dir) {
+ logmsg(LOG_ERR, _("cannot open directory %s: %s"),
+ name, strerror(errno));
+ return 1;
+ }
+
+ for (rc = 0; rc == 0 && (ent = readdir(dir));) {
+ struct stat st;
+
+ if (strcmp(ent->d_name, ".") == 0
+ || strcmp(ent->d_name, "..") == 0)
+ continue;
+
+ if (stat(ent->d_name, &st) && errno != ENOENT) {
+ logmsg(LOG_ERR, _("cannot stat file `%s': %s"),
+ name, strerror(errno));
+ rc = 1;
+ } else if (S_ISDIR(st.st_mode))
+ rc = rmdir_r(ent->d_name);
+ else if ((rc = unlink(ent->d_name)) != 0 && errno != ENOENT)
+ logmsg(LOG_ERR, _("cannot unlink %s: %s"),
+ ent->d_name, strerror(errno));
+ }
+ closedir(dir);
+ return rc;
}
/* Recursively remove the contents of the directory NAME and the directory
itself. Do not change CWD. */
static int
-rmdir_r (const char *name)
+rmdir_r(const char *name)
{
- int rc;
-
- if (push_dir (NULL))
- {
- logmsg (LOG_ERR, _("cannot save current directory: %s"),
- strerror (errno));
- return 1;
- }
- rc = recursive_rmdir (name);
- if (pop_dir ())
- {
- logmsg (LOG_ERR, _("cannot restore current directory: %s"),
- strerror (errno));
- rc = 1;
- }
-
- if (rc == 0 && rmdir (name))
- {
- logmsg (LOG_ERR, _("cannot remove directory %s: %s"),
- name, strerror (errno));
- return 1;
- }
-
- return rc;
+ int rc;
+
+ if (push_dir(NULL)) {
+ logmsg(LOG_ERR, _("cannot save current directory: %s"),
+ strerror(errno));
+ return 1;
+ }
+ rc = recursive_rmdir(name);
+ if (pop_dir()) {
+ logmsg(LOG_ERR, _("cannot restore current directory: %s"),
+ strerror(errno));
+ rc = 1;
+ }
+
+ if (rc == 0 && rmdir(name)) {
+ logmsg(LOG_ERR, _("cannot remove directory %s: %s"),
+ name, strerror(errno));
+ return 1;
+ }
+
+ return rc;
}
/* Remove temporary GPG home directory */
static void
-remove_homedir ()
+remove_homedir()
{
- if (debug_level > 1)
- logmsg (LOG_DEBUG, _("removing GNUPG home directory: %s"), temp_homedir);
- if (rmdir_r (temp_homedir))
- logmsg (LOG_CRIT, _("failed to remove GPG directory %s"), temp_homedir);
+ if (debug_level > 1)
+ logmsg(LOG_DEBUG, _("removing GNUPG home directory: %s"),
+ temp_homedir);
+ if (rmdir_r(temp_homedir))
+ logmsg(LOG_CRIT, _("failed to remove GPG directory %s"),
+ temp_homedir);
}
/* Create a temporary GPG home directory */
static int
-create_gpg_homedir ()
+create_gpg_homedir()
{
- if (temp_homedir)
- return 0;
-
- temp_homedir = grecs_strdup ("/tmp/wydawca-XXXXXX");
- if (!mkdtemp (temp_homedir))
- {
- logmsg (LOG_CRIT, _("cannot create GPG home directory (%s): %s"),
- temp_homedir, strerror (errno));
- return 1;
- }
- atexit (remove_homedir);
- if (debug_level > 1)
- logmsg (LOG_DEBUG, _("GNUPG home directory: %s"), temp_homedir);
- setenv ("GNUPGHOME", temp_homedir, 1);
- return 0;
+ if (temp_homedir)
+ return 0;
+
+ temp_homedir = grecs_strdup("/tmp/wydawca-XXXXXX");
+ if (!mkdtemp(temp_homedir)) {
+ logmsg(LOG_CRIT,
+ _("cannot create GPG home directory (%s): %s"),
+ temp_homedir, strerror(errno));
+ return 1;
+ }
+ atexit(remove_homedir);
+ if (debug_level > 1)
+ logmsg(LOG_DEBUG, _("GNUPG home directory: %s"), temp_homedir);
+ setenv("GNUPGHOME", temp_homedir, 1);
+ return 0;
}
static int
-checksig (gpgme_signature_t sig, const char *uid, struct file_triplet *trp)
+checksig(gpgme_signature_t sig, const char *uid, struct file_triplet *trp)
{
- switch (gpg_err_code (sig->status))
- {
- case GPG_ERR_NO_ERROR:
- if (debug_level)
- logmsg (LOG_NOTICE, _("Good signature from %s"), uid);
- trp->uploader = uploader_find_frp (trp->uploader_list, sig->fpr);
- if (!trp->uploader)
- {
- logmsg (LOG_ERR,
- _("good signature from %s, "
- "but the uploader info for %s not found"),
- uid, sig->fpr);
- return 1;
+ switch (gpg_err_code(sig->status)) {
+ case GPG_ERR_NO_ERROR:
+ if (debug_level)
+ logmsg(LOG_NOTICE, _("Good signature from %s"), uid);
+ trp->uploader = uploader_find_frp(trp->uploader_list,
+ sig->fpr);
+ if (!trp->uploader) {
+ logmsg(LOG_ERR,
+ _("good signature from %s, "
+ "but the uploader info for %s not found"),
+ uid, sig->fpr);
+ return 1;
+ }
+ break;
+
+ case GPG_ERR_BAD_SIGNATURE:
+ UPDATE_STATS(STAT_BAD_SIGNATURE);
+ logmsg(LOG_ERR, _("BAD signature from %s"), uid);
+ return 0;
+
+ case GPG_ERR_NO_PUBKEY:
+ UPDATE_STATS(STAT_ACCESS_VIOLATIONS);
+ logmsg(LOG_ERR, _("No public key"));
+ return 0;
+
+ case GPG_ERR_NO_DATA:
+ UPDATE_STATS(STAT_BAD_TRIPLETS);
+ logmsg(LOG_ERR, _("No signature"));
+ return 0;
+
+ case GPG_ERR_SIG_EXPIRED:
+ UPDATE_STATS(STAT_BAD_SIGNATURE);
+ logmsg(LOG_ERR, _("Expired signature from %s"), uid);
+ return 0;
+
+ case GPG_ERR_KEY_EXPIRED:
+ UPDATE_STATS(STAT_BAD_SIGNATURE);
+ logmsg(LOG_ERR, _("Key expired (%s)"), uid);
+ return 0;
+
+ default:
+ logmsg(LOG_ERR, _("Unknown signature error"));
+ return 0;
}
- break;
-
- case GPG_ERR_BAD_SIGNATURE:
- UPDATE_STATS (STAT_BAD_SIGNATURE);
- logmsg (LOG_ERR, _("BAD signature from %s"), uid);
- return 0;
-
- case GPG_ERR_NO_PUBKEY:
- UPDATE_STATS (STAT_ACCESS_VIOLATIONS);
- logmsg (LOG_ERR, _("No public key"));
- return 0;
-
- case GPG_ERR_NO_DATA:
- UPDATE_STATS (STAT_BAD_TRIPLETS);
- logmsg (LOG_ERR, _("No signature"));
- return 0;
-
- case GPG_ERR_SIG_EXPIRED:
- UPDATE_STATS (STAT_BAD_SIGNATURE);
- logmsg (LOG_ERR, _("Expired signature from %s"), uid);
- return 0;
-
- case GPG_ERR_KEY_EXPIRED:
- UPDATE_STATS (STAT_BAD_SIGNATURE);
- logmsg (LOG_ERR, _("Key expired (%s)"), uid);
- return 0;
-
- default:
- logmsg (LOG_ERR, _("Unknown signature error"));
- return 0;
- }
- return -1;
+ return -1;
}
static int
-gpg_verify_signature (gpgme_ctx_t ctx, gpgme_signature_t sig,
- struct file_triplet *trp)
+gpg_verify_signature(gpgme_ctx_t ctx, gpgme_signature_t sig,
+ struct file_triplet *trp)
{
- if (!sig)
- return 0;
-
- for (; sig; sig = sig->next)
- {
- const char *uid;
- gpgme_key_t key;
- int rc;
-
- if (gpgme_get_key (ctx, sig->fpr, &key, 0) == GPG_ERR_NO_ERROR)
- uid = key->uids->uid;
- else
- uid = sig->fpr;
- rc = checksig (sig, uid, trp);
- gpgme_key_unref (key);
- if (rc != -1)
- return rc;
- }
- return 1;
+ if (!sig)
+ return 0;
+
+ for (; sig; sig = sig->next) {
+ const char *uid;
+ gpgme_key_t key;
+ int rc;
+
+ if (gpgme_get_key(ctx, sig->fpr, &key, 0) == GPG_ERR_NO_ERROR)
+ uid = key->uids->uid;
+ else
+ uid = sig->fpr;
+ rc = checksig(sig, uid, trp);
+ gpgme_key_unref(key);
+ if (rc != -1)
+ return rc;
+ }
+ return 1;
}
/* Verify the directive file from TRP using public key PUBKEY */
int
-verify_directive_signature (struct file_triplet *trp)
+verify_directive_signature(struct file_triplet *trp)
{
- gpgme_ctx_t ctx;
- gpgme_data_t key_data, directive_data, plain = NULL;
- gpgme_error_t ec;
- int rc;
- struct uploader_info *uptr;
-
- create_gpg_homedir ();
- fail_if_err (gpgme_new (&ctx));
-
- for (uptr = trp->uploader_list; uptr; uptr = uptr->next)
- {
- gpgme_import_result_t res;
- gpgme_import_status_t pstat;
-
- fail_if_err (gpgme_data_new_from_mem (&key_data,
- uptr->gpg_key,
- strlen (uptr->gpg_key),
- 0));
- fail_if_err (gpgme_op_import (ctx, key_data));
- res = gpgme_op_import_result (ctx);
- pstat = res->imports;
- uptr->fpr = grecs_strdup (pstat->fpr);
- if (debug_level > 2)
- logmsg (LOG_DEBUG, _("imported key: user = %s, fingerprint = %s"),
- uptr->name, uptr->fpr);
- }
-
- fail_if_err (gpgme_data_new_from_file (&directive_data,
- trp->file[file_directive].name, 1));
- gpgme_data_new (&plain);
- ec = gpgme_op_verify (ctx, directive_data, NULL, plain);
- if (ec == GPG_ERR_NO_ERROR)
- {
- gpgme_verify_result_t result;
-
- result = gpgme_op_verify_result (ctx);
- if (!gpg_verify_signature (ctx, result->signatures, trp))
- {
- UPDATE_STATS (STAT_BAD_SIGNATURE);
- notify (trp->spool->notification, trp, ev_bad_directive_signature);
- rc = 1;
+ gpgme_ctx_t ctx;
+ gpgme_data_t key_data, directive_data, plain = NULL;
+ gpgme_error_t ec;
+ int rc;
+ struct uploader_info *uptr;
+
+ create_gpg_homedir();
+ fail_if_err(gpgme_new(&ctx));
+
+ for (uptr = trp->uploader_list; uptr; uptr = uptr->next) {
+ gpgme_import_result_t res;
+ gpgme_import_status_t pstat;
+
+ fail_if_err(gpgme_data_new_from_mem(&key_data,
+ uptr->gpg_key,
+ strlen(uptr->gpg_key), 0));
+ fail_if_err(gpgme_op_import(ctx, key_data));
+ res = gpgme_op_import_result(ctx);
+ pstat = res->imports;
+ uptr->fpr = grecs_strdup(pstat->fpr);
+ if (debug_level > 2)
+ logmsg(LOG_DEBUG,
+ _("imported key: user = %s, fingerprint = %s"),
+ uptr->name, uptr->fpr);
}
- else
- rc = 0;
- }
- else
- {
- rc = 1;
- UPDATE_STATS (STAT_BAD_SIGNATURE);
- logmsg (LOG_ERR, _("%s: directive verification failed: %s"),
- trp->name, gpgme_strerror (ec));
- }
-
- gpgme_data_release (plain);
- gpgme_data_release (directive_data);
- gpgme_data_release (key_data);
- gpgme_release (ctx);
-
- return rc;
+
+ fail_if_err(gpgme_data_new_from_file(&directive_data,
+ trp->file[file_directive].name,
+ 1));
+ gpgme_data_new(&plain);
+ ec = gpgme_op_verify(ctx, directive_data, NULL, plain);
+ if (ec == GPG_ERR_NO_ERROR) {
+ gpgme_verify_result_t result;
+
+ result = gpgme_op_verify_result(ctx);
+ if (!gpg_verify_signature(ctx, result->signatures, trp)) {
+ UPDATE_STATS(STAT_BAD_SIGNATURE);
+ notify(trp->spool->notification, trp,
+ ev_bad_directive_signature);
+ rc = 1;
+ } else
+ rc = 0;
+ } else {
+ rc = 1;
+ UPDATE_STATS(STAT_BAD_SIGNATURE);
+ logmsg(LOG_ERR, _("%s: directive verification failed: %s"),
+ trp->name, gpgme_strerror(ec));
+ }
+
+ gpgme_data_release(plain);
+ gpgme_data_release(directive_data);
+ gpgme_data_release(key_data);
+ gpgme_release(ctx);
+
+ return rc;
}
/* Verify the detached signature of TRP.
NOTE: It is assumed that the public key is already registered (by
a previous call to verify_directive_signature). */
int
-verify_detached_signature (struct file_triplet *trp)
+verify_detached_signature(struct file_triplet *trp)
{
- gpgme_engine_info_t info;
- const char *argv[5];
- const struct spool *spool;
-
- ASGN_SPOOL (spool, trp, return 1);
-
- fail_if_err (gpgme_get_engine_info (&info));
- while (info && info->protocol != GPGME_PROTOCOL_OpenPGP)
- info = info->next;
- if (!info)
- {
- logmsg (LOG_CRIT,
- _("cannot find path to gpg binary (attempting to verify "
- "the detached signature for %s"), trp->name);
- return 1;
- }
-
- create_gpg_homedir ();
- argv[0] = info->file_name;
- argv[1] = "--verify";
- argv[2] = trp->file[file_signature].name;
- argv[3] = trp->file[file_dist].name;
- argv[4] = NULL;
-
- switch (wydawca_exec (5, argv, NULL))
- {
- case exec_success:
- if (debug_level)
- logmsg (LOG_DEBUG, _("good detached signature for %s"), trp->name);
- return 0;
-
- case exec_fail:
- UPDATE_STATS (STAT_BAD_SIGNATURE);
- logmsg (LOG_ERR, _("BAD detached signature for %s"), trp->name);
- notify (spool->notification, trp, ev_bad_detached_signature);
- break;
-
- case exec_error:
- logmsg (LOG_CRIT, _("cannot verify detached signature for %s"),
- trp->name);
- break;
- }
-
- return 1;
+ gpgme_engine_info_t info;
+ const char *argv[5];
+ const struct spool *spool;
+
+ ASGN_SPOOL(spool, trp, return 1);
+
+ fail_if_err(gpgme_get_engine_info(&info));
+ while (info && info->protocol != GPGME_PROTOCOL_OpenPGP)
+ info = info->next;
+ if (!info) {
+ logmsg(LOG_CRIT,
+ _("cannot find path to gpg binary (attempting to "
+ "verify the detached signature for %s"), trp->name);
+ return 1;
+ }
+
+ create_gpg_homedir();
+ argv[0] = info->file_name;
+ argv[1] = "--verify";
+ argv[2] = trp->file[file_signature].name;
+ argv[3] = trp->file[file_dist].name;
+ argv[4] = NULL;
+
+ switch (wydawca_exec(5, argv, NULL)) {
+ case exec_success:
+ if (debug_level)
+ logmsg(LOG_DEBUG, _("good detached signature for %s"),
+ trp->name);
+ return 0;
+
+ case exec_fail:
+ UPDATE_STATS(STAT_BAD_SIGNATURE);
+ logmsg(LOG_ERR, _("BAD detached signature for %s"), trp->name);
+ notify(spool->notification, trp, ev_bad_detached_signature);
+ break;
+
+ case exec_error:
+ logmsg(LOG_CRIT, _("cannot verify detached signature for %s"),
+ trp->name);
+ break;
+ }
+
+ return 1;
}

Return to:

Send suggestions and report system problems to the System administrator.