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 */
|
/* attempt to stat the package file, ensure it exists */
|
||||||
if(stat(pkgfile, &st) == 0) {
|
if(stat(pkgfile, &st) == 0) {
|
||||||
int sig_ret;
|
|
||||||
|
|
||||||
newpkg = _alpm_pkg_new();
|
newpkg = _alpm_pkg_new();
|
||||||
if(newpkg == NULL) {
|
if(newpkg == NULL) {
|
||||||
RET_ERR(PM_ERR_MEMORY, NULL);
|
RET_ERR(PM_ERR_MEMORY, NULL);
|
||||||
}
|
}
|
||||||
newpkg->filename = strdup(pkgfile);
|
newpkg->filename = strdup(pkgfile);
|
||||||
newpkg->size = st.st_size;
|
newpkg->size = st.st_size;
|
||||||
|
|
||||||
/* TODO: do something with ret value */
|
|
||||||
sig_ret = _alpm_load_signature(pkgfile, &(newpkg->pgpsig));
|
|
||||||
(void)sig_ret;
|
|
||||||
} else {
|
} else {
|
||||||
/* couldn't stat the pkgfile, return an error */
|
/* couldn't stat the pkgfile, return an error */
|
||||||
RET_ERR(PM_ERR_PKG_OPEN, NULL);
|
RET_ERR(PM_ERR_PKG_OPEN, NULL);
|
||||||
|
|
|
@ -314,27 +314,6 @@ pmdb_t *_alpm_db_new(const char *treename, int is_local)
|
||||||
return db;
|
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)
|
void _alpm_db_free(pmdb_t *db)
|
||||||
{
|
{
|
||||||
ALPM_LOG_FUNC;
|
ALPM_LOG_FUNC;
|
||||||
|
@ -343,8 +322,6 @@ void _alpm_db_free(pmdb_t *db)
|
||||||
_alpm_db_free_pkgcache(db);
|
_alpm_db_free_pkgcache(db);
|
||||||
/* cleanup server list */
|
/* cleanup server list */
|
||||||
FREELIST(db->servers);
|
FREELIST(db->servers);
|
||||||
/* only need to free data */
|
|
||||||
FREE(db->pgpsig.data);
|
|
||||||
FREE(db->_path);
|
FREE(db->_path);
|
||||||
FREE(db->treename);
|
FREE(db->treename);
|
||||||
FREE(db);
|
FREE(db);
|
||||||
|
|
|
@ -63,8 +63,6 @@ struct __pmdb_t {
|
||||||
pmpkghash_t *pkgcache;
|
pmpkghash_t *pkgcache;
|
||||||
alpm_list_t *grpcache;
|
alpm_list_t *grpcache;
|
||||||
alpm_list_t *servers;
|
alpm_list_t *servers;
|
||||||
/* do not access directly, use _alpm_db_pgpsig(db) for lazy access */
|
|
||||||
pmpgpsig_t pgpsig;
|
|
||||||
pgp_verify_t pgp_verify;
|
pgp_verify_t pgp_verify;
|
||||||
|
|
||||||
struct db_operations *ops;
|
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_local(void);
|
||||||
pmdb_t *_alpm_db_register_sync(const char *treename);
|
pmdb_t *_alpm_db_register_sync(const char *treename);
|
||||||
void _alpm_db_unregister(pmdb_t *db);
|
void _alpm_db_unregister(pmdb_t *db);
|
||||||
const pmpgpsig_t *_alpm_db_pgpsig(pmdb_t *db);
|
|
||||||
|
|
||||||
/* be_*.c, backend specific calls */
|
/* be_*.c, backend specific calls */
|
||||||
int _alpm_local_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq);
|
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 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)
|
* @return a int value : 0 (valid), 1 (invalid), -1 (an error occured)
|
||||||
*/
|
*/
|
||||||
int _alpm_gpgme_checksig(const char *path, const pmpgpsig_t *sig)
|
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_data_t filedata, sigdata;
|
||||||
gpgme_verify_result_t result;
|
gpgme_verify_result_t result;
|
||||||
gpgme_signature_t gpgsig;
|
gpgme_signature_t gpgsig;
|
||||||
|
char *sigpath = NULL;
|
||||||
FILE *file = NULL, *sigfile = NULL;
|
FILE *file = NULL, *sigfile = NULL;
|
||||||
|
|
||||||
ALPM_LOG_FUNC;
|
ALPM_LOG_FUNC;
|
||||||
|
|
||||||
if(!sig || !sig->data) {
|
|
||||||
RET_ERR(PM_ERR_SIG_UNKNOWN, -1);
|
|
||||||
}
|
|
||||||
if(!path || access(path, R_OK) != 0) {
|
if(!path || access(path, R_OK) != 0) {
|
||||||
RET_ERR(PM_ERR_NOT_A_FILE, -1);
|
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()) {
|
if(gpgme_init()) {
|
||||||
/* pm_errno was set in gpgme_init() */
|
/* pm_errno was set in gpgme_init() */
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -140,7 +153,19 @@ int _alpm_gpgme_checksig(const char *path, const pmpgpsig_t *sig)
|
||||||
CHECK_ERR();
|
CHECK_ERR();
|
||||||
|
|
||||||
/* next create data object for the signature */
|
/* next create data object for the signature */
|
||||||
|
if(sig) {
|
||||||
|
/* memory-based, we loaded it from a sync DB */
|
||||||
err = gpgme_data_new_from_mem(&sigdata, (char *)sig->data, sig->len, 0);
|
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();
|
CHECK_ERR();
|
||||||
|
|
||||||
/* here's where the magic happens */
|
/* here's where the magic happens */
|
||||||
|
@ -196,6 +221,7 @@ error:
|
||||||
if(file) {
|
if(file) {
|
||||||
fclose(file);
|
fclose(file);
|
||||||
}
|
}
|
||||||
|
FREE(sigpath);
|
||||||
if(err != GPG_ERR_NO_ERROR) {
|
if(err != GPG_ERR_NO_ERROR) {
|
||||||
_alpm_log(PM_LOG_ERROR, _("GPGME error: %s\n"), gpgme_strerror(err));
|
_alpm_log(PM_LOG_ERROR, _("GPGME error: %s\n"), gpgme_strerror(err));
|
||||||
RET_ERR(PM_ERR_GPGME, -1);
|
RET_ERR(PM_ERR_GPGME, -1);
|
||||||
|
@ -203,55 +229,6 @@ error:
|
||||||
return ret;
|
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
|
* Determines the necessity of checking for a valid PGP signature
|
||||||
* @param db the sync database to query
|
* @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
|
* @param pkg the package to check
|
||||||
* @return a int value : 0 (valid), 1 (invalid), -1 (an error occurred)
|
* @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
|
* @param db the database to check
|
||||||
* @return a int value : 0 (valid), 1 (invalid), -1 (an error occurred)
|
* @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;
|
ALPM_LOG_FUNC;
|
||||||
ASSERT(db != NULL, return 0);
|
ASSERT(db != NULL, return 0);
|
||||||
|
|
||||||
return _alpm_gpgme_checksig(_alpm_db_path(db),
|
return _alpm_gpgme_checksig(_alpm_db_path(db), NULL);
|
||||||
_alpm_db_pgpsig(db));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* vim: set ts=2 sw=2 noet: */
|
/* 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_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);
|
pgp_verify_t _alpm_db_get_sigverify_level(pmdb_t *db);
|
||||||
|
|
||||||
#endif /* _ALPM_SIGNING_H */
|
#endif /* _ALPM_SIGNING_H */
|
||||||
|
|
Loading…
Add table
Reference in a new issue