Skip to content

fix(sshconfig): apply algorithm list modifiers to the built-in defaults - #513

Merged
kke merged 3 commits into
mainfrom
fix/sshconfig-modifier-defaults
Nov 2, 2026
Merged

kke merged 3 commits into
mainfrom
fix/sshconfig-modifier-defaults

Conversation

@kke

@kke kke commented Nov 2, 2026

Copy link
Copy Markdown
Contributor

Fixes how the +, - and ^ modifiers of the ssh_config algorithm lists (KexAlgorithms, Ciphers, MACs, HostKeyAlgorithms, PubkeyAcceptedAlgorithms, HostbasedAcceptedAlgorithms, CASignatureAlgorithms) build their result. Four bugs, all in that path:

  1. The base list came from ssh -Q <key>. That is every algorithm the local ssh binary supports, in OpenSSH's table order, not a preference order. It starts with diffie-hellman-group1-sha1, so KexAlgorithms +x made rig prefer the weakest key exchanges. It also says nothing about rig, which negotiates through x/crypto rather than the ssh binary.
  2. Without an ssh binary the fallback was unreachable. defaultList was called with "KexAlgorithms" but its switch only knew "kexalgorithms", so in a container without ssh the modifiers worked against an empty list.
  3. -a,b duplicated the defaults. Each default was appended once per pattern it did not match.
  4. - wildcards never matched. The pattern was passed to patternMatch as the value, so -ecdh-* removed nothing.

The modifiers now work against the platform's built-in default config, the same lists rig already uses when nothing is configured. Keys match without regard to case and through the deprecated HostbasedKeyTypes / PubkeyAcceptedKeyTypes names the Windows defaults use. As a side effect, importing sshconfig no longer runs ssh -V and ssh -Q at package init.

1 and 2 are one change, since fixing 1 removes the code 2 was in. 3 and 4 are a second commit.

Found while checking whether release-0.x #512 (FIPS / X25519 key exchange) needs a v2 port. It doesn't for the default path: v2 always sends the built-in KexAlgorithms list, which has no mlkem768x25519-sha256, and in FIPS mode x/crypto narrows it to the NIST ECDH curves.

Tests

  • TestDefaultList: every modifier key has a non-empty built-in list, case-insensitive, aliases resolve.
  • TestParserAlgorithmListModifiers: +, ^, multi-pattern - and wildcard - end to end through the parser, against the built-in list. With the old code all four fail; with only the new base, the two - cases still fail.
  • The existing - test in TestSetterField* no longer skips itself when the runner's ssh -Q list is short.

🤖 Generated with Claude Code

kke added 2 commits November 2, 2026 11:49
The +, - and ^ modifiers of the algorithm lists worked against
`ssh -Q <key>` from the local ssh binary: every algorithm that binary
supports, in OpenSSH's table order rather than any preference order.
That starts with diffie-hellman-group1-sha1, so KexAlgorithms +x made
rig prefer the weakest key exchanges. It also says nothing about rig,
which negotiates through x/crypto, not the ssh binary.

Without an ssh binary, as in a container, the lookup fell back to
constants it never reached: defaultList was called with "KexAlgorithms"
while its switch only knew "kexalgorithms", so the modifiers worked
against an empty list.

The defaults now come from the platform's built-in default config, the
same lists rig uses when nothing is configured, matched without regard
to case and through the deprecated HostbasedKeyTypes and
PubkeyAcceptedKeyTypes names that the Windows defaults use. Importing
sshconfig no longer runs ssh at package init.

Signed-off-by: Kimmo Lehto <klehto@mirantis.com>
The - modifier appended a default once for every pattern it did not
match, so -a,b listed each remaining default twice. It also passed the
pattern as the value to patternMatch, so a wildcard such as -ecdh-*
removed nothing.

Signed-off-by: Kimmo Lehto <klehto@mirantis.com>
@kke
kke requested a balanced review from Copilot November 2, 2026 09:49

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Removing all default algorithms leaves an empty field that the parser repopulates with built-in defaults, silently undoing the removal; the setter needs to reject empty results and include a parser regression test.

1 open issue
What changed in this PR

This PR makes SSH algorithm-list modifiers use rig’s built-in defaults rather than the local OpenSSH binary’s supported algorithms, preserving rig’s default preferences.

Changes:

  • Resolve default lists case-insensitively, including deprecated aliases, without running SSH commands at package initialization.
  • Correct multi-pattern removal and wildcard matching.
  • Add regression tests for default lookup and modifiers, and make existing removal checks unconditional.
File Description
sshconfig/​setterbuilders.go Fix wildcard matching and prevent duplicate entries during removal.
sshconfig/​set_test.go Run removal assertions unconditionally against built-in defaults.
sshconfig/​parser_test.go Add end-to-end coverage for algorithm-list modifiers.
sshconfig/​defaults.go Replace OpenSSH queries with case-insensitive built-in default lookup.
sshconfig/​defaults_test.go Test default lists, deprecated aliases, and unknown keys.

Review effort: Balanced

Comment thread sshconfig/setterbuilders.go Resolved
With wildcards now matching, -* empties the list. An empty field reads
as unset, so the built-in defaults filled it back in and quietly undid
the removal. ssh accepts the line but is left with nothing to negotiate,
so refuse it where the config says so.

Signed-off-by: Kimmo Lehto <klehto@mirantis.com>
@kke
kke requested a balanced review from Copilot November 2, 2026 09:54

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

No active review issues were identified for the switch to built-in SSH algorithm defaults.

No open issues 🎉

1 resolved since last review

Review effort: Balanced

@kke
kke merged commit 7dfac40 into main Nov 2, 2026
18 checks passed
@kke
kke deleted the fix/sshconfig-modifier-defaults branch November 2, 2026 11:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants