Make the runtime gssapi-with-mic guard match the existing
configuration and method advertisement checks.
An incomplete GSSAPIWithMICConfig can be treated as unavailable when
building the advertised auth method list, while still remaining
reachable from the runtime auth dispatcher. Treat incomplete
configurations as not configured.
This change introduces a single internal completeness check for
GSSAPIWithMICConfig and uses it for the startup authentication
validation, the runtime gssapi-with-mic dispatch guard, and the
advertised authentication method list.
The change also adds a regression test. The test configures a server
with a normal PasswordCallback, a GSSAPIWithMICConfig with Server set,
and AllowLogin intentionally unset. It then uses a custom client auth
method that explicitly sends a USERAUTH_REQUEST with Method set to
gssapi-with-mic even though the server does not advertise that method,
and verifies that authentication fails cleanly with
"ssh: gssapi-with-mic auth not configured".
No golang/go issue reference is available yet.
Change-Id: I9a0c965d3a56192bd68309aa41e2c1f91952036c
GitHub-Last-Rev: 0267bda8e15e7c258ba3b92cd54f0941534c5fc9
GitHub-Pull-Request: golang/crypto#345
Reviewed-on: https://go-review.googlesource.com/c/crypto/+/773460
Reviewed-by: Mark Freeman <markfreeman@google.com>
Reviewed-by: Nicola Murino <nicola.murino@gmail.com>
Reviewed-by: David Chase <drchase@google.com>
Reviewed-by: Filippo Valsorda <filippo@golang.org>
LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Add ClientAuthCallback, a hook invoked before each authentication
attempt that allows the client to dynamically select an auth method
based on server capabilities, partial successes, or previous failures.
clientAuthenticate tracks partial successes in a slice and passes
them to AuthCallback via ClientAuthContext.PartialSuccessMethods,
along with the list of failed methods and currently allowed methods.
When AuthCallback returns a non-nil AuthMethod, it is used for the
next attempt, bypassing the static findNext selection. When it
returns (nil, nil), the static config.Auth selection proceeds as
before. If AuthCallback returns (nil, error) the handshake aborts
immediately with that error.
To bound resource use when AuthCallback keeps supplying methods, the
client caps the total number of authentication attempts (failures and
partial successes combined) at 64; exceeding the cap aborts the
handshake with an error.
Fixesgolang/go#76146
Change-Id: I0d02bea7b9dd724e95e5d9d49d85306666c0df7a
Reviewed-on: https://go-review.googlesource.com/c/crypto/+/717140
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: Filippo Valsorda <filippo@golang.org>
LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Previously, pickSignatureAlgorithm constructed the list of candidate
algorithms by iterating over the static list returned by
algorithmsForKeyFormat. This caused the Signer's preference order
to be ignored in favor of the library's default internal order.
This change inverts the filtering logic to iterate over the signer's
supported algorithms first. This ensures that if a MultiAlgorithmSigner
explicitly prefers a specific algorithm (e.g., rsa-sha2-512 over
rsa-sha2-256), that preference is preserved and respected during the
handshake negotiation.
Fixesgolang/go#78248
Change-Id: I48a0aac720be7f973963342b82047ce32fc96699
Reviewed-on: https://go-review.googlesource.com/c/crypto/+/746020
Reviewed-by: Lonny Wong <lonnywang.cn@gmail.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Auto-Submit: Nicola Murino <nicola.murino@gmail.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Filippo Valsorda <filippo@golang.org>
Reviewed-by: Carlos Amedee <carlos@golang.org>
Seems the OpenSSH server running on windows fails keyboard-interactive
auth this way without sending any prompt to client. In such case the
golang ssh client should not retry keyboard-interactive auth when the
auth method is wrapped in a RetryableAuthMethod(). Rather the auth
method should be immediately marked as tried&failed and the client auth
process should move on to next available and acceptable auth method.
Fixesgolang/go#67855
Change-Id: I6c64ae58ff8325774e37af716601b112f8833d8f
GitHub-Last-Rev: 7fafc4d1c81284b31000d7d6ccadd934dda26d24
GitHub-Pull-Request: golang/crypto#297
Reviewed-on: https://go-review.googlesource.com/c/crypto/+/590956
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
Auto-Submit: Nicola Murino <nicola.murino@gmail.com>
Reviewed-by: Nicola Murino <nicola.murino@gmail.com>
After adding support for rsa-sha2-256/512 on the server side some edge
cases started to arise with old clients:
1) public key authentication with gpg-agent < 2.2.6 fails because we
receive ssh-rsa as signature format and rsa-sha2-256 or rsa-sha2-512
as algorithm.
This is a bug in gpg-agent fixed in this commit:
https://github.com/gpg/gnupg/commit/80b775bdbb852aa4a80292c9357e5b1876110c00
2) certificate authentication fails with OpenSSH 7.2-7.7 because we
receive ssh-rsa-cert-v01@openssh.com as algorithm and rsa-sha2-256
or rsa-sha2-512 as signature format.
This patch is based on CL 412854 and has been tested with every version
of OpenSSH from 7.1 to 7.9 and OpenSSH 9.3.
Fixesgolang/go#53391
Change-Id: Id71f596f73d84efb5c76d6d5388432cccad3e3b1
Reviewed-on: https://go-review.googlesource.com/c/crypto/+/506835
Auto-Submit: Filippo Valsorda <filippo@golang.org>
Reviewed-by: Filippo Valsorda <filippo@golang.org>
Run-TryBot: Filippo Valsorda <filippo@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Roland Shoemaker <roland@golang.org>
CL 220037 had implemented support for host authentication using
rsa-sha2-256/512, but not client public key authentication. OpenSSH
disabled the SHA-1 based ssh-rsa by default in version 8.8 (after
pre-announcing it in versions 8.2, 8.3, 8.4, 8.5, 8.6, and 8.7) although
some distributions re-enable it. GitHub will start rejecting ssh-rsa for
keys uploaded before November 2, 2021 on March 15, 2022.
https://github.blog/2021-09-01-improving-git-protocol-security-github/
The server side already worked, as long as the client selected one of
the SHA-2 algorithms, because the signature flowed freely to Verify.
There was however nothing verifying that the signature algorithm matched
the advertised one. The comment suggested the check was being performed,
but it got lost back in CL 86190043. Not a security issue because the
signature had to pass the callback's Verify method regardless, and both
values were checked to be acceptable.
Tested with OpenSSH 8.8 configured with "PubkeyAcceptedKeyTypes -ssh-rsa"
and no application-side changes.
The Signers returned by ssh/agent (when backed by an agent client)
didn't actually implement AlgorithmSigner but ParameterizedSigner, an
interface defined in an earlier version of CL 123955.
Updates golang/go#49269Fixesgolang/go#39885
For golang/go#49952
Change-Id: I13b41db8041f1112a70f106c55f077b904b12cb8
Reviewed-on: https://go-review.googlesource.com/c/crypto/+/392394
Trust: Filippo Valsorda <filippo@golang.org>
Run-TryBot: Filippo Valsorda <filippo@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Roland Shoemaker <roland@golang.org>
Add the diffie-hellman-group-exchange-sha256 defined in RFC 4419 to
the list of supported key exchange algorithms for ssh.
The server half is only a minimal implementation to satisfy the automated tests.
Fixesgolang/go#17230
Change-Id: I25880a564347fd9b4738dd2ed1e347cd5d2e21bb
GitHub-Last-Rev: 9f0b8d02c0c96e9baf00cdf1cf063ff834245443
GitHub-Pull-Request: golang/crypto#87
Reviewed-on: https://go-review.googlesource.com/c/crypto/+/174257
Run-TryBot: Han-Wen Nienhuys <hanwen@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Han-Wen Nienhuys <hanwen@google.com>
Previously, this would return the default error "no auth passed yet".
Not only is the new error more specific, it makes it easier to verify
the control flow of server authentication code.
Change-Id: I6c8de4e3f91da74274acbe9d87ec4f6158b4a94f
Reviewed-on: https://go-review.googlesource.com/c/142897
Run-TryBot: Han-Wen Nienhuys <hanwen@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
yet.
Since ServerAuthError returns all errors collected during the
userAuthLoop, it will always include the generic error "no auth passed
yet" (assuming the connection fails).
Change-Id: I5f6c67f3f0762b023618178d4028600d2b6c9253
Reviewed-on: https://go-review.googlesource.com/92737
Reviewed-by: Han-Wen Nienhuys <hanwen@google.com>
Run-TryBot: Han-Wen Nienhuys <hanwen@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
This is a breaking change.
This adds a new hostkey callback which takes the hostname field
restrictions into account when validating host certificates.
Prior to this, a known_hosts file with the following entry
@cert-authority *.example.com ssh-rsa <example.com public key>
would, when passed to knownhosts.New() generate an ssh.HostKeyCallback
that would accept all host certificates signed by the example.com public
key, no matter what host the client was connecting to.
After this change, that known_hosts entry can only be used to validate
host certificates presented when connecting to hosts under *.example.com
This also renames IsAuthority to IsUserAuthority to make its intended
purpose more clear.
Change-Id: I7188a53fdd40a8c0bc21983105317b3498f567bb
Reviewed-on: https://go-review.googlesource.com/41751
Reviewed-by: Han-Wen Nienhuys <hanwen@google.com>
Run-TryBot: Han-Wen Nienhuys <hanwen@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
This change breaks backwards compatibility.
MaxAuthTries specifies the maximum number of authentication attempts
permitted per connection. If set to a negative number, the server will
allow unlimited authentication attempts. MaxAuthTries defaults to 6 if
not specified, which is a backwards incompatible change. On exceeding
maximum authentication attempts, the server will send a disconnect
message to the client.
This configuration property mirrors a similar property in sshd_config
and prevents bad actors from continuously trying authentication.
Change-Id: Ic77d2c29ee2fd2ae5c764becf7df91d29d03131b
Reviewed-on: https://go-review.googlesource.com/35230
Reviewed-by: Han-Wen Nienhuys <hanwen@google.com>
Run-TryBot: Han-Wen Nienhuys <hanwen@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
This change breaks existing behavior.
Before, a missing ClientConfig.HostKeyCallback would cause host key
checking to be disabled. In this configuration, establishing a
connection to any host just works, so today, most SSH client code in
the wild does not perform any host key checks.
This makes it easy to perform a MITM attack:
* SSH installations that use keyboard-interactive or password
authentication can be attacked with MITM, thereby stealing
passwords.
* Clients that use public-key authentication with agent forwarding are
also vulnerable: the MITM server could allow the login to succeed, and
then immediately ask the agent to authenticate the login to the real
server.
* Clients that use public-key authentication without agent forwarding
are harder to attack unnoticedly: an attacker cannot authenticate the
login to the real server, so it cannot in general present a convincing
server to the victim.
Now, a missing HostKeyCallback will cause the handshake to fail. This
change also provides InsecureIgnoreHostKey() and FixedHostKey(key) as
ready made host checkers.
A simplistic parser for OpenSSH's known_hosts file is given as an
example. This change does not provide a full-fledged parser, as it
has complexity (wildcards, revocation, hashed addresses) that will
need further consideration.
When introduced, the host checking feature maintained backward
compatibility at the expense of security. We have decided this is not
the right tradeoff for the SSH library.
Fixesgolang/go#19767
Change-Id: I45fc7ba9bd1ea29c31ec23f115cdbab99913e814
Reviewed-on: https://go-review.googlesource.com/38701
Run-TryBot: Han-Wen Nienhuys <hanwen@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
The ssh tests currently require 127.0.0.1 to work which isn't
necessarily available everywhere. To fix the source-address tests,
support comma-separated source-address values per the PROTOCOL.certkeys
file:
Comma-separated list of source addresses
from which this certificate is accepted
for authentication. Addresses are
specified in CIDR format (nn.nn.nn.nn/nn
or hhhh::hhhh/nn).
If this option is not present then
certificates may be presented from any
source address.
Change-Id: I87536ff81ffa005c073da103021ebc0dfb12b620
Reviewed-on: https://go-review.googlesource.com/36110
Reviewed-by: Han-Wen Nienhuys <hanwen@google.com>
Run-TryBot: Heschi Kreinick <heschi@google.com>
RSA and DSA keys if encrypted have the
phrase ENCRYPTED in their Proc-Type block
header according to RFC 1421 Section 4.6.1.1.
This CL checks for that phrase and errors out
if we encounter it, since we don't yet have
decryption of encrypted private keys.
Fixesgolang/go#6650
Change-Id: I5b157716a2f93557d289af5f62994234a2e7a0ed
Reviewed-on: https://go-review.googlesource.com/29676
Reviewed-by: Han-Wen Nienhuys <hanwen@google.com>
Run-TryBot: Han-Wen Nienhuys <hanwen@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
The current behaviour of the crypto/ssh server implementation is to
remove the username from ConnMetadata if the connection is done without
authentication (NoClientAuth). This appears to be a bug.
This behaviour is different from other SSH server implementations like
for example Paramiko (Python) which keeps the username.
Additionally RFC4252 (https://www.ietf.org/rfc/rfc4252.txt) section
5 states the username has to be included in every USERAUTH message.
Change-Id: I27fa50db92eb535e90fe088453faa6f2a76ee31f
Reviewed-on: https://go-review.googlesource.com/27612
Reviewed-by: Han-Wen Nienhuys <hanwen@google.com>
Run-TryBot: Han-Wen Nienhuys <hanwen@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
This failure is tracked already. Remove it from the dashboard
while it's fixed so it doesn't hide more interesting failures.
Updates golang/go#15198
Change-Id: Ib48d1e37ac97914ac082b2602c812151147393e4
Reviewed-on: https://go-review.googlesource.com/24986
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Adds a new AuthMethod called "RetryableAuthMethod" which decorates any
other authmethod, allowing it to be retried up to maxTries before
aborting.
Fixes#16077
Change-Id: Ie310c24643e53dca4fa452750a69936674906484
Reviewed-on: https://go-review.googlesource.com/24156
Reviewed-by: Han-Wen Nienhuys <hanwen@google.com>
Run-TryBot: Han-Wen Nienhuys <hanwen@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
The error message reported by the ssh client when it can't find a
"cipher" in common between the client and server was overly vague. This
adds more detailed error messages to findAgreedAlgorithms so that the
user can more easily identify which of the components can't reach
agreement.
Change-Id: I4d985e92fea964793213e5600b52b3141e712000
Reviewed-on: https://go-review.googlesource.com/13817
Reviewed-by: Adam Langley <agl@golang.org>