[pacman-dev] [PATCH 0/2] make gpgme optional
The package signing Wiki page says we could make gpgme optional for pacman. The two following (very small patches) define another callback for package signing. It allows to make gpgme optional while preserving signature check capabilities, via an external callback. How such a callback could be defined remains to be decided in pacman code or pacman.conf syntax. -- Rémy.
This callback will make possible the use of an external tool to check signatures. Signed-off-by: Rémy Oudompheng <remy@archlinux.org> --- lib/libalpm/alpm.h | 11 +++++++++++ lib/libalpm/error.c | 2 ++ lib/libalpm/handle.c | 13 +++++++++++++ lib/libalpm/handle.h | 1 + 4 files changed, 27 insertions(+), 0 deletions(-) diff --git a/lib/libalpm/alpm.h b/lib/libalpm/alpm.h index b08191d..5fb3d86 100644 --- a/lib/libalpm/alpm.h +++ b/lib/libalpm/alpm.h @@ -94,6 +94,13 @@ typedef void (*alpm_cb_totaldl)(off_t total); typedef int (*alpm_cb_fetch)(const char *url, const char *localpath, int force); +/** A callback for checking signatures. + * @param path the path of the signed file + * @param sig the signature to check + * @return an int value : 0 (valid), 1 (invalid), -1 (an error occured) + */ +typedef int (*alpm_cb_checksig)(const char *path, const pmpgpsig_t *sig); + /* * Options */ @@ -110,6 +117,9 @@ void alpm_option_set_fetchcb(alpm_cb_fetch cb); alpm_cb_totaldl alpm_option_get_totaldlcb(void); void alpm_option_set_totaldlcb(alpm_cb_totaldl cb); +alpm_cb_checksig alpm_option_get_checksigcb(void); +int alpm_option_set_checksigcb(alpm_cb_checksig cb); + const char *alpm_option_get_root(void); int alpm_option_set_root(const char *root); @@ -561,6 +571,7 @@ enum _pmerrno_t { PM_ERR_LIBARCHIVE, PM_ERR_LIBCURL, PM_ERR_EXTERNAL_DOWNLOAD, + PM_ERR_EXTERNAL_SIGCHECK, PM_ERR_GPGME }; diff --git a/lib/libalpm/error.c b/lib/libalpm/error.c index 4d4a065..839ecc3 100644 --- a/lib/libalpm/error.c +++ b/lib/libalpm/error.c @@ -158,6 +158,8 @@ const char SYMEXPORT *alpm_strerror(int err) return _("gpgme error"); case PM_ERR_EXTERNAL_DOWNLOAD: return _("error invoking external downloader"); + case PM_ERR_EXTERNAL_SIGCHECK: + return _("error invoking external signature check"); /* Unknown error! */ default: return _("unexpected error"); diff --git a/lib/libalpm/handle.c b/lib/libalpm/handle.c index 42c0cd1..5eb0dc5 100644 --- a/lib/libalpm/handle.c +++ b/lib/libalpm/handle.c @@ -130,6 +130,12 @@ alpm_cb_totaldl SYMEXPORT alpm_option_get_totaldlcb() return handle->totaldlcb; } +alpm_cb_checksig SYMEXPORT alpm_option_get_checksigcb() +{ + ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, NULL)); + return handle->checksigcb; +} + const char SYMEXPORT *alpm_option_get_root() { if (handle == NULL) { @@ -310,6 +316,13 @@ void SYMEXPORT alpm_option_set_totaldlcb(alpm_cb_totaldl cb) handle->totaldlcb = cb; } +int SYMEXPORT alpm_option_set_checksigcb(alpm_cb_checksig cb) +{ + ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); + handle->checksigcb = cb; + return 0; +} + int SYMEXPORT alpm_option_set_root(const char *root) { struct stat st; diff --git a/lib/libalpm/handle.h b/lib/libalpm/handle.h index cf192bc..2f2e5d2 100644 --- a/lib/libalpm/handle.h +++ b/lib/libalpm/handle.h @@ -52,6 +52,7 @@ typedef struct _pmhandle_t { alpm_cb_download dlcb; /* Download callback function */ alpm_cb_totaldl totaldlcb; /* Total download callback function */ alpm_cb_fetch fetchcb; /* Download file callback function */ + alpm_cb_checksig checksigcb; /* Signature check callback function */ /* filesystem paths */ char *root; /* Root path, default '/' */ -- 1.7.4.2
This makes it possible to compile libalpm without the gpgme library. This option is reflected in the configure script. Signed-off-by: Rémy Oudompheng <remy@archlinux.org> --- configure.ac | 19 +++++++++++++++++-- lib/libalpm/signing.c | 33 ++++++++++++++++++++++++++++++--- lib/libalpm/signing.h | 2 +- lib/libalpm/sync.c | 2 +- 4 files changed, 49 insertions(+), 7 deletions(-) diff --git a/configure.ac b/configure.ac index 87330af..b71058a 100644 --- a/configure.ac +++ b/configure.ac @@ -93,6 +93,11 @@ AC_ARG_WITH(openssl, AS_HELP_STRING([--with-openssl], [use OpenSSL crypto implementations instead of internal routines]), [], [with_openssl=check]) +# Help line for using GPGME +AC_ARG_WITH(gpgme, + AS_HELP_STRING([--with-gpgme], [enable signing capabilities]), + [], [with_gpgme=check]) + # Check for useable libcurl LIBCURL_CHECK_CONFIG([yes], [7.19.4]) @@ -148,8 +153,17 @@ AS_IF([test "x$with_openssl" != "xno"], AM_CONDITIONAL([HAVE_LIBSSL], [test "x$ac_cv_lib_ssl_MD5_Final" = "xyes"]) # Check for gpgme -AC_CHECK_LIB([gpgme], [gpgme_check_version], , - AC_MSG_ERROR([gpgme is needed to compile pacman!])) +AC_MSG_CHECKING(whether to enable gpgme) +AS_IF([test "x$with_gpgme" != "xno"], + [AC_MSG_RESULT(yes) + AC_CHECK_LIB([gpgme], [gpgme_check_version], , + [if test "x$with_gpgme" != "xcheck"; then + AC_MSG_FAILURE([--with-gpgme was given, but -lgpgme was not found]) + fi], + [-lgpgme])] + with_gpgme=$ac_cv_lib_gpgme_gpgme_check_version, + AC_MSG_RESULT(no)) +AM_CONDITIONAL([HAVE_LIBGPGME], [test "x$ac_cv_lib_gpgme_gpgme_check_version" = "xyes"]) # Checks for header files. AC_CHECK_HEADERS([fcntl.h glob.h libintl.h locale.h mntent.h string.h \ @@ -402,6 +416,7 @@ ${PACKAGE_NAME}: Compilation options: Run make in doc/ dir : ${wantdoc} ${asciidoc} Doxygen support : ${usedoxygen} + GPGME signing support : ${with_gpgme} debug support : ${debug} " diff --git a/lib/libalpm/signing.c b/lib/libalpm/signing.c index c30650b..581d5c2 100644 --- a/lib/libalpm/signing.c +++ b/lib/libalpm/signing.c @@ -23,19 +23,24 @@ #include <stdio.h> #include <string.h> #include <locale.h> /* setlocale() */ + +#ifdef HAVE_LIBGPGME #include <gpgme.h> +#endif /* libalpm */ #include "signing.h" #include "package.h" #include "util.h" #include "log.h" +#include "handle.h" #include "alpm.h" #define CHECK_ERR(void) do { \ if(err != GPG_ERR_NO_ERROR) { goto error; } \ } while(0) +#ifdef HAVE_LIBGPGME static int gpgme_init(void) { static int init = 0; @@ -97,7 +102,7 @@ error: * @param sig PGP signature data in raw form (already decoded) * @return a int value : 0 (valid), 1 (invalid), -1 (an error occured) */ -int _alpm_gpgme_checksig(const char *path, const pmpgpsig_t *sig) +static int _alpm_gpgme_checksig(const char *path, const pmpgpsig_t *sig) { int ret = 0; gpgme_error_t err; @@ -202,6 +207,7 @@ error: } return ret; } +#endif /** * Load the signature from the given path into the provided struct. @@ -248,6 +254,27 @@ int _alpm_load_signature(const char *sigfile, pmpgpsig_t *pgpsig) { return 0; } +/** Check the PGP signature for an arbitrary file. + * This function redirects to the standard gpgme checking + * function or a user-defined external callback. + */ +int _alpm_file_checksig(const char *path, const pmpgpsig_t *sig) +{ + if(handle->checksigcb == NULL) { +#ifdef HAVE_LIBGPGME + return _alpm_gpgme_checksig(path, sig); +#else + RET_ERR(PM_ERR_EXTERNAL_SIGCHECK, -1); +#endif + } else { + int ret = handle->checksigcb(path, sig); + if(ret == -1) { + RET_ERR(PM_ERR_EXTERNAL_SIGCHECK, -1); + } + return ret; + } +} + /** * Check the PGP package signature for the given package file. * @param pkg the package to check @@ -258,7 +285,7 @@ int SYMEXPORT alpm_pkg_check_pgp_signature(pmpkg_t *pkg) ALPM_LOG_FUNC; ASSERT(pkg != NULL, return 0); - return _alpm_gpgme_checksig(alpm_pkg_get_filename(pkg), + return _alpm_file_checksig(alpm_pkg_get_filename(pkg), alpm_pkg_get_pgpsig(pkg)); } @@ -272,7 +299,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), + return _alpm_file_checksig(_alpm_db_path(db), _alpm_db_pgpsig(db)); } diff --git a/lib/libalpm/signing.h b/lib/libalpm/signing.h index b37abf0..6781377 100644 --- a/lib/libalpm/signing.h +++ b/lib/libalpm/signing.h @@ -31,7 +31,7 @@ struct __pmpgpsig_t { unsigned char *rawdata; }; -int _alpm_gpgme_checksig(const char *path, const pmpgpsig_t *sig); +int _alpm_file_checksig(const char *path, const pmpgpsig_t *sig); int _alpm_load_signature(const char *sigfile, pmpgpsig_t *pgpsig); #endif /* _ALPM_SIGNING_H */ diff --git a/lib/libalpm/sync.c b/lib/libalpm/sync.c index 5428e40..4f55c95 100644 --- a/lib/libalpm/sync.c +++ b/lib/libalpm/sync.c @@ -850,7 +850,7 @@ int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t **data) pmdb_t *sdb = alpm_pkg_get_db(spkg); if(sdb->pgp_verify != PM_PGP_VERIFY_NEVER) { - int ret = _alpm_gpgme_checksig(filepath, pgpsig); + int ret = _alpm_file_checksig(filepath, pgpsig); if((sdb->pgp_verify == PM_PGP_VERIFY_ALWAYS && ret != 0) || (sdb->pgp_verify == PM_PGP_VERIFY_OPTIONAL && ret == 1)) { errors++; -- 1.7.4.2
participants (1)
-
Rémy Oudompheng