[pacman-dev] [PATCH v2] Add configuration option for Upgrade operation SigLevel
Allan McRae
allan at archlinux.org
Sat Feb 18 09:09:04 EST 2012
Add LocalFileSigLevel and RemoteFileSigLevel to control the signature
checking for "pacman -U <file>" and "pacman -U <url>" operations
respectively. The starting value for both these options is SigLevel,
if it is specified in the [options] section, or the built-in system
default. The specified values override and/or supplement this initial
value. Note there is no destintion between setting "Required" and
"PackageRequired" as there is not database options for Upgrade
operations.
Signed-off-by: Allan McRae <allan at archlinux.org>
---
This fixes all the issues I was concerned about in the previous patch.
Thanks to Bluewind for his idea which set me on the path to fixing it
(although I did it quite different so any crap implemenation is purely
me...).
lib/libalpm/alpm.h | 9 ++++++++
lib/libalpm/handle.c | 52 ++++++++++++++++++++++++++++++++++++++++++++-----
lib/libalpm/handle.h | 4 +++
src/pacman/conf.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++
src/pacman/conf.h | 2 +
src/pacman/upgrade.c | 21 +++++++++++++++++--
6 files changed, 131 insertions(+), 9 deletions(-)
diff --git a/lib/libalpm/alpm.h b/lib/libalpm/alpm.h
index eafe931..223a242 100644
--- a/lib/libalpm/alpm.h
+++ b/lib/libalpm/alpm.h
@@ -111,6 +111,9 @@ typedef enum _alpm_siglevel_t {
ALPM_SIG_DATABASE_MARGINAL_OK = (1 << 12),
ALPM_SIG_DATABASE_UNKNOWN_OK = (1 << 13),
+ ALPM_SIG_PACKAGE_SET = (1 << 27),
+ ALPM_SIG_PACKAGE_TRUST_SET = (1 << 28),
+
ALPM_SIG_USE_DEFAULT = (1 << 31)
} alpm_siglevel_t;
@@ -549,6 +552,12 @@ int alpm_option_set_checkspace(alpm_handle_t *handle, int checkspace);
alpm_siglevel_t alpm_option_get_default_siglevel(alpm_handle_t *handle);
int alpm_option_set_default_siglevel(alpm_handle_t *handle, alpm_siglevel_t level);
+alpm_siglevel_t alpm_option_get_local_file_siglevel(alpm_handle_t *handle);
+int alpm_option_set_local_file_siglevel(alpm_handle_t *handle, alpm_siglevel_t level);
+
+alpm_siglevel_t alpm_option_get_remote_file_siglevel(alpm_handle_t *handle);
+int alpm_option_set_remote_file_siglevel(alpm_handle_t *handle, alpm_siglevel_t level);
+
/** @} */
/** @addtogroup alpm_api_databases Database Functions
diff --git a/lib/libalpm/handle.c b/lib/libalpm/handle.c
index ec4cc56..534a4ed 100644
--- a/lib/libalpm/handle.c
+++ b/lib/libalpm/handle.c
@@ -596,6 +596,18 @@ int SYMEXPORT alpm_option_set_deltaratio(alpm_handle_t *handle, double ratio)
return 0;
}
+alpm_db_t SYMEXPORT *alpm_get_localdb(alpm_handle_t *handle)
+{
+ CHECK_HANDLE(handle, return NULL);
+ return handle->db_local;
+}
+
+alpm_list_t SYMEXPORT *alpm_get_syncdbs(alpm_handle_t *handle)
+{
+ CHECK_HANDLE(handle, return NULL);
+ return handle->dbs_sync;
+}
+
int SYMEXPORT alpm_option_set_checkspace(alpm_handle_t *handle, int checkspace)
{
CHECK_HANDLE(handle, return -1);
@@ -623,16 +635,44 @@ alpm_siglevel_t SYMEXPORT alpm_option_get_default_siglevel(alpm_handle_t *handle
return handle->siglevel;
}
-alpm_db_t SYMEXPORT *alpm_get_localdb(alpm_handle_t *handle)
+int SYMEXPORT alpm_option_set_local_file_siglevel(alpm_handle_t *handle,
+ alpm_siglevel_t level)
{
- CHECK_HANDLE(handle, return NULL);
- return handle->db_local;
+ CHECK_HANDLE(handle, return -1);
+#ifdef HAVE_LIBGPGME
+ handle->localfilesiglevel = level;
+#else
+ if(level != 0 && level != ALPM_SIG_USE_DEFAULT) {
+ RET_ERR(handle, ALPM_ERR_WRONG_ARGS, -1);
+ }
+#endif
+ return 0;
}
-alpm_list_t SYMEXPORT *alpm_get_syncdbs(alpm_handle_t *handle)
+alpm_siglevel_t SYMEXPORT alpm_option_get_local_file_siglevel(alpm_handle_t *handle)
{
- CHECK_HANDLE(handle, return NULL);
- return handle->dbs_sync;
+ CHECK_HANDLE(handle, return -1);
+ return handle->localfilesiglevel;
+}
+
+int SYMEXPORT alpm_option_set_remote_file_siglevel(alpm_handle_t *handle,
+ alpm_siglevel_t level)
+{
+ CHECK_HANDLE(handle, return -1);
+#ifdef HAVE_LIBGPGME
+ handle->remotefilesiglevel = level;
+#else
+ if(level != 0 && level != ALPM_SIG_USE_DEFAULT) {
+ RET_ERR(handle, ALPM_ERR_WRONG_ARGS, -1);
+ }
+#endif
+ return 0;
+}
+
+alpm_siglevel_t SYMEXPORT alpm_option_get_remote_file_siglevel(alpm_handle_t *handle)
+{
+ CHECK_HANDLE(handle, return -1);
+ return handle->remotefilesiglevel;
}
/* vim: set ts=2 sw=2 noet: */
diff --git a/lib/libalpm/handle.h b/lib/libalpm/handle.h
index a090ae4..4d92d11 100644
--- a/lib/libalpm/handle.h
+++ b/lib/libalpm/handle.h
@@ -92,6 +92,10 @@ struct __alpm_handle_t {
int usesyslog; /* Use syslog instead of logfile? */ /* TODO move to frontend */
int checkspace; /* Check disk space before installing */
alpm_siglevel_t siglevel; /* Default signature verification level */
+ alpm_siglevel_t localfilesiglevel; /* Signature verification level for local file
+ upgrade operations */
+ alpm_siglevel_t remotefilesiglevel; /* Signature verification level for remote file
+ upgrade operations */
/* error code */
alpm_errno_t pm_errno;
diff --git a/src/pacman/conf.c b/src/pacman/conf.c
index bfa8cad..cbf6f22 100644
--- a/src/pacman/conf.c
+++ b/src/pacman/conf.c
@@ -56,6 +56,8 @@ config_t *config_new(void)
if(alpm_capabilities() & ALPM_CAPABILITY_SIGNATURES) {
newconfig->siglevel = ALPM_SIG_PACKAGE | ALPM_SIG_PACKAGE_OPTIONAL |
ALPM_SIG_DATABASE | ALPM_SIG_DATABASE_OPTIONAL;
+ newconfig->localfilesiglevel = ALPM_SIG_USE_DEFAULT;
+ newconfig->remotefilesiglevel = ALPM_SIG_USE_DEFAULT;
}
return newconfig;
@@ -276,6 +278,7 @@ static int process_siglevel(alpm_list_t *values, alpm_siglevel_t *storage,
if(strcmp(value, "Never") == 0) {
if(package) {
level &= ~ALPM_SIG_PACKAGE;
+ level |= ALPM_SIG_PACKAGE_SET;
}
if(database) {
level &= ~ALPM_SIG_DATABASE;
@@ -284,6 +287,7 @@ static int process_siglevel(alpm_list_t *values, alpm_siglevel_t *storage,
if(package) {
level |= ALPM_SIG_PACKAGE;
level |= ALPM_SIG_PACKAGE_OPTIONAL;
+ level |= ALPM_SIG_PACKAGE_SET;
}
if(database) {
level |= ALPM_SIG_DATABASE;
@@ -293,6 +297,7 @@ static int process_siglevel(alpm_list_t *values, alpm_siglevel_t *storage,
if(package) {
level |= ALPM_SIG_PACKAGE;
level &= ~ALPM_SIG_PACKAGE_OPTIONAL;
+ level |= ALPM_SIG_PACKAGE_SET;
}
if(database) {
level |= ALPM_SIG_DATABASE;
@@ -302,6 +307,7 @@ static int process_siglevel(alpm_list_t *values, alpm_siglevel_t *storage,
if(package) {
level &= ~ALPM_SIG_PACKAGE_MARGINAL_OK;
level &= ~ALPM_SIG_PACKAGE_UNKNOWN_OK;
+ level |= ALPM_SIG_PACKAGE_TRUST_SET;
}
if(database) {
level &= ~ALPM_SIG_DATABASE_MARGINAL_OK;
@@ -311,6 +317,7 @@ static int process_siglevel(alpm_list_t *values, alpm_siglevel_t *storage,
if(package) {
level |= ALPM_SIG_PACKAGE_MARGINAL_OK;
level |= ALPM_SIG_PACKAGE_UNKNOWN_OK;
+ level |= ALPM_SIG_PACKAGE_TRUST_SET;
}
if(database) {
level |= ALPM_SIG_DATABASE_MARGINAL_OK;
@@ -340,6 +347,30 @@ static int process_siglevel(alpm_list_t *values, alpm_siglevel_t *storage,
return ret;
}
+/**
+ * Merge the package entires of two signature verification levels.
+ * @param base initial siglevel
+ * @param over overridden siglevel, derived value is stored here
+ */
+static void merge_siglevel(alpm_siglevel_t *base, alpm_siglevel_t *over)
+{
+ alpm_siglevel_t level = *over;
+ if(level & ALPM_SIG_USE_DEFAULT) {
+ level = *base;
+ } else {
+ if(!(level & ALPM_SIG_PACKAGE_SET)) {
+ level |= *base & ALPM_SIG_PACKAGE;
+ level |= *base & ALPM_SIG_PACKAGE_OPTIONAL;
+ }
+ if(!(level & ALPM_SIG_PACKAGE_TRUST_SET)) {
+ level |= *base & ALPM_SIG_PACKAGE_MARGINAL_OK;
+ level |= *base & ALPM_SIG_PACKAGE_UNKNOWN_OK;
+ }
+ }
+
+ *over = level;
+}
+
static int process_cleanmethods(alpm_list_t *values,
const char *file, int linenum)
{
@@ -483,6 +514,22 @@ static int _parse_options(const char *key, char *value,
return 1;
}
FREELIST(values);
+ } else if(strcmp(key, "LocalFileSigLevel") == 0) {
+ alpm_list_t *values = NULL;
+ setrepeatingoption(value, "LocalFileSigLevel", &values);
+ if(process_siglevel(values, &config->localfilesiglevel, file, linenum)) {
+ FREELIST(values);
+ return 1;
+ }
+ FREELIST(values);
+ } else if(strcmp(key, "RemoteFileSigLevel") == 0) {
+ alpm_list_t *values = NULL;
+ setrepeatingoption(value, "RemoteFileSigLevel", &values);
+ if(process_siglevel(values, &config->remotefilesiglevel, file, linenum)) {
+ FREELIST(values);
+ return 1;
+ }
+ FREELIST(values);
} else {
pm_printf(ALPM_LOG_WARNING,
_("config file %s, line %d: directive '%s' in section '%s' not recognized.\n"),
@@ -605,6 +652,11 @@ static int setup_libalpm(void)
alpm_option_set_default_siglevel(handle, config->siglevel);
+ merge_siglevel(&config->siglevel, &config->localfilesiglevel);
+ merge_siglevel(&config->siglevel, &config->remotefilesiglevel);
+ alpm_option_set_local_file_siglevel(handle, config->localfilesiglevel);
+ alpm_option_set_remote_file_siglevel(handle, config->remotefilesiglevel);
+
if(config->xfercommand) {
alpm_option_set_fetchcb(handle, download_with_xfercommand);
} else if(!(alpm_capabilities() & ALPM_CAPABILITY_DOWNLOADER)) {
diff --git a/src/pacman/conf.h b/src/pacman/conf.h
index 481132f..7447e89 100644
--- a/src/pacman/conf.h
+++ b/src/pacman/conf.h
@@ -72,6 +72,8 @@ typedef struct __config_t {
unsigned int ask;
alpm_transflag_t flags;
alpm_siglevel_t siglevel;
+ alpm_siglevel_t localfilesiglevel;
+ alpm_siglevel_t remotefilesiglevel;
/* conf file options */
/* I Love Candy! */
diff --git a/src/pacman/upgrade.c b/src/pacman/upgrade.c
index 87f7c39..c60649a 100644
--- a/src/pacman/upgrade.c
+++ b/src/pacman/upgrade.c
@@ -40,8 +40,7 @@
int pacman_upgrade(alpm_list_t *targets)
{
int retval = 0;
- alpm_list_t *i;
- alpm_siglevel_t level = alpm_option_get_default_siglevel(config->handle);
+ alpm_list_t *i, *remote = NULL;
if(targets == NULL) {
pm_printf(ALPM_LOG_ERROR, _("no targets specified (use -h for help)\n"));
@@ -51,6 +50,8 @@ int pacman_upgrade(alpm_list_t *targets)
/* Check for URL targets and process them
*/
for(i = targets; i; i = alpm_list_next(i)) {
+ int *r = malloc(sizeof(int));
+
if(strstr(i->data, "://")) {
char *str = alpm_fetch_pkgurl(config->handle, i->data);
if(str == NULL) {
@@ -60,8 +61,13 @@ int pacman_upgrade(alpm_list_t *targets)
} else {
free(i->data);
i->data = str;
+ *r = 1;
}
+ } else {
+ *r = 0;
}
+
+ remote = alpm_list_add(remote, r);
}
if(retval) {
@@ -75,9 +81,16 @@ int pacman_upgrade(alpm_list_t *targets)
printf(_("loading packages...\n"));
/* add targets to the created transaction */
- for(i = targets; i; i = alpm_list_next(i)) {
+ for(i = targets; i; i = alpm_list_next(i), remote = alpm_list_next(remote)) {
const char *targ = i->data;
alpm_pkg_t *pkg;
+ alpm_siglevel_t level;
+
+ if(*(int *)remote->data) {
+ level = alpm_option_get_remote_file_siglevel(config->handle);
+ } else {
+ level = alpm_option_get_local_file_siglevel(config->handle);
+ }
if(alpm_pkg_load(config->handle, targ, 1, level, &pkg) != 0) {
pm_printf(ALPM_LOG_ERROR, "'%s': %s\n",
@@ -95,6 +108,8 @@ int pacman_upgrade(alpm_list_t *targets)
config->explicit_adds = alpm_list_add(config->explicit_adds, pkg);
}
+ FREELIST(remote);
+
if(retval) {
trans_release();
return retval;
--
1.7.9.1
More information about the pacman-dev
mailing list