Check keys are in keyring before package validation

Keys used to create signatures are checked for presence in the keyring
before package validation is performed.

Signed-off-by: Allan McRae <allan@archlinux.org>

Conflicts:
	lib/libalpm/alpm.h

Signed-off-by: Allan McRae <allan@archlinux.org>
This commit is contained in:
Allan McRae 2012-11-03 00:21:48 +10:00
parent 198154962b
commit 31b9b264c1
3 changed files with 101 additions and 2 deletions

View File

@ -361,7 +361,15 @@ typedef enum _alpm_event_t {
* The requiring package and its dependency are passed to the callback */
ALPM_EVENT_OPTDEP_REQUIRED,
/** A configured repository database is missing */
ALPM_EVENT_DATABASE_MISSING
ALPM_EVENT_DATABASE_MISSING,
/** Checking keys used to create signatures are in keyring. */
ALPM_EVENT_KEYRING_START,
/** Keyring checking is finished. */
ALPM_EVENT_KEYRING_DONE,
/** Downloading missing keys into keyring. */
ALPM_EVENT_KEY_DOWNLOAD_START,
/** Key downloading is finished. */
ALPM_EVENT_KEY_DOWNLOAD_DONE
} alpm_event_t;
/** Event callback */
@ -395,7 +403,8 @@ typedef enum _alpm_progress_t {
ALPM_PROGRESS_CONFLICTS_START,
ALPM_PROGRESS_DISKSPACE_START,
ALPM_PROGRESS_INTEGRITY_START,
ALPM_PROGRESS_LOAD_START
ALPM_PROGRESS_LOAD_START,
ALPM_PROGRESS_KEYRING_START
} alpm_progress_t;
/** Progress callback */

View File

@ -969,6 +969,76 @@ finish:
return errors;
}
static int check_keyring(alpm_handle_t *handle)
{
size_t current = 0, numtargs;
alpm_list_t *i, *errors = NULL;
EVENT(handle, ALPM_EVENT_KEYRING_START, NULL, NULL);
numtargs = alpm_list_count(handle->trans->add);
for(i = handle->trans->add; i; i = i->next, current++) {
alpm_pkg_t *pkg = i->data;
alpm_siglevel_t level;
int percent = (current * 100) / numtargs;
PROGRESS(handle, ALPM_PROGRESS_KEYRING_START, "", percent,
numtargs, current);
if(pkg->origin == ALPM_PKG_FROM_FILE) {
continue; /* pkg_load() has been already called, this package is valid */
}
level = alpm_db_get_siglevel(alpm_pkg_get_db(pkg));
if((level & ALPM_SIG_PACKAGE) && pkg->base64_sig) {
unsigned char *decoded_sigdata = NULL;
size_t data_len;
int decode_ret = _alpm_decode_signature(pkg->base64_sig,
&decoded_sigdata, &data_len);
if(decode_ret == 0) {
alpm_list_t *keys = NULL;
if(_alpm_extract_keyid(handle, pkg->name, decoded_sigdata,
data_len, &keys) == 0) {
alpm_list_t *k;
for(k = keys; k; k = k->next) {
char *key = k->data;
if(_alpm_key_in_keychain(handle, key) == 0) {
if(!alpm_list_find_str(errors, key)) {
errors = alpm_list_add(errors, strdup(key));
}
}
}
FREELIST(keys);
}
}
}
}
PROGRESS(handle, ALPM_PROGRESS_KEYRING_START, "", 100,
numtargs, current);
EVENT(handle, ALPM_EVENT_KEYRING_DONE, NULL, NULL);
if(errors) {
EVENT(handle, ALPM_EVENT_KEY_DOWNLOAD_START, NULL, NULL);
int fail = 0;
alpm_list_t *k;
for(k = errors; k; k = k->next) {
char *key = k->data;
if(_alpm_key_import(handle, key) == -1) {
fail = 1;
}
}
EVENT(handle, ALPM_EVENT_KEY_DOWNLOAD_DONE, NULL, NULL);
if(fail) {
_alpm_log(handle, ALPM_LOG_ERROR, _("required key missing from keyring\n"));
return -1;
}
}
return 0;
}
static int check_validity(alpm_handle_t *handle,
size_t total, size_t total_bytes)
{
@ -1134,6 +1204,13 @@ int _alpm_sync_commit(alpm_handle_t *handle, alpm_list_t **data)
return -1;
}
#if HAVE_LIBGPGME
/* make sure all required signatures are in keyring */
if(check_keyring(handle)) {
return -1;
}
#endif
/* get the total size of all packages so we can adjust the progress bar more
* realistically if there are small and huge packages involved */
for(i = trans->add; i; i = i->next) {

View File

@ -212,6 +212,14 @@ void cb_event(alpm_event_t event, void *data1, void *data2)
printf(_("checking package integrity...\n"));
}
break;
case ALPM_EVENT_KEYRING_START:
if(config->noprogressbar) {
printf(_("checking keyring...\n"));
}
break;
case ALPM_EVENT_KEY_DOWNLOAD_START:
printf(_("downloading required keys...\n"));
break;
case ALPM_EVENT_LOAD_START:
if(config->noprogressbar) {
printf(_("loading package files...\n"));
@ -259,6 +267,8 @@ void cb_event(alpm_event_t event, void *data1, void *data2)
case ALPM_EVENT_RESOLVEDEPS_DONE:
case ALPM_EVENT_INTERCONFLICTS_DONE:
case ALPM_EVENT_INTEGRITY_DONE:
case ALPM_EVENT_KEYRING_DONE:
case ALPM_EVENT_KEY_DOWNLOAD_DONE:
case ALPM_EVENT_LOAD_DONE:
case ALPM_EVENT_DELTA_INTEGRITY_DONE:
case ALPM_EVENT_DELTA_PATCHES_DONE:
@ -446,6 +456,9 @@ void cb_progress(alpm_progress_t event, const char *pkgname, int percent,
case ALPM_PROGRESS_INTEGRITY_START:
opr = _("checking package integrity");
break;
case ALPM_PROGRESS_KEYRING_START:
opr = _("checking keys in keyring");
break;
case ALPM_PROGRESS_LOAD_START:
opr = _("loading package files");
break;