Skip to content

Commit 44deb31

Browse files
heiytorotavio
authored andcommitted
fix(ssh): fix session authentication issues in older agent versions
Versions earlier than 0.6.0 do not validate the user when receiving a public key authentication request. This implies that requests with invalid users are treated as "authenticated" because the connection does not raise any error. Moreover, the agent panics after the connection ends. To avoid this, connections with public key are not permitted when agent version is 0.5.x or earlier
1 parent 4fac57e commit 44deb31

File tree

1 file changed

+59
-29
lines changed

1 file changed

+59
-29
lines changed

ssh/server/handler/ssh.go

Lines changed: 59 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -21,35 +21,37 @@ import (
2121

2222
// Errors returned by handlers to client.
2323
var (
24-
ErrRequestShell = fmt.Errorf("failed to open a shell in the device")
25-
ErrRequestExec = fmt.Errorf("failed to exec the command in the device")
26-
ErrRequestHeredoc = fmt.Errorf("failed to exec the command as heredoc in the device")
27-
ErrRequestUnsupported = fmt.Errorf("failed to get the request type")
28-
ErrPublicKey = fmt.Errorf("failed to get the parsed public key")
29-
ErrPrivateKey = fmt.Errorf("failed to get a key data from the server")
30-
ErrSigner = fmt.Errorf("failed to create a signer from the private key")
31-
ErrConnect = fmt.Errorf("failed to connect to device")
32-
ErrSession = fmt.Errorf("failed to create a session between the server to the agent")
33-
ErrGetAuth = fmt.Errorf("failed to get auth data from key")
34-
ErrWebData = fmt.Errorf("failed to get the data to connect to device")
35-
ErrFindDevice = fmt.Errorf("failed to find the device")
36-
ErrFindPublicKey = fmt.Errorf("failed to get the public key from the server")
37-
ErrEvaluatePublicKey = fmt.Errorf("failed to evaluate the public key in the server")
38-
ErrForbiddenPublicKey = fmt.Errorf("failed to use the public key for this action")
39-
ErrDataPublicKey = fmt.Errorf("failed to parse the public key data")
40-
ErrSignaturePublicKey = fmt.Errorf("failed to decode the public key signature")
41-
ErrVerifyPublicKey = fmt.Errorf("failed to verify the public key")
42-
ErrSignerPublicKey = fmt.Errorf("failed to signer the public key")
43-
ErrDialSSH = fmt.Errorf("failed to dial to connect to server")
44-
ErrEnvIPAddress = fmt.Errorf("failed to set the env virable of ip address from client")
45-
ErrEnvWS = fmt.Errorf("failed to set the env virable of web socket from client")
46-
ErrPipe = fmt.Errorf("failed to pipe client data to agent")
47-
ErrPty = fmt.Errorf("failed to request the pty to agent")
48-
ErrShell = fmt.Errorf("failed to get the shell to agent")
49-
ErrTarget = fmt.Errorf("failed to get client target")
50-
ErrAuthentication = fmt.Errorf("failed to authenticate to device")
51-
ErrEnvs = fmt.Errorf("failed to parse server envs")
52-
ErrConfiguration = fmt.Errorf("failed to create communication configuration")
24+
ErrRequestShell = fmt.Errorf("failed to open a shell in the device")
25+
ErrRequestExec = fmt.Errorf("failed to exec the command in the device")
26+
ErrRequestHeredoc = fmt.Errorf("failed to exec the command as heredoc in the device")
27+
ErrRequestUnsupported = fmt.Errorf("failed to get the request type")
28+
ErrPublicKey = fmt.Errorf("failed to get the parsed public key")
29+
ErrPrivateKey = fmt.Errorf("failed to get a key data from the server")
30+
ErrSigner = fmt.Errorf("failed to create a signer from the private key")
31+
ErrConnect = fmt.Errorf("failed to connect to device")
32+
ErrSession = fmt.Errorf("failed to create a session between the server to the agent")
33+
ErrGetAuth = fmt.Errorf("failed to get auth data from key")
34+
ErrWebData = fmt.Errorf("failed to get the data to connect to device")
35+
ErrFindDevice = fmt.Errorf("failed to find the device")
36+
ErrFindPublicKey = fmt.Errorf("failed to get the public key from the server")
37+
ErrEvaluatePublicKey = fmt.Errorf("failed to evaluate the public key in the server")
38+
ErrForbiddenPublicKey = fmt.Errorf("failed to use the public key for this action")
39+
ErrDataPublicKey = fmt.Errorf("failed to parse the public key data")
40+
ErrSignaturePublicKey = fmt.Errorf("failed to decode the public key signature")
41+
ErrVerifyPublicKey = fmt.Errorf("failed to verify the public key")
42+
ErrSignerPublicKey = fmt.Errorf("failed to signer the public key")
43+
ErrDialSSH = fmt.Errorf("failed to dial to connect to server")
44+
ErrEnvIPAddress = fmt.Errorf("failed to set the env virable of ip address from client")
45+
ErrEnvWS = fmt.Errorf("failed to set the env virable of web socket from client")
46+
ErrPipe = fmt.Errorf("failed to pipe client data to agent")
47+
ErrPty = fmt.Errorf("failed to request the pty to agent")
48+
ErrShell = fmt.Errorf("failed to get the shell to agent")
49+
ErrTarget = fmt.Errorf("failed to get client target")
50+
ErrAuthentication = fmt.Errorf("failed to authenticate to device")
51+
ErrEnvs = fmt.Errorf("failed to parse server envs")
52+
ErrConfiguration = fmt.Errorf("failed to create communication configuration")
53+
ErrInvalidVersion = fmt.Errorf("failed to parse device version")
54+
ErrUnsuportedPublicKeyAuth = fmt.Errorf("connections using public keys are not permitted when the agent version is 0.5.x or earlier")
5355
)
5456

5557
type ConfigOptions struct {
@@ -103,6 +105,34 @@ func SSHHandler(tunnel *httptunnel.Tunnel) gliderssh.Handler {
103105
}
104106

105107
func connectSSH(ctx context.Context, client gliderssh.Session, sess *session.Session, config *gossh.ClientConfig, api internalclient.Client, opts ConfigOptions) error {
108+
// Versions earlier than 0.6.0 do not validate the user when receiving a public key
109+
// authentication request. This implies that requests with invalid users are
110+
// treated as "authenticated" because the connection does not raise any error.
111+
// Moreover, the agent panics after the connection ends. To avoid this, connections
112+
// with public key are not permitted when agent version is 0.5.x or earlier
113+
switch metadata.RestoreAuthenticationMethod(ctx.(gliderssh.Context)) {
114+
case metadata.PublicKeyAuthenticationMethod:
115+
device := metadata.RestoreDevice(ctx.(gliderssh.Context))
116+
117+
if device.Info.Version != "latest" {
118+
ver, err := semver.NewVersion(device.Info.Version)
119+
if err != nil {
120+
log.WithError(err).
121+
WithFields(log.Fields{"client": device.UID}).
122+
Error("Failed to parse device version")
123+
124+
return ErrInvalidVersion
125+
}
126+
127+
if ver.LessThan(semver.MustParse("0.6.0")) {
128+
log.WithFields(log.Fields{"client": device.UID}).
129+
Error("Connections using public keys are not permitted when the agent version is 0.5.x or earlier.")
130+
131+
return ErrUnsuportedPublicKeyAuth
132+
}
133+
}
134+
}
135+
106136
connection, reqs, err := sess.NewClientConnWithDeadline(config)
107137
if err != nil {
108138
log.WithError(err).

0 commit comments

Comments
 (0)