diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2007-08-23 16:17:47 +0000 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2007-08-23 16:17:47 +0000 |
commit | 766d41f8bf91a6d209c66e8fd12dbd6688ce2739 (patch) | |
tree | 12552a0788d42ac73e7260b883aa84a8045e957a /src/gpg.c | |
parent | c7e791e9563b7805fc7a375bc7e616b4252a9c57 (diff) | |
download | wydawca-766d41f8bf91a6d209c66e8fd12dbd6688ce2739.tar.gz wydawca-766d41f8bf91a6d209c66e8fd12dbd6688ce2739.tar.bz2 |
Improve safety checks; implement symlink/rmsymlink/archive directives; Fix directive signature verification.
git-svn-id: file:///svnroot/wydawca/trunk@286 6bb4bd81-ecc2-4fd4-a2d4-9571d19c0d33
Diffstat (limited to 'src/gpg.c')
-rw-r--r-- | src/gpg.c | 80 |
1 files changed, 70 insertions, 10 deletions
@@ -1,7 +1,7 @@ -/* wydawca - FTP release synchronisation daemon +/* wydawca - FTP release synchronization daemon Copyright (C) 2007 Sergey Poznyakoff This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. @@ -144,12 +144,63 @@ wydawca_gpg_homedir () if (debug_level > 1) logmsg (LOG_DEBUG, "GNUPG home directory: %s", homedir); setenv ("GNUPGHOME", homedir, 1); return 0; } +static int +gpg_sig_ok_p (gpgme_ctx_t ctx, gpgme_signature_t sig) +{ + if (!sig) + return 0; + + for (; sig; sig = sig->next) + { + const char *uid; + gpgme_key_t key; + + if (gpgme_get_key (ctx, sig->fpr, &key, 0) == GPG_ERR_NO_ERROR) + uid = key->uids->uid; + else + uid = sig->fpr; + + switch (gpg_err_code (sig->status)) + { + case GPG_ERR_NO_ERROR: + if (debug_level) + logmsg (LOG_NOTICE, "Good signature from %s", uid); + break; + + case GPG_ERR_BAD_SIGNATURE: + logmsg (LOG_ERR, "BAD signature from %s", uid); + return 0; + + case GPG_ERR_NO_PUBKEY: + logmsg (LOG_ERR, "No public key"); + return 0; + + case GPG_ERR_NO_DATA: + logmsg (LOG_ERR, "No signature"); + return 0; + + case GPG_ERR_SIG_EXPIRED: + logmsg (LOG_ERR, "Expired signature from %s", uid); + return 0; + + case GPG_ERR_KEY_EXPIRED: + logmsg (LOG_ERR, "Key expired (%s)", uid); + return 0; + + default: + logmsg (LOG_ERR, "Unknown signature error"); + return 0; + } + } + return 1; +} + /* Verify the directive file from TRP using public key PUBKEY */ /* FIXME: dpair currently unused */ int verify_directive_signature (struct file_triplet *trp, struct directory_pair *dpair, const char *pubkey) { @@ -168,20 +219,29 @@ verify_directive_signature (struct file_triplet *trp, 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) { - size = gpgme_data_seek (plain, 0, SEEK_END); - gpgme_data_seek (plain, 0, SEEK_SET); - trp->blurb = xmalloc (size + 1); - gpgme_data_read (plain, trp->blurb, size); - trp->blurb[size] = 0; - gpgme_data_release (plain); - - rc = directive_parse (trp); + gpgme_verify_result_t result; + gpgme_signature_t sig; + + result = gpgme_op_verify_result (ctx); + if (gpg_sig_ok_p (ctx, result->signatures)) + { + size = gpgme_data_seek (plain, 0, SEEK_END); + gpgme_data_seek (plain, 0, SEEK_SET); + trp->blurb = xmalloc (size + 1); + gpgme_data_read (plain, trp->blurb, size); + trp->blurb[size] = 0; + gpgme_data_release (plain); + + rc = directive_parse (trp); + } + else + rc = 1; } else { rc = 1; logmsg (LOG_ERR, "%s: directive verification failed: %s", trp->name, gpgme_strerror (ec)); @@ -227,13 +287,13 @@ verify_detached_signature (struct file_triplet *trp, case exec_success: if (debug_level) logmsg (LOG_DEBUG, "good detached signature for %s", trp->name); return 0; case exec_fail: - logmsg (LOG_ERR, "bad detached signature for %s", trp->name); + logmsg (LOG_ERR, "BAD detached signature for %s", trp->name); break; case exec_error: logmsg (LOG_CRIT, "cannot verify detached signature for %s", trp->name); break; } |