commit:     c3fa8f90327227df7b1fd098cf1a977ccacf3c42
Author:     Sam James <sam <AT> gentoo <DOT> org>
AuthorDate: Fri Nov 28 05:21:34 2025 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Fri Dec 26 18:11:47 2025 +0000
URL:        https://gitweb.gentoo.org/proj/portage.git/commit/?id=c3fa8f90

binrepos.conf: implement `verify-signature`

Add `verify-signature` to binrepos.conf to allow controlling PGP signature
verification on a per-binary repository basis.

Users may want to verify binpkgs from the official Gentoo binhost or
other binhosts they run themselves, but not be forced to have a signing
key on such consumer machines to casually run `quickpkg` or `FEATURES=buildpkg`.

We can then toggle the default in the config file we ship in stages,
the handbook, etc, and possibly ship some default in Portage for `[gentoo]`. For
this work to be deployed, we also first need to change the default `location`
for that binhost to something else to avoid comingling of trusted and 
(potentially)
untrusted binpkgs. Users will need to purge comingled binpkgs first to use
this reliably.

I've not split this into two like we do for FEATURES="binpkg-request-signature"
and FEATURES="binpkg-ignore-signature". Instead, `verify-signature` just
controls 'both' (i.e. on = verify, off = don't even look to see if there's
a signature). I think having two toggles was a mistake we shouldn't repeat.

_instance_key_multi_instance disambiguates when cpv + BUILD_ID match for
a binpkg by using size, build time, and mtime, so we shouldn't get confused
in get_local_repo_location.

Supposing get_local_repo_location does somehow get confused, there are
the following scenarios for induced collisions via another repository:

* Collision where binhost-A has verify-signature and binhost-B has
  verify-signature disabled. A binpkg from binhost-A is used when we thought
  it was from binhost-B: we unnecessarily verify the binpkg and that may
  fail.

* Collision where binhost-A has verify-signature and binhost-B has
  verify-signature too. A binpkg from binhost-B is used and it gets verified
  just as it would've been if it was from binhost-A. We don't specify the
  keyring (at least currently) in binrepos.conf, so this distinction isn't
  observable.

* Collision where binhost-A has verify-signature and binhost-B has
  verify-signature disabled. A binpkg from binhost-B is used when we thought
  it was from binhost-A: we don't verify the binpkg.

  But this isn't actually a problem, because if the binpkg is in a configured
  binhost in binrepos.conf, it already could've been used outside of collisions,
  so there's no downgrade in protection. i.e. A collision isn't required
  for the binpkg to be used unverified from binhost-B anyway.

  See below for a variant on this.

There's another case to think about where collision occurs from a verified
  repository, rather than an unverified repository trying to undermine a
  verified one:

* binhost-A has verify-signature, binhost-B doesn't. binhost-B is trusted.
  We use a binpkg from binhost-A and then don't verify it because of a
  collision.

  The distinction here is that if an attacker has control over your local,
  unverified binhost-B, they could just serve you a bad binpkg anyway.

  But this does matter if you're fetching a binpkg from binhost-A, you're going
  to verify it if you know it is from binhost-A, but the collision (perhaps
  chosen by an attacker to match a binpkg you likely to have locally in
  binhost-B) means it is not verified.

  This shouldn't be possible because:
    filename: unpack_metadata -> getname(cpv) -> getname_build_id(cpv)
                                              -> get_local_repo_location(cpv)
                                              -> get_local_repo(cpv)

    repoconfig: unpack_metadata -> get_local_repo(cpv)

  uses the same logic and should return the same result, meaning it should be
  internally consistent (i.e. if we chose a binpkg and we have its full path,
  it should correspond to the config we've just now looked up).

Bug: https://bugs.gentoo.org/930730
Bug: https://bugs.gentoo.org/941770
Bug: https://bugs.gentoo.org/945384
Signed-off-by: Sam James <sam <AT> gentoo.org>

 lib/portage/binrepo/config.py                    |   4 +-
 lib/portage/dbapi/bintree.py                     |  43 +++-
 lib/portage/gpkg.py                              |  55 ++--
 lib/portage/tests/gpkg/test_gpkg_gpg_emerge.py   | 315 +++++++++++++++++++++++
 lib/portage/tests/resolver/ResolverPlayground.py |   1 +
 man/make.conf.5                                  |   6 +-
 man/portage.5                                    |   4 +
 7 files changed, 392 insertions(+), 36 deletions(-)

diff --git a/lib/portage/binrepo/config.py b/lib/portage/binrepo/config.py
index 97207eb24b..4c0b729c57 100644
--- a/lib/portage/binrepo/config.py
+++ b/lib/portage/binrepo/config.py
@@ -20,8 +20,9 @@ class BinRepoConfig:
         "priority",
         "resumecommand",
         "sync_uri",
+        "verify_signature",
     )
-    _bool_opts = ("frozen",)
+    _bool_opts = ("frozen", "verify_signature")
 
     def __init__(self, opts):
         """
@@ -46,6 +47,7 @@ class BinRepoConfig:
         if self.priority is not None:
             repo_msg.append(indent + "priority: " + str(self.priority))
         repo_msg.append(indent + "sync-uri: " + self.sync_uri)
+        repo_msg.append(indent + f"verify-signature: {self.verify_signature}")
         if self.frozen:
             repo_msg.append(f"{indent}frozen: {str(self.frozen).lower()}")
         repo_msg.append("")

diff --git a/lib/portage/dbapi/bintree.py b/lib/portage/dbapi/bintree.py
index ec54e19c64..54ea0dba17 100644
--- a/lib/portage/dbapi/bintree.py
+++ b/lib/portage/dbapi/bintree.py
@@ -369,9 +369,19 @@ class bindbapi(fakedbapi):
                     dest_dir,
                 )
             elif binpkg_format == "gpkg":
+                gpkg_args = {}
+                repoconfig = self.bintree.get_local_repo(cpv)
+                if repoconfig:
+                    # This may be missing if it's not a remote binpkg, or
+                    # remote binpkgs are mingled in with local binpkgs
+                    # (no separate `location` in binrepos.conf)
+                    gpkg_args["verify_signature"] = repoconfig.verify_signature
+
                 await loop.run_in_executor(
                     ForkExecutor(loop=loop),
-                    portage.gpkg.gpkg(self.settings, cpv, 
binpkg_file).unpack_metadata,
+                    portage.gpkg.gpkg(
+                        self.settings, cpv, binpkg_file, **gpkg_args
+                    ).unpack_metadata,
                     dest_dir,
                 )
             else:
@@ -420,9 +430,19 @@ class bindbapi(fakedbapi):
                 if extractor.returncode != os.EX_OK:
                     raise PortageException(f"Error Extracting '{pkg_path}'")
             elif binpkg_format == "gpkg":
+                gpkg_args = {}
+                repoconfig = self.bintree.get_local_repo(cpv)
+                if repoconfig:
+                    # This may be missing if it's not a remote binpkg, or
+                    # remote binpkgs are mingled in with local binpkgs
+                    # (no separate `location` in binrepos.conf)
+                    gpkg_args["verify_signature"] = repoconfig.verify_signature
+
                 await loop.run_in_executor(
                     ForkExecutor(loop=loop),
-                    portage.gpkg.gpkg(self.settings, cpv, pkg_path).decompress,
+                    portage.gpkg.gpkg(
+                        self.settings, cpv, pkg_path, **gpkg_args
+                    ).decompress,
                     dest_dir,
                 )
             else:
@@ -2636,11 +2656,8 @@ class binarytree:
             or int(remote_metadata["_mtime_"]) != st[stat.ST_MTIME]
         )
 
-    def get_local_repo_location(self, pkgname):
-        """Returns local repo location associated with pkgname or None
-        if a location is not associated."""
-        from portage.util import normalize_path
-
+    def get_local_repo(self, pkgname):
+        """Returns local repo associated with pkgname"""
         # Since pkgname._repoconfig is not guaranteed to be present
         # here, retrieve it from the remote metadata.
         if not self._remotepkgs:
@@ -2648,10 +2665,16 @@ class binarytree:
         instance_key = self.dbapi._instance_key(pkgname)
         remote_metadata = self._remotepkgs.get(instance_key)
         if remote_metadata is None:
-            return False
-        repoconfig = remote_metadata["CPV"]._repoconfig
-        if repoconfig is None:
             return None
+        repoconfig = remote_metadata["CPV"]._repoconfig
+        return repoconfig
+
+    def get_local_repo_location(self, pkgname):
+        """Returns local repo location associated with pkgname or None
+        if a location is not associated."""
+        from portage.util import normalize_path
+
+        repoconfig = self.get_local_repo(pkgname)
         if repoconfig.location:
             location = normalize_path(repoconfig.location)
             if location == self.pkgdir:

diff --git a/lib/portage/gpkg.py b/lib/portage/gpkg.py
index 3d18d3b5eb..c100c9f666 100644
--- a/lib/portage/gpkg.py
+++ b/lib/portage/gpkg.py
@@ -710,7 +710,7 @@ class gpkg:
     https://www.gentoo.org/glep/glep-0078.html
     """
 
-    def __init__(self, settings, basename=None, gpkg_file=None):
+    def __init__(self, settings, basename=None, gpkg_file=None, 
verify_signature=None):
         """
         gpkg class handle all gpkg operations for one package.
         basename is the package basename.
@@ -735,32 +735,43 @@ class gpkg:
         self.signature_exist = None
         self.prefix = None
 
-        # Compression is the compression algorithm, if set to None will
-        # not use compression.
+        # Compression is the compression algorithm. No compression
+        # if set to None.
         self.compression = self.settings.get("BINPKG_COMPRESS", None)
         if self.compression in ["", "none"]:
             self.compression = None
 
-        # The create_signature is whether create signature for the package or 
not.
-        if "binpkg-signing" in self.settings.features:
-            self.create_signature = True
+        # Whether to sign the package or not
+        self.create_signature = "binpkg-signing" in self.settings.features
+
+        # If `verify-signature` is unset in binrepos.conf, use the FEATURES
+        # flags instead.
+        if verify_signature is None:
+            # request_signature is whether signature files are mandatory.
+            # If true, any missing signature file will cause processing to be
+            # rejected.
+            self.request_signature = (
+                "binpkg-request-signature" in self.settings.features
+            )
+
+            # verify_signature is whether to verify package signatures or not.
+            # In rare cases, the user may want to ignore signature, e.g.
+            # a package with an expired signature.
+            self.verify_signature = (
+                "binpkg-ignore-signature" not in self.settings.features
+            )
         else:
-            self.create_signature = False
+            self.verify_signature = verify_signature
+            self.request_signature = verify_signature
 
-        # The request_signature is whether signature files are mandatory.
-        # If set true, any missing signature file will cause reject processing.
+        # FEATURES should override in one direction if they're stronger
+        # and explicitly set. This also makes testing easier.
         if "binpkg-request-signature" in self.settings.features:
             self.request_signature = True
-        else:
+            self.verify_signature = True
+        elif "binpkg-ignore-signature" in self.settings.features:
             self.request_signature = False
-
-        # The verify_signature is whether verify package signature or not.
-        # In rare case user may want to ignore signature,
-        # E.g. package with expired signature.
-        if "binpkg-ignore-signature" in self.settings.features:
             self.verify_signature = False
-        else:
-            self.verify_signature = True
 
         self.ext_list = {
             "gzip": ".gz",
@@ -879,7 +890,7 @@ class gpkg:
             )
 
             # Verify metadata file signature if needed
-            # binpkg-ignore-signature can override this.
+            # (binpkg-ignore-signature can override this)
             signature_filename = metadata_tarinfo.name + ".sig"
             if signature_filename in container.getnames():
                 if self.request_signature and self.verify_signature:
@@ -1630,7 +1641,7 @@ class gpkg:
                 signature_exist = True
 
             # Check Manifest signature if needed.
-            # binpkg-ignore-signature can override this.
+            # (binpkg-ignore-signature can override this.)
             if self.request_signature or signature_exist:
                 checksum_info = checksum_helper(
                     self.settings, gpg_operation=checksum_helper.VERIFY, 
detached=False
@@ -1680,7 +1691,7 @@ class gpkg:
                     continue
 
                 # Verify current file signature if needed
-                # binpkg-ignore-signature can override this.
+                # (binpkg-ignore-signature can override this.)
                 if (
                     (self.request_signature or signature_exist)
                     and self.verify_signature
@@ -1742,13 +1753,13 @@ class gpkg:
                 unverified_files.remove(f)
                 unverified_manifest.remove(manifest_record)
 
-        # Check if any file IN Manifest but NOT IN binary package
+        # Check if any files are IN the Manifest but NOT IN the binary package
         if len(unverified_manifest) != 0:
             raise DigestException(
                 f"Missing files: {str(unverified_manifest)} in 
{self.gpkg_file}"
             )
 
-        # Check if any file NOT IN Manifest but IN binary package
+        # Check if any files are NOT IN the Manifest but are IN the binary 
package
         if len(unverified_files) != 0:
             raise DigestException(
                 f"Unknown files exists: {str(unverified_files)} in 
{self.gpkg_file}"

diff --git a/lib/portage/tests/gpkg/test_gpkg_gpg_emerge.py 
b/lib/portage/tests/gpkg/test_gpkg_gpg_emerge.py
new file mode 100644
index 0000000000..6c38c3c68f
--- /dev/null
+++ b/lib/portage/tests/gpkg/test_gpkg_gpg_emerge.py
@@ -0,0 +1,315 @@
+# Copyright 2022-2025 Gentoo Authors
+# Similar to test_gpkg_gpg.py but
+# with full emerge calls to test how we control signature verification.
+
+import portage
+import shutil
+import sys
+import tempfile
+import subprocess
+
+from portage import os
+from portage import shutil
+from portage.const import PORTAGE_PYM_PATH, USER_CONFIG_PATH
+from portage.gpg import GPG
+from portage.process import find_binary
+from portage.tests import TestCase, CommandStep, FunctionStep
+from portage.tests.resolver.ResolverPlayground import ResolverPlayground
+from portage.util import ensure_dirs
+
+
+class test_gpkg_gpg_emerge_case(TestCase):
+    def test_gpkg_require_signed_repo(self):
+        debug = False
+        gpg = None
+        tmpdir = tempfile.mkdtemp()
+
+        binhost_dir = os.path.join(tmpdir, "binhost-verifyme")
+        other_binhost_dir = os.path.join(tmpdir, "binhost-dontverify-me")
+        os.mkdir(f"{binhost_dir}-incoming")
+        os.mkdir(f"{other_binhost_dir}-incoming")
+        os.makedirs(os.path.join(binhost_dir, "app-misc", "hello"))
+        os.makedirs(os.path.join(other_binhost_dir, "app-misc", "hello"))
+
+        playground = ResolverPlayground(
+            user_config={
+                "make.conf": (
+                    'FEATURES="${FEATURES} buildpkg -binpkg-signing 
-binpkg-index-trusted"',
+                    'BINPKG_FORMAT="gpkg"',
+                    'BINPKG_COMPRESS="none"',
+                ),
+                "binrepos.conf": (
+                    "[test-binhost]",
+                    f"sync-uri = file://{binhost_dir}",
+                    f"location = {binhost_dir}-incoming",
+                    "verify-signature = true",
+                    "[test-other-binhost]",
+                    f"sync-uri = file://{other_binhost_dir}",
+                    f"location = {other_binhost_dir}-incoming",
+                    "verify-signature = false",
+                ),
+            },
+            ebuilds={
+                "app-misc/hello-1": {
+                    "EAPI": 8,
+                }
+            },
+        )
+
+        try:
+            settings = playground.settings
+            gpg = GPG(settings)
+            gpg.unlock()
+
+            portage_python = portage._python_interpreter
+            emerge_cmd = (
+                portage_python,
+                "-b",
+                "-Wd",
+                os.path.join(str(self.bindir), "emerge"),
+            )
+
+            settings = playground.settings
+            eprefix = settings["EPREFIX"]
+            eroot = settings["EROOT"]
+            var_cache_edb = os.path.join(eprefix, "var", "cache", "edb")
+            user_config_dir = os.path.join(eprefix, USER_CONFIG_PATH)
+
+            test_commands = (
+                # Create a binpkg. This step should succeed because
+                # we aren't requiring just-created local binpkgs
+                # to be signed.
+                CommandStep(
+                    returncode=os.EX_OK,
+                    command=emerge_cmd
+                    + (
+                        "--oneshot",
+                        "app-misc/hello",
+                    ),
+                ),
+                # Move it to the 'external' binhost we'll fetch from
+                FunctionStep(
+                    function=lambda i: self.assertTrue(
+                        shutil.move(
+                            os.path.join(
+                                eroot,
+                                "pkgdir",
+                                "app-misc",
+                                "hello",
+                                "hello-1-1.gpkg.tar",
+                            ),
+                            os.path.join(
+                                binhost_dir, "app-misc", "hello", 
"hello-1-1.gpkg.tar"
+                            ),
+                        ),
+                        f"step {i}",
+                    )
+                ),
+                FunctionStep(
+                    function=lambda i: self.assertTrue(
+                        shutil.copy(
+                            os.path.join(eroot, "pkgdir", "Packages"),
+                            os.path.join(binhost_dir, "Packages"),
+                        ),
+                        f"step {i}",
+                    ),
+                ),
+                # Cleanup the internal PKGDIR where it was
+                # originally made, as it's now gone
+                CommandStep(
+                    returncode=os.EX_OK,
+                    command=("emaint",)
+                    + (
+                        "binhost",
+                        "--fix",
+                    ),
+                ),
+                # Try to fetch it from the external binhost upon which
+                # verification should fail because it was never signed.
+                CommandStep(
+                    returncode=not os.EX_OK,
+                    command=emerge_cmd
+                    + (
+                        "--getbinpkgonly",
+                        "--verbose",
+                        "app-misc/hello",
+                    ),
+                ),
+                # FEATURES="binpkg-ignore-signature" should take precedence
+                # over binrepos.conf.
+                CommandStep(
+                    returncode=os.EX_OK,
+                    env={"FEATURES": "binpkg-ignore-signature"},
+                    command=emerge_cmd
+                    + (
+                        "--getbinpkgonly",
+                        "--verbose",
+                        "app-misc/hello",
+                    ),
+                ),
+                #
+                # Test with the other binhost now.
+                #
+                # Move it to the 'external' binhost we'll fetch from
+                FunctionStep(
+                    function=lambda i: self.assertTrue(
+                        shutil.move(
+                            os.path.join(
+                                binhost_dir,
+                                "app-misc",
+                                "hello",
+                                "hello-1-1.gpkg.tar",
+                            ),
+                            os.path.join(
+                                other_binhost_dir,
+                                "app-misc",
+                                "hello",
+                                "hello-1-1.gpkg.tar",
+                            ),
+                        ),
+                        f"step {i}",
+                    )
+                ),
+                FunctionStep(
+                    function=lambda i: self.assertTrue(
+                        shutil.copy(
+                            os.path.join(binhost_dir, "Packages"),
+                            os.path.join(other_binhost_dir, "Packages"),
+                        ),
+                        f"step {i}",
+                    ),
+                ),
+                # Cleanup the internal PKGDIR where it was
+                # originally made, as it's now gone
+                CommandStep(
+                    returncode=os.EX_OK,
+                    command=("emaint",)
+                    + (
+                        "binhost",
+                        "--fix",
+                    ),
+                ),
+                # FEATURES="binpkg-request-signature" should take precedence
+                # over binrepos.conf.
+                CommandStep(
+                    returncode=not os.EX_OK,
+                    env={
+                        "FEATURES": "binpkg-request-signature",
+                        "PORTAGE_TRUST_HELPER": "true",
+                    },
+                    command=emerge_cmd
+                    + (
+                        "--getbinpkgonly",
+                        "--verbose",
+                        "app-misc/hello",
+                    ),
+                ),
+            )
+
+            fake_bin = os.path.join(eprefix, "bin")
+            portage_tmpdir = os.path.join(eprefix, "var", "tmp", "portage")
+
+            path = settings.get("PATH")
+            if path is not None and not path.strip():
+                path = None
+            if path is None:
+                path = ""
+            else:
+                path = ":" + path
+            path = fake_bin + path
+
+            pythonpath = os.environ.get("PYTHONPATH")
+            if pythonpath is not None and not pythonpath.strip():
+                pythonpath = None
+            if pythonpath is not None and pythonpath.split(":")[0] == 
PORTAGE_PYM_PATH:
+                pass
+            else:
+                if pythonpath is None:
+                    pythonpath = ""
+                else:
+                    pythonpath = ":" + pythonpath
+                pythonpath = PORTAGE_PYM_PATH + pythonpath
+
+            env = {
+                "PORTAGE_OVERRIDE_EPREFIX": eprefix,
+                "PATH": path,
+                "PORTAGE_PYTHON": portage_python,
+                "PORTAGE_REPOSITORIES": settings.repositories.config_string(),
+                "PYTHONDONTWRITEBYTECODE": os.environ.get(
+                    "PYTHONDONTWRITEBYTECODE", ""
+                ),
+                "PYTHONPATH": pythonpath,
+                "PORTAGE_INST_GID": str(os.getgid()),
+                "PORTAGE_INST_UID": str(os.getuid()),
+                "FEATURES": "buildpkg",
+            }
+
+            dirs = [
+                playground.distdir,
+                fake_bin,
+                portage_tmpdir,
+                user_config_dir,
+                var_cache_edb,
+            ]
+            true_symlinks = ["chown", "chgrp"]
+            needed_binaries = {
+                "true": (find_binary("true"), True),
+            }
+
+            for d in dirs:
+                ensure_dirs(d)
+            for x in true_symlinks:
+                os.symlink(needed_binaries["true"][0], os.path.join(fake_bin, 
x))
+
+            with open(os.path.join(var_cache_edb, "counter"), "wb") as f:
+                f.write(b"100")
+
+            if debug:
+                # The subprocess inherits both stdout and stderr, for
+                # debugging purposes.
+                stdout = None
+            else:
+                # The subprocess inherits stderr so that any warnings
+                # triggered by python -Wd will be visible.
+                stdout = subprocess.PIPE
+
+            for i, step in enumerate(test_commands):
+                if isinstance(step, FunctionStep):
+                    try:
+                        step.function(i)
+                    except Exception as e:
+                        if isinstance(e, AssertionError) and f"step {i}" in 
str(e):
+                            raise
+                        raise AssertionError(
+                            f"step {i} raised {e.__class__.__name__}"
+                        ) from e
+                    continue
+
+                proc = subprocess.Popen(
+                    step.command,
+                    env=dict(env.items(), **(step.env or {})),
+                    cwd=step.cwd,
+                    stdout=stdout,
+                )
+
+                if debug:
+                    proc.wait()
+                else:
+                    output = proc.stdout.readlines()
+                    proc.wait()
+                    proc.stdout.close()
+                    if proc.returncode != step.returncode:
+                        for line in output:
+                            sys.stderr.write(portage._unicode_decode(line))
+
+                self.assertEqual(
+                    step.returncode,
+                    proc.returncode,
+                    f"{step.command} (step {i}) failed with exit code 
{proc.returncode}",
+                )
+        finally:
+            if gpg is not None:
+                gpg.stop()
+            shutil.rmtree(tmpdir)
+            playground.debug = False
+            playground.cleanup()

diff --git a/lib/portage/tests/resolver/ResolverPlayground.py 
b/lib/portage/tests/resolver/ResolverPlayground.py
index 9d4aa25acc..6b7653d93f 100644
--- a/lib/portage/tests/resolver/ResolverPlayground.py
+++ b/lib/portage/tests/resolver/ResolverPlayground.py
@@ -50,6 +50,7 @@ class ResolverPlayground:
     config_files = frozenset(
         (
             "eapi",
+            "binrepos.conf",
             "layout.conf",
             "make.conf",
             "modules",

diff --git a/man/make.conf.5 b/man/make.conf.5
index 3d610b1406..e980b87e0a 100644
--- a/man/make.conf.5
+++ b/man/make.conf.5
@@ -360,7 +360,7 @@ strips (or splits) them before installing.
 .B binpkg-ignore-signature
 This will disable GPG signature check for all binary packages. Enable this
 could be dangerous if you get binary packages from remote site or use third
-party packages.
+party packages.  If enabled, takes precedence over \fBbinrepos.conf\fR.
 .TP
 .B binpkg\-logs
 Keep logs from successful binary package merges. This is relevant only when
@@ -397,8 +397,8 @@ This feature is enabled by default.
 .B binpkg-request-signature
 Binary packages are requested to be signed by trusted GPG signature.
 Portage will reject to process any binary package without a valid GPG
-signature. The verify command is defined in
-\fBBINPKG_GPG_VERIFY_COMMAND\fR variable.
+signature. The verify command is defined in \fBBINPKG_GPG_VERIFY_COMMAND\fR
+variable.  If enabled, takes precedence over \fBbinrepos.conf\fR.
 .TP
 .B binpkg-signing
 Binary packages will be signed by given GPG command. The signing command

diff --git a/man/portage.5 b/man/portage.5
index 17423b30bc..298bd77ef4 100644
--- a/man/portage.5
+++ b/man/portage.5
@@ -675,6 +675,10 @@ remote repository. If unset then the effective default is 
PKGDIR
 .TP
 .B sync\-uri
 Specifies URI of repository used for `emerge \-\-getbinpkg`.
+.TP
+.B verify\-signature
+Controls whether PGP signatures should be verified for binary packages
+from this repository.
 .RE
 .RE
 

Reply via email to