mirror of
https://github.com/rclone/rclone.git
synced 2025-01-22 22:28:47 +01:00
serve sftp: fix authentication on one connection blocking others - fixes #4882
Before this change, if one connection was authenticating this would block any others from authenticating. This was due to ssh.NewServerConn not being called in a go routine after the Accept call. This is fixed by running the ssh authentication in a go routine. Thanks to @FiloSottile for advice on how to fix this. See: https://github.com/golang/go/issues/43521
This commit is contained in:
parent
15f31d3ca4
commit
9d9999d17b
@ -75,23 +75,16 @@ func (s *server) getVFS(what string, sshConn *ssh.ServerConn) (VFS *vfs.VFS) {
|
|||||||
return VFS
|
return VFS
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *server) acceptConnections() {
|
// Accept a single connection - run in a go routine as the ssh
|
||||||
for {
|
// authentication can block
|
||||||
nConn, err := s.listener.Accept()
|
func (s *server) acceptConnection(nConn net.Conn) {
|
||||||
if err != nil {
|
|
||||||
if strings.Contains(err.Error(), "use of closed network connection") {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
fs.Errorf(nil, "Failed to accept incoming connection: %v", err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
what := describeConn(nConn)
|
what := describeConn(nConn)
|
||||||
|
|
||||||
// Before use, a handshake must be performed on the incoming net.Conn.
|
// Before use, a handshake must be performed on the incoming net.Conn.
|
||||||
sshConn, chans, reqs, err := ssh.NewServerConn(nConn, s.config)
|
sshConn, chans, reqs, err := ssh.NewServerConn(nConn, s.config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fs.Errorf(what, "SSH login failed: %v", err)
|
fs.Errorf(what, "SSH login failed: %v", err)
|
||||||
continue
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
fs.Infof(what, "SSH login from %s using %s", sshConn.User(), sshConn.ClientVersion())
|
fs.Infof(what, "SSH login from %s using %s", sshConn.User(), sshConn.ClientVersion())
|
||||||
@ -106,12 +99,26 @@ func (s *server) acceptConnections() {
|
|||||||
if c.vfs == nil {
|
if c.vfs == nil {
|
||||||
fs.Infof(what, "Closing unauthenticated connection (couldn't find VFS)")
|
fs.Infof(what, "Closing unauthenticated connection (couldn't find VFS)")
|
||||||
_ = nConn.Close()
|
_ = nConn.Close()
|
||||||
continue
|
return
|
||||||
}
|
}
|
||||||
c.handlers = newVFSHandler(c.vfs)
|
c.handlers = newVFSHandler(c.vfs)
|
||||||
|
|
||||||
// Accept all channels
|
// Accept all channels
|
||||||
go c.handleChannels(chans)
|
go c.handleChannels(chans)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Accept connections and call them in a go routine
|
||||||
|
func (s *server) acceptConnections() {
|
||||||
|
for {
|
||||||
|
nConn, err := s.listener.Accept()
|
||||||
|
if err != nil {
|
||||||
|
if strings.Contains(err.Error(), "use of closed network connection") {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fs.Errorf(nil, "Failed to accept incoming connection: %v", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
go s.acceptConnection(nConn)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user