signing: let GPGME handle loading signatures from files

Rather than go through all the hassle of doing this ourselves, just let
GPGME handle the work by passing it a file handle.

Signed-off-by: Dan McGee <dan@archlinux.org>
This commit is contained in:
Dan McGee 2011-04-21 19:01:06 -05:00
parent a7d33d0c36
commit 31e55b8049
5 changed files with 35 additions and 92 deletions

View file

@ -243,18 +243,12 @@ static pmpkg_t *pkg_load(const char *pkgfile, int full)
/* attempt to stat the package file, ensure it exists */
if(stat(pkgfile, &st) == 0) {
int sig_ret;
newpkg = _alpm_pkg_new();
if(newpkg == NULL) {
RET_ERR(PM_ERR_MEMORY, NULL);
}
newpkg->filename = strdup(pkgfile);
newpkg->size = st.st_size;
/* TODO: do something with ret value */
sig_ret = _alpm_load_signature(pkgfile, &(newpkg->pgpsig));
(void)sig_ret;
} else {
/* couldn't stat the pkgfile, return an error */
RET_ERR(PM_ERR_PKG_OPEN, NULL);

View file

@ -314,27 +314,6 @@ pmdb_t *_alpm_db_new(const char *treename, int is_local)
return db;
}
const pmpgpsig_t *_alpm_db_pgpsig(pmdb_t *db)
{
ALPM_LOG_FUNC;
/* Sanity checks */
ASSERT(db != NULL, return(NULL));
if(db->pgpsig.data == NULL) {
const char *dbfile;
int ret;
dbfile = _alpm_db_path(db);
/* TODO: do something with ret value */
ret = _alpm_load_signature(dbfile, &(db->pgpsig));
(void)ret;
}
return &(db->pgpsig);
}
void _alpm_db_free(pmdb_t *db)
{
ALPM_LOG_FUNC;
@ -343,8 +322,6 @@ void _alpm_db_free(pmdb_t *db)
_alpm_db_free_pkgcache(db);
/* cleanup server list */
FREELIST(db->servers);
/* only need to free data */
FREE(db->pgpsig.data);
FREE(db->_path);
FREE(db->treename);
FREE(db);

View file

@ -63,8 +63,6 @@ struct __pmdb_t {
pmpkghash_t *pkgcache;
alpm_list_t *grpcache;
alpm_list_t *servers;
/* do not access directly, use _alpm_db_pgpsig(db) for lazy access */
pmpgpsig_t pgpsig;
pgp_verify_t pgp_verify;
struct db_operations *ops;
@ -81,7 +79,6 @@ alpm_list_t *_alpm_db_search(pmdb_t *db, const alpm_list_t *needles);
pmdb_t *_alpm_db_register_local(void);
pmdb_t *_alpm_db_register_sync(const char *treename);
void _alpm_db_unregister(pmdb_t *db);
const pmpgpsig_t *_alpm_db_pgpsig(pmdb_t *db);
/* be_*.c, backend specific calls */
int _alpm_local_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq);

View file

@ -92,9 +92,10 @@ error:
}
/**
* Check the PGP package signature for the given file.
* Check the PGP signature for the given file.
* @param path the full path to a file
* @param sig PGP signature data in raw form (already decoded)
* @param sig PGP signature data in raw form (already decoded); if NULL, expect
* a signature file next to 'path'
* @return a int value : 0 (valid), 1 (invalid), -1 (an error occured)
*/
int _alpm_gpgme_checksig(const char *path, const pmpgpsig_t *sig)
@ -105,16 +106,28 @@ int _alpm_gpgme_checksig(const char *path, const pmpgpsig_t *sig)
gpgme_data_t filedata, sigdata;
gpgme_verify_result_t result;
gpgme_signature_t gpgsig;
char *sigpath = NULL;
FILE *file = NULL, *sigfile = NULL;
ALPM_LOG_FUNC;
if(!sig || !sig->data) {
RET_ERR(PM_ERR_SIG_UNKNOWN, -1);
}
if(!path || access(path, R_OK) != 0) {
RET_ERR(PM_ERR_NOT_A_FILE, -1);
}
if(!sig) {
size_t len = strlen(path) + 5;
CALLOC(sigpath, len, sizeof(char), RET_ERR(PM_ERR_MEMORY, -1));
snprintf(sigpath, len, "%s.sig", path);
if(!access(sigpath, R_OK) == 0) {
FREE(sigpath);
RET_ERR(PM_ERR_SIG_UNKNOWN, -1);
}
} else if(!sig->data) {
RET_ERR(PM_ERR_SIG_UNKNOWN, -1);
}
if(gpgme_init()) {
/* pm_errno was set in gpgme_init() */
return -1;
@ -140,7 +153,19 @@ int _alpm_gpgme_checksig(const char *path, const pmpgpsig_t *sig)
CHECK_ERR();
/* next create data object for the signature */
err = gpgme_data_new_from_mem(&sigdata, (char *)sig->data, sig->len, 0);
if(sig) {
/* memory-based, we loaded it from a sync DB */
err = gpgme_data_new_from_mem(&sigdata, (char *)sig->data, sig->len, 0);
} else {
/* file-based, it is on disk */
sigfile = fopen(sigpath, "rb");
if(sigfile == NULL) {
pm_errno = PM_ERR_NOT_A_FILE;
ret = -1;
goto error;
}
err = gpgme_data_new_from_stream(&sigdata, sigfile);
}
CHECK_ERR();
/* here's where the magic happens */
@ -196,6 +221,7 @@ error:
if(file) {
fclose(file);
}
FREE(sigpath);
if(err != GPG_ERR_NO_ERROR) {
_alpm_log(PM_LOG_ERROR, _("GPGME error: %s\n"), gpgme_strerror(err));
RET_ERR(PM_ERR_GPGME, -1);
@ -203,55 +229,6 @@ error:
return ret;
}
/**
* Load the signature from the given path into the provided struct.
* @param sigfile the signature to attempt to load
* @param pgpsig the struct to place the data in
*
* @return 0 on success, 1 on file not found, -1 on error
*/
int _alpm_load_signature(const char *file, pmpgpsig_t *pgpsig) {
struct stat st;
char *sigfile;
int ret = -1;
/* look around for a PGP signature file; load if available */
MALLOC(sigfile, strlen(file) + 5, RET_ERR(PM_ERR_MEMORY, -1));
sprintf(sigfile, "%s.sig", file);
if(access(sigfile, R_OK) == 0 && stat(sigfile, &st) == 0) {
FILE *f;
size_t bytes_read;
if(st.st_size > 4096 || (f = fopen(sigfile, "rb")) == NULL) {
free(sigfile);
return ret;
}
CALLOC(pgpsig->data, st.st_size, sizeof(unsigned char),
RET_ERR(PM_ERR_MEMORY, -1));
bytes_read = fread(pgpsig->data, sizeof(char), st.st_size, f);
if(bytes_read == (size_t)st.st_size) {
pgpsig->len = bytes_read;
_alpm_log(PM_LOG_DEBUG, "loaded gpg signature file, location %s\n",
sigfile);
ret = 0;
} else {
_alpm_log(PM_LOG_WARNING, _("Failed reading PGP signature file %s"),
sigfile);
FREE(pgpsig->data);
}
fclose(f);
} else {
_alpm_log(PM_LOG_DEBUG, "signature file %s not found\n", sigfile);
/* not fatal...we return a different error code here */
ret = 1;
}
free(sigfile);
return ret;
}
/**
* Determines the necessity of checking for a valid PGP signature
* @param db the sync database to query
@ -271,7 +248,7 @@ pgp_verify_t _alpm_db_get_sigverify_level(pmdb_t *db)
}
/**
* Check the PGP package signature for the given package file.
* Check the PGP signature for the given package file.
* @param pkg the package to check
* @return a int value : 0 (valid), 1 (invalid), -1 (an error occurred)
*/
@ -285,7 +262,7 @@ int SYMEXPORT alpm_pkg_check_pgp_signature(pmpkg_t *pkg)
}
/**
* Check the PGP package signature for the given database.
* Check the PGP signature for the given database.
* @param db the database to check
* @return a int value : 0 (valid), 1 (invalid), -1 (an error occurred)
*/
@ -294,8 +271,7 @@ int SYMEXPORT alpm_db_check_pgp_signature(pmdb_t *db)
ALPM_LOG_FUNC;
ASSERT(db != NULL, return 0);
return _alpm_gpgme_checksig(_alpm_db_path(db),
_alpm_db_pgpsig(db));
return _alpm_gpgme_checksig(_alpm_db_path(db), NULL);
}
/* vim: set ts=2 sw=2 noet: */

View file

@ -32,7 +32,6 @@ struct __pmpgpsig_t {
};
int _alpm_gpgme_checksig(const char *path, const pmpgpsig_t *sig);
int _alpm_load_signature(const char *sigfile, pmpgpsig_t *pgpsig);
pgp_verify_t _alpm_db_get_sigverify_level(pmdb_t *db);
#endif /* _ALPM_SIGNING_H */