* add _alpm_get_sigverify_level * add alpm_option_{get,set}_default_sigverify This requires moving around protos in alpm.h so that pgp_verify_t is known to the get/set methods for default_sigverify. Signed-off-by: Dave Reisner <d@falconindy.com> --- lib/libalpm/alpm.h | 36 ++++++++++++++++++++---------------- lib/libalpm/be_sync.c | 2 +- lib/libalpm/handle.c | 12 ++++++++++++ lib/libalpm/handle.h | 11 ++++++----- lib/libalpm/signing.c | 21 +++++++++++++++++++-- lib/libalpm/signing.h | 1 + lib/libalpm/sync.c | 17 ++++++++++++++--- src/pacman/pacman.c | 20 ++++++++++++++++---- 8 files changed, 89 insertions(+), 31 deletions(-) diff --git a/lib/libalpm/alpm.h b/lib/libalpm/alpm.h index 43ff4ba..8d97aac 100644 --- a/lib/libalpm/alpm.h +++ b/lib/libalpm/alpm.h @@ -95,6 +95,23 @@ typedef int (*alpm_cb_fetch)(const char *url, const char *localpath, int force); /* + * Signatures + */ + +int alpm_pkg_check_pgp_signature(pmpkg_t *pkg); +int alpm_db_check_pgp_signature(pmdb_t *db); + +/* GPG signature verification option */ +typedef enum _pgp_verify_t { + PM_PGP_VERIFY_UNKNOWN, + PM_PGP_VERIFY_ALWAYS, + PM_PGP_VERIFY_OPTIONAL, + PM_PGP_VERIFY_NEVER +} pgp_verify_t; + +int alpm_db_set_pgp_verify(pmdb_t *db, pgp_verify_t verify); + +/* * Options */ @@ -168,6 +185,9 @@ alpm_list_t *alpm_option_get_syncdbs(void); const char *alpm_option_get_useragent(void); void alpm_option_set_useragent(char *useragent); +pgp_verify_t alpm_option_get_default_sigverify(void); +void alpm_option_set_default_sigverify(pgp_verify_t level); + /* * Install reasons -- ie, why the package was installed */ @@ -249,22 +269,6 @@ off_t alpm_pkg_download_size(pmpkg_t *newpkg); alpm_list_t *alpm_pkg_unused_deltas(pmpkg_t *pkg); /* - * Signatures - */ - -int alpm_pkg_check_pgp_signature(pmpkg_t *pkg); -int alpm_db_check_pgp_signature(pmdb_t *db); - -/* GPG signature verification option */ -typedef enum _pgp_verify_t { - PM_PGP_VERIFY_ALWAYS, - PM_PGP_VERIFY_OPTIONAL, - PM_PGP_VERIFY_NEVER -} pgp_verify_t; - -int alpm_db_set_pgp_verify(pmdb_t *db, pgp_verify_t verify); - -/* * Deltas */ diff --git a/lib/libalpm/be_sync.c b/lib/libalpm/be_sync.c index ce62c2b..4c1201a 100644 --- a/lib/libalpm/be_sync.c +++ b/lib/libalpm/be_sync.c @@ -127,7 +127,7 @@ int SYMEXPORT alpm_db_update(int force, pmdb_t *db) CALLOC(fileurl, len, sizeof(char), RET_ERR(PM_ERR_MEMORY, -1)); snprintf(fileurl, len, "%s/%s.db", server, db->treename); - ret = _alpm_download(fileurl, syncpath, force, db->pgp_verify); + ret = _alpm_download(fileurl, syncpath, force, _alpm_get_sigverify_level(db)); FREE(fileurl); if(ret != -1) { break; diff --git a/lib/libalpm/handle.c b/lib/libalpm/handle.c index df4ed54..d211f16 100644 --- a/lib/libalpm/handle.c +++ b/lib/libalpm/handle.c @@ -50,6 +50,8 @@ pmhandle_t *_alpm_handle_new() CALLOC(handle, 1, sizeof(pmhandle_t), RET_ERR(PM_ERR_MEMORY, NULL)); + handle->sigverify = PM_PGP_VERIFY_ALWAYS; + return handle; } @@ -612,4 +614,14 @@ const char SYMEXPORT *alpm_option_get_useragent() return handle->useragent; } +void SYMEXPORT alpm_option_set_default_sigverify(pgp_verify_t level) +{ + handle->sigverify = level; +} + +pgp_verify_t SYMEXPORT alpm_option_get_default_sigverify() +{ + return handle->sigverify; +} + /* vim: set ts=2 sw=2 noet: */ diff --git a/lib/libalpm/handle.h b/lib/libalpm/handle.h index 2a0bcd4..74c2e8e 100644 --- a/lib/libalpm/handle.h +++ b/lib/libalpm/handle.h @@ -68,11 +68,12 @@ typedef struct _pmhandle_t { alpm_list_t *ignoregrp; /* List of groups to ignore */ /* options */ - int usesyslog; /* Use syslog instead of logfile? */ /* TODO move to frontend */ - char *arch; /* Architecture of packages we should allow */ - int usedelta; /* Download deltas if possible */ - int checkspace; /* Check disk space before installing */ - char *useragent; /* User agent string to set for internal downloader */ + int usesyslog; /* Use syslog instead of logfile? */ /* TODO move to frontend */ + char *arch; /* Architecture of packages we should allow */ + int usedelta; /* Download deltas if possible */ + int checkspace; /* Check disk space before installing */ + char *useragent; /* User agent string to set for internal downloader */ + pgp_verify_t sigverify; /* Default signature verification level */ } pmhandle_t; /* global handle variable */ diff --git a/lib/libalpm/signing.c b/lib/libalpm/signing.c index c30650b..bedf3bf 100644 --- a/lib/libalpm/signing.c +++ b/lib/libalpm/signing.c @@ -249,6 +249,24 @@ int _alpm_load_signature(const char *sigfile, pmpgpsig_t *pgpsig) { } /** + * Determines the necessity of checking for a valid pgp signature + * @param db the sync db to query + * + * @return signature verification level + */ +pgp_verify_t _alpm_get_sigverify_level(pmdb_t *db) +{ + ALPM_LOG_FUNC; + ASSERT(db != NULL, return PM_PGP_VERIFY_UNKNOWN); + + if(db->pgp_verify != PM_PGP_VERIFY_UNKNOWN) { + return db->pgp_verify; + } else { + return alpm_option_get_default_sigverify(); + } +} + +/** * Check the PGP package signature for the given package file. * @param pkg the package to check * @return a int value : 0 (valid), 1 (invalid), -1 (an error occured) @@ -270,11 +288,10 @@ int SYMEXPORT alpm_pkg_check_pgp_signature(pmpkg_t *pkg) int SYMEXPORT alpm_db_check_pgp_signature(pmdb_t *db) { ALPM_LOG_FUNC; - ASSERT(db != NULL, return(0)); + ASSERT(db != NULL, return 0); return _alpm_gpgme_checksig(_alpm_db_path(db), _alpm_db_pgpsig(db)); } - /* vim: set ts=2 sw=2 noet: */ diff --git a/lib/libalpm/signing.h b/lib/libalpm/signing.h index b37abf0..d4b55de 100644 --- a/lib/libalpm/signing.h +++ b/lib/libalpm/signing.h @@ -31,6 +31,7 @@ struct __pmpgpsig_t { unsigned char *rawdata; }; +pgp_verify_t _alpm_get_sigverify_level(pmdb_t *db); int _alpm_gpgme_checksig(const char *path, const pmpgpsig_t *sig); int _alpm_load_signature(const char *sigfile, pmpgpsig_t *pgpsig); diff --git a/lib/libalpm/sync.c b/lib/libalpm/sync.c index bd4d8e9..2c0e54b 100644 --- a/lib/libalpm/sync.c +++ b/lib/libalpm/sync.c @@ -857,6 +857,7 @@ int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t **data) char *filepath = _alpm_filecache_find(filename); const char *md5sum = alpm_pkg_get_md5sum(spkg); const pmpgpsig_t *pgpsig = alpm_pkg_get_pgpsig(spkg); + pgp_verify_t check_sig; /* check md5sum first */ if(test_md5sum(trans, filepath, md5sum) != 0) { @@ -868,10 +869,20 @@ int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t **data) /* check PGP signature next */ pmdb_t *sdb = alpm_pkg_get_db(spkg); - if(sdb->pgp_verify != PM_PGP_VERIFY_NEVER) { + check_sig = _alpm_get_sigverify_level(sdb); + + /* fprintf(stderr, "check_sig for %s = %d\n", sdb->treename, check_sig); */ + + if(check_sig == PM_PGP_VERIFY_UNKNOWN) { + _alpm_log(PM_LOG_ERROR, "failed to determine signature verification level " + "for db: %s\n", sdb->treename); + goto error; + } + + if(check_sig != PM_PGP_VERIFY_NEVER) { int ret = _alpm_gpgme_checksig(filepath, pgpsig); - if((sdb->pgp_verify == PM_PGP_VERIFY_ALWAYS && ret != 0) || - (sdb->pgp_verify == PM_PGP_VERIFY_OPTIONAL && ret == 1)) { + if((check_sig == PM_PGP_VERIFY_ALWAYS && ret != 0) || + (check_sig == PM_PGP_VERIFY_OPTIONAL && ret == 1)) { errors++; *data = alpm_list_add(*data, strdup(filename)); FREE(filepath); diff --git a/src/pacman/pacman.c b/src/pacman/pacman.c index 381d2bc..012043d 100644 --- a/src/pacman/pacman.c +++ b/src/pacman/pacman.c @@ -1038,22 +1038,34 @@ static int _parse_options(const char *key, char *value, config->rootdir = strdup(value); pm_printf(PM_LOG_DEBUG, "config: rootdir: %s\n", value); } - } else if (strcmp(key, "GPGDir") == 0) { + } else if(strcmp(key, "GPGDir") == 0) { if(!config->gpgdir) { config->gpgdir = strdup(value); pm_printf(PM_LOG_DEBUG, "config: gpgdir: %s\n", value); } - } else if (strcmp(key, "LogFile") == 0) { + } else if(strcmp(key, "LogFile") == 0) { if(!config->logfile) { config->logfile = strdup(value); pm_printf(PM_LOG_DEBUG, "config: logfile: %s\n", value); } - } else if (strcmp(key, "XferCommand") == 0) { + } else if(strcmp(key, "XferCommand") == 0) { config->xfercommand = strdup(value); alpm_option_set_fetchcb(download_with_xfercommand); pm_printf(PM_LOG_DEBUG, "config: xfercommand: %s\n", value); - } else if (strcmp(key, "CleanMethod") == 0) { + } else if(strcmp(key, "CleanMethod") == 0) { setrepeatingoption(value, "CleanMethod", option_add_cleanmethod); + } else if(strcmp(key, "VerifySig") == 0) { + if (strcmp(value, "Always") == 0) { + alpm_option_set_default_sigverify(PM_PGP_VERIFY_ALWAYS); + } else if(strcmp(value, "Optional") == 0) { + alpm_option_set_default_sigverify(PM_PGP_VERIFY_OPTIONAL); + } else if(strcmp(value, "Never") == 0) { + alpm_option_set_default_sigverify(PM_PGP_VERIFY_NEVER); + } else { + pm_printf(PM_LOG_ERROR, _("invalid value for 'VerifySig' : '%s'\n"), value); + return 1; + } + pm_printf(PM_LOG_DEBUG, "config: setting default VerifySig: %s\n", value); } else { pm_printf(PM_LOG_WARNING, -- 1.7.4.2