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:
parent
a7d33d0c36
commit
31e55b8049
5 changed files with 35 additions and 92 deletions
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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: */
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Add table
Reference in a new issue