From e5fdc704f3bcd1588bbb382d00f0b6f329823480 Mon Sep 17 00:00:00 2001 From: Oliver Kurth Date: Mon, 20 Oct 2025 20:58:24 +0000 Subject: [PATCH] add option --nocmdlinegpgcheck to disable gpgcheck just for packages on the command line Signed-off-by: Oliver Kurth --- client/config.c | 14 +++++++++++++- client/repolist.c | 2 ++ common/config.h | 2 +- include/tdnftypes.h | 2 ++ pytests/tests/test_rpm_cmdline.py | 32 +++++++++++++++++++++++++++++++ tools/cli/lib/parseargs.c | 4 +++- 6 files changed, 53 insertions(+), 3 deletions(-) diff --git a/client/config.c b/client/config.c index 143a6bb7..450581de 100644 --- a/client/config.c +++ b/client/config.c @@ -160,6 +160,10 @@ TDNFConfigFromCnfTree(PTDNF_CONF pConf, struct cnfnode *cn_top) { pConf->nGPGCheck = isTrue(cn->value); } + else if (strcmp(cn->name, TDNF_CONF_KEY_CMDLINEGPGCHECK) == 0) + { + pConf->nCliGPGCheck = isTrue(cn->value); + } else if (strcmp(cn->name, TDNF_CONF_KEY_SSL_VERIFY) == 0) { pConf->nSSLVerify = isTrue(cn->value); @@ -335,7 +339,7 @@ TDNFReadConfig( /* defaults */ pConf->nGPGCheck = 0; - pConf->nInstallOnlyLimit = 1; + pConf->nCliGPGCheck = -1; /* mark as unset */ pConf->nCleanRequirementsOnRemove = 0; pConf->nKeepCache = 0; pConf->nOpenMax = TDNF_CONF_DEFAULT_OPENMAX; @@ -432,6 +436,14 @@ TDNFReadConfig( pszTdnfVersion = TDNFGetVersion(); + /* override from cmd line */ + if (pTdnf->pArgs->nNoCmdLineGPGCheck) { + pConf->nCliGPGCheck = 0; + /* if unset, same as general nGPGCheck */ + } else if (pConf->nCliGPGCheck == -1) { + pConf->nCliGPGCheck = pConf->nGPGCheck; + } + if (pConf->pszOSName == NULL) TDNFAllocateString("UNKNOWN", &pConf->pszOSName); diff --git a/client/repolist.c b/client/repolist.c index b603efe4..d7ab2741 100644 --- a/client/repolist.c +++ b/client/repolist.c @@ -340,6 +340,8 @@ TDNFCreateCmdLineRepo( dwError = TDNFCreateRepo(pTdnf, &pRepo, CMDLINE_REPO_NAME); BAIL_ON_TDNF_ERROR(dwError); pRepo->nHasMetaData = 0; + if (pTdnf->pConf->nCliGPGCheck == 0) + pRepo->nGPGCheck = 0; dwError = TDNFSafeAllocateString(CMDLINE_REPO_NAME, &pRepo->pszName); BAIL_ON_TDNF_ERROR(dwError); diff --git a/common/config.h b/common/config.h index 7a4eec23..95d97e77 100644 --- a/common/config.h +++ b/common/config.h @@ -28,6 +28,7 @@ //Conf file key names #define TDNF_CONF_KEY_GPGCHECK "gpgcheck" +#define TDNF_CONF_KEY_CMDLINEGPGCHECK "cligpgcheck" #define TDNF_CONF_KEY_INSTALLONLY_LIMIT "installonly_limit" #define TDNF_CONF_KEY_INSTALLONLYPKGS "installonlypkgs" #define TDNF_CONF_KEY_CLEAN_REQ_ON_REMOVE "clean_requirements_on_remove" @@ -120,7 +121,6 @@ // repo default settings #define TDNF_REPO_DEFAULT_ENABLED 0 #define TDNF_REPO_DEFAULT_SKIP 0 -#define TDNF_REPO_DEFAULT_GPGCHECK 1 #define TDNF_REPO_DEFAULT_MINRATE 0 #define TDNF_REPO_DEFAULT_THROTTLE 0 #define TDNF_REPO_DEFAULT_TIMEOUT 0 diff --git a/include/tdnftypes.h b/include/tdnftypes.h index a7895ff7..68b81610 100644 --- a/include/tdnftypes.h +++ b/include/tdnftypes.h @@ -221,6 +221,7 @@ typedef struct _TDNF_CMD_ARGS int nShowVersion; //show version and exit int nNoDeps; //download no dependencies int nNoGPGCheck; //skip gpg check + int nNoCmdLineGPGCheck; //skip gpg check for local packages (from command line) int nSkipSignature; int nSkipDigest; int nNoOutput; //if quiet and assumeyes are provided @@ -255,6 +256,7 @@ typedef struct _TDNF_CMD_ARGS typedef struct _TDNF_CONF { int nGPGCheck; + int nCliGPGCheck; int nSSLVerify; int nInstallOnlyLimit; int nCleanRequirementsOnRemove; diff --git a/pytests/tests/test_rpm_cmdline.py b/pytests/tests/test_rpm_cmdline.py index cdcbc26a..8897cf1d 100644 --- a/pytests/tests/test_rpm_cmdline.py +++ b/pytests/tests/test_rpm_cmdline.py @@ -176,3 +176,35 @@ def test_reinstall_as_file(utils): assert utils.check_package(pkgname) assert "Nothing to do" not in "\n".join(ret['stderr']) assert "Reinstalling" in "\n".join(ret['stdout']) + + +# test something like "tdnf install /path/to/pkg.rpm" +# with nocmdlinegpgcheck option +def test_install_as_file_nocmdlinegpgcheck(utils): + pkgname = utils.config["sglversion_pkgname"] + path = get_pkg_file_path(utils, pkgname) + + # make sure we will fail if option isn't set + ret = utils.run(['tdnf', 'install', '-y', '--setopt=gpgcheck=1', path]) + assert ret['retval'] != 0 + assert not utils.check_package(pkgname) + + ret = utils.run(['tdnf', 'install', '-y', '--setopt=gpgcheck=1', '--nocligpgcheck', path]) + assert ret['retval'] == 0 + assert utils.check_package(pkgname) + + +# test something like "tdnf install /path/to/pkg.rpm" +# with gpgcheck set to 1, but cligpgcheck set to 0 +def test_install_as_file_nocmdlinegpgcheck_conf(utils): + pkgname = utils.config["sglversion_pkgname"] + path = get_pkg_file_path(utils, pkgname) + + # make sure we will fail if option isn't set + ret = utils.run(['tdnf', 'install', '-y', '--setopt=gpgcheck=1', path]) + assert ret['retval'] != 0 + assert not utils.check_package(pkgname) + + ret = utils.run(['tdnf', 'install', '-y', '--setopt=gpgcheck=1', '--setopt=cligpgcheck=0', path]) + assert ret['retval'] == 0 + assert utils.check_package(pkgname) diff --git a/tools/cli/lib/parseargs.c b/tools/cli/lib/parseargs.c index 820892e7..88e9c049 100644 --- a/tools/cli/lib/parseargs.c +++ b/tools/cli/lib/parseargs.c @@ -40,8 +40,9 @@ static struct option pstOptions[] = {"noautoremove", no_argument, &_opt.nNoAutoRemove, 1}, {"nodeps", no_argument, &_opt.nNoDeps, 1}, {"nogpgcheck", no_argument, &_opt.nNoGPGCheck, 1}, //--nogpgcheck + {"nocligpgcheck", no_argument, &_opt.nNoCmdLineGPGCheck, 1}, //--nocligpgcheck {"noplugins", no_argument, 0, 0}, //--noplugins - {"quiet", no_argument, &_opt.nQuiet, 1}, //--nogpgcheck + {"quiet", no_argument, &_opt.nQuiet, 1}, //--quiet {"refresh", no_argument, &_opt.nRefresh, 1}, //--refresh {"releasever", required_argument, 0, 0}, //--releasever {"reboot-required", no_argument, 0, 0}, //--reboot-required @@ -338,6 +339,7 @@ TDNFCopyOptions( pArgs->nDebugSolver = pOptionArgs->nDebugSolver; pArgs->nNoDeps = pOptionArgs->nNoDeps; pArgs->nNoGPGCheck = pOptionArgs->nNoGPGCheck; + pArgs->nNoCmdLineGPGCheck = pOptionArgs->nNoCmdLineGPGCheck; pArgs->nSkipSignature = pOptionArgs->nSkipSignature; pArgs->nSkipDigest = pOptionArgs->nSkipDigest; pArgs->nNoOutput = pOptionArgs->nQuiet && pOptionArgs->nAssumeYes;