[pacman-dev] [PATCH 1/2] pacman-key: when refreshing gpg.conf, don't truncate option checking
If an option is a two-part option, we print both (separated by IFS=' '), but when grepping to see if it already exists, we only checked the first component. This means that something like keyserver-options could only check if there were existing keyserver options of any sort, but not which ones. Signed-off-by: Eli Schwartz <eschwartz@archlinux.org> --- scripts/pacman-key.sh.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/pacman-key.sh.in b/scripts/pacman-key.sh.in index b05754e5..c3b02850 100644 --- a/scripts/pacman-key.sh.in +++ b/scripts/pacman-key.sh.in @@ -169,7 +169,7 @@ add_gpg_conf_option() { local conffile=$1; shift # looking for the option 'bare', only leading spaces or # chars allowed, # followed by at least one space and any other text or the end of line. - if ! grep -q "^[[:space:]#]*$1\([[:space:]].*\)*$" "$conffile" &>/dev/null; then + if ! grep -q "^[[:space:]#]*$*\([[:space:]].*\)*$" "$conffile" &>/dev/null; then printf '%s\n' "$*" >> "$conffile" fi } -- 2.22.0
By default, the latest versions of GnuPG disable the Web of Trust and refuse to import signatures from public keyservers. This is to prevent denial of service attacks, because refusing to import signatures only if the key size is too big, is apparently too silly to consider. Either way, pacman needs the WoT. If pacman imports a key at all, it means everything failed and we are in fallback mode, trying to overcome a shortcoming in the availability of keys in the keyring package. (This commonly means the user needs to acquire a new key during the same transaction that updates archlinux-keyring.) In order for that new key to be usable, it *must* also import signatures from the Master Keys. I don't give credence to this supposed DoS, since the worst case scenario is nothing happening and needing to CTRL+C in order to exit the program. In the case of pacman, this is better than being unable to install anything at all (which is gnupg doing a much more harmful DoS to pacman), and in the already unusual case where something like --refresh-keys is being used directly instead of depending on the keyring package itself, gnupg supports WKD out of the box and will prefer that for people whose keys are marketed as being non-DOSable. Signed-off-by: Eli Schwartz <eschwartz@archlinux.org> --- I've been sitting on this for a bit, but this does seem to be the best way to implement a reversion to the old method. Feel free to bikeshed about version checks in pacman-key! This is independent of the WKD patchset, and works for people without @archlinux.org uids, or more generally for pacman downstreams that don't have a WKD infrastructure. In the long run, I expect the keyservers to implement less insane DoS mitigations, for example, an evolution of hagrid that supports mutually signed keys. I don't know if I should hold my breath waiting for gnupg to get proper error checking, though! Once proper mitigations exist, we'd need to disable the builtin default self-sigs-only,import-clean anyway, assuming gnupg itself didn't roll back these settings. scripts/pacman-key.sh.in | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/scripts/pacman-key.sh.in b/scripts/pacman-key.sh.in index c3b02850..d6ba0e3b 100644 --- a/scripts/pacman-key.sh.in +++ b/scripts/pacman-key.sh.in @@ -210,6 +210,11 @@ initialize() { add_gpg_conf_option "$conffile" 'lock-never' add_gpg_conf_option "$conffile" 'keyserver-options' 'timeout=10' + local gpg_ver=$(gpg --version | awk '{print $3; exit}') + if (( $(vercmp "$gpg_ver" 2.2.17) >= 0 )); then + add_gpg_conf_option "$conffile" 'keyserver-options' 'no-self-sigs-only,no-import-clean' + fi + # gpg-agent.conf agent_conffile="${PACMAN_KEYRING_DIR}/gpg-agent.conf" [[ -f $agent_conffile ]] || touch "$agent_conffile" -- 2.22.0
On 6/8/19 2:53 am, Eli Schwartz wrote:
By default, the latest versions of GnuPG disable the Web of Trust and refuse to import signatures from public keyservers. This is to prevent denial of service attacks, because refusing to import signatures only if the key size is too big, is apparently too silly to consider.
Either way, pacman needs the WoT. If pacman imports a key at all, it means everything failed and we are in fallback mode, trying to overcome a shortcoming in the availability of keys in the keyring package. (This commonly means the user needs to acquire a new key during the same transaction that updates archlinux-keyring.) In order for that new key to be usable, it *must* also import signatures from the Master Keys.
I don't give credence to this supposed DoS, since the worst case scenario is nothing happening and needing to CTRL+C in order to exit the program. In the case of pacman, this is better than being unable to install anything at all (which is gnupg doing a much more harmful DoS to pacman), and in the already unusual case where something like --refresh-keys is being used directly instead of depending on the keyring package itself, gnupg supports WKD out of the box and will prefer that for people whose keys are marketed as being non-DOSable.
Signed-off-by: Eli Schwartz <eschwartz@archlinux.org> ---
I've been sitting on this for a bit, but this does seem to be the best way to implement a reversion to the old method.
I think this fine.
Feel free to bikeshed about version checks in pacman-key!
Well... see below...
This is independent of the WKD patchset, and works for people without @archlinux.org uids, or more generally for pacman downstreams that don't have a WKD infrastructure.
In the long run, I expect the keyservers to implement less insane DoS mitigations, for example, an evolution of hagrid that supports mutually signed keys. I don't know if I should hold my breath waiting for gnupg to get proper error checking, though! Once proper mitigations exist, we'd need to disable the builtin default self-sigs-only,import-clean anyway, assuming gnupg itself didn't roll back these settings.
scripts/pacman-key.sh.in | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/scripts/pacman-key.sh.in b/scripts/pacman-key.sh.in index c3b02850..d6ba0e3b 100644 --- a/scripts/pacman-key.sh.in +++ b/scripts/pacman-key.sh.in @@ -210,6 +210,11 @@ initialize() { add_gpg_conf_option "$conffile" 'lock-never' add_gpg_conf_option "$conffile" 'keyserver-options' 'timeout=10'
+ local gpg_ver=$(gpg --version | awk '{print $3; exit}')
I very much dislike relying on output format from some other piece of software. But looking at the gpg code, this is quite stable, so allowable.
+ if (( $(vercmp "$gpg_ver" 2.2.17) >= 0 )); then + add_gpg_conf_option "$conffile" 'keyserver-options' 'no-self-sigs-only,no-import-clean'
Doesn't import-clean actually do what we want? Strips signatures from keys not in the keyring? Assuming users are not setting up the initial keyring by importing keys manually...
+ fi + # gpg-agent.conf agent_conffile="${PACMAN_KEYRING_DIR}/gpg-agent.conf" [[ -f $agent_conffile ]] || touch "$agent_conffile"
On 10/6/19 10:42 PM, Allan McRae wrote:
+ if (( $(vercmp "$gpg_ver" 2.2.17) >= 0 )); then + add_gpg_conf_option "$conffile" 'keyserver-options' 'no-self-sigs-only,no-import-clean'
Doesn't import-clean actually do what we want? Strips signatures from keys not in the keyring? Assuming users are not setting up the initial keyring by importing keys manually...
Hmm, on second thought you're right. no-self-sigs-only will prevent the main thing that annoys us, which is getting rid of sigs we want because we have the WoT keys which match it. no-import-clean would return us to feature parity with the older gnupg releases, but that's not the fundamental goal, and the only benefit it would get us is being able to later on import a master key and have it validate, which seems like an unlikely event. Anyway, it seems like refreshing that key would re-acquire the cleaned signatures. Do you want to leave the import-clean setting out entirely, or take the opportunity to start having the keyring be guaranteed to be cleaned? -- Eli Schwartz Bug Wrangler and Trusted User
On 7/10/19 12:53 pm, Eli Schwartz wrote:
On 10/6/19 10:42 PM, Allan McRae wrote:
+ if (( $(vercmp "$gpg_ver" 2.2.17) >= 0 )); then + add_gpg_conf_option "$conffile" 'keyserver-options' 'no-self-sigs-only,no-import-clean'
Doesn't import-clean actually do what we want? Strips signatures from keys not in the keyring? Assuming users are not setting up the initial keyring by importing keys manually...
Hmm, on second thought you're right. no-self-sigs-only will prevent the main thing that annoys us, which is getting rid of sigs we want because we have the WoT keys which match it.
no-import-clean would return us to feature parity with the older gnupg releases, but that's not the fundamental goal, and the only benefit it would get us is being able to later on import a master key and have it validate, which seems like an unlikely event. Anyway, it seems like refreshing that key would re-acquire the cleaned signatures.
Do you want to leave the import-clean setting out entirely, or take the opportunity to start having the keyring be guaranteed to be cleaned?
no-self-sigs-only,import-clean seems a good trade off as default
By default, the latest versions of GnuPG disable the Web of Trust and refuse to import signatures from public keyservers. This is to prevent denial of service attacks, because refusing to import signatures only if the key size is too big, is apparently too silly to consider. Either way, pacman needs the WoT. If pacman imports a key at all, it means everything failed and we are in fallback mode, trying to overcome a shortcoming in the availability of keys in the keyring package. (This commonly means the user needs to acquire a new key during the same transaction that updates archlinux-keyring.) In order for that new key to be usable, it *must* also import signatures from the Master Keys. I don't give credence to this supposed DoS, since the worst case scenario is nothing happening and needing to CTRL+C in order to exit the program. In the case of pacman, this is better than being unable to install anything at all (which is gnupg doing a much more harmful DoS to pacman), and in the already unusual case where something like --refresh-keys is being used directly instead of depending on the keyring package itself, gnupg supports WKD out of the box and will prefer that for people whose keys are marketed as being non-DOSable. Signed-off-by: Eli Schwartz <eschwartz@archlinux.org> --- v2: drop no-import-clean as it is out of scope of this proposed change and doesn't seem to aid the cause. It is sufficient to avoid self-sigs-only for our purposes. scripts/pacman-key.sh.in | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/scripts/pacman-key.sh.in b/scripts/pacman-key.sh.in index c3b02850..93600bc0 100644 --- a/scripts/pacman-key.sh.in +++ b/scripts/pacman-key.sh.in @@ -210,6 +210,11 @@ initialize() { add_gpg_conf_option "$conffile" 'lock-never' add_gpg_conf_option "$conffile" 'keyserver-options' 'timeout=10' + local gpg_ver=$(gpg --version | awk '{print $3; exit}') + if (( $(vercmp "$gpg_ver" 2.2.17) >= 0 )); then + add_gpg_conf_option "$conffile" 'keyserver-options' 'no-self-sigs-only' + fi + # gpg-agent.conf agent_conffile="${PACMAN_KEYRING_DIR}/gpg-agent.conf" [[ -f $agent_conffile ]] || touch "$agent_conffile" -- 2.23.0
There is no good reason to bloat the keyring by importing tons of signatures we cannot use; drop any signatures that don't validate against another available key (probably the master keys). If any desired signatures get cleaned, the key can be refreshed after importing the new signing public key. Signed-off-by: Eli Schwartz <eschwartz@archlinux.org> --- v3: introduce new followup which adds import-clean -- it has been around for some time, and seems generally useful even if not directly applicable to WoT fixes, so let us seize the opportunity to implement it. scripts/pacman-key.sh.in | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/pacman-key.sh.in b/scripts/pacman-key.sh.in index 93600bc0..117acc40 100644 --- a/scripts/pacman-key.sh.in +++ b/scripts/pacman-key.sh.in @@ -209,6 +209,7 @@ initialize() { add_gpg_conf_option "$conffile" 'no-permission-warning' add_gpg_conf_option "$conffile" 'lock-never' add_gpg_conf_option "$conffile" 'keyserver-options' 'timeout=10' + add_gpg_conf_option "$conffile" 'keyserver-options' 'import-clean' local gpg_ver=$(gpg --version | awk '{print $3; exit}') if (( $(vercmp "$gpg_ver" 2.2.17) >= 0 )); then -- 2.23.0
participants (2)
-
Allan McRae
-
Eli Schwartz