summaryrefslogtreecommitdiff
path: root/internal/ssh/server
diff options
context:
space:
mode:
authorPaul Buetow <pbuetow@mimecast.com>2022-02-04 21:37:29 +0000
committerPaul Buetow <pbuetow@mimecast.com>2022-02-04 21:37:29 +0000
commit1db3b5dc1219e34e0e1c612e6646327701c40274 (patch)
treecab22128af9e54131facd0062a474459383a1c90 /internal/ssh/server
parent6625d019271d3d7931587167845d77834d187d57 (diff)
parentcc6f19f69d0fb34af96e17147b2030c352d46845 (diff)
merge 4.0.0-RC
Diffstat (limited to 'internal/ssh/server')
-rw-r--r--internal/ssh/server/hostkey.go21
-rw-r--r--internal/ssh/server/publickeycallback.go91
2 files changed, 72 insertions, 40 deletions
diff --git a/internal/ssh/server/hostkey.go b/internal/ssh/server/hostkey.go
index 07790ad..be23d85 100644
--- a/internal/ssh/server/hostkey.go
+++ b/internal/ssh/server/hostkey.go
@@ -1,37 +1,42 @@
package server
import (
- "github.com/mimecast/dtail/internal/config"
- "github.com/mimecast/dtail/internal/io/logger"
- "github.com/mimecast/dtail/internal/ssh"
"io/ioutil"
"os"
+
+ "github.com/mimecast/dtail/internal/config"
+ "github.com/mimecast/dtail/internal/io/dlog"
+ "github.com/mimecast/dtail/internal/ssh"
)
// PrivateHostKey retrieves the private server RSA host key.
func PrivateHostKey() []byte {
hostKeyFile := config.Server.HostKeyFile
+ if config.Env("DTAIL_INTEGRATION_TEST_RUN_MODE") {
+ hostKeyFile = "./ssh_host_key"
+ }
_, err := os.Stat(hostKeyFile)
if os.IsNotExist(err) {
- logger.Info("Generating private server RSA host key")
+ dlog.Server.Info("Generating private server RSA host key")
privateKey, err := ssh.GeneratePrivateRSAKey(config.Server.HostKeyBits)
if err != nil {
- logger.FatalExit("Failed to generate private server RSA host key", err)
+ dlog.Server.FatalPanic("Failed to generate private server RSA host key", err)
}
pem := ssh.EncodePrivateKeyToPEM(privateKey)
if err := ioutil.WriteFile(hostKeyFile, pem, 0600); err != nil {
- logger.Error("Unable to write private server RSA host key to file", hostKeyFile, err)
+ dlog.Server.Error("Unable to write private server RSA host key to file",
+ hostKeyFile, err)
}
return pem
}
- logger.Info("Reading private server RSA host key from file", hostKeyFile)
+ dlog.Server.Info("Reading private server RSA host key from file", hostKeyFile)
pem, err := ioutil.ReadFile(hostKeyFile)
if err != nil {
- logger.FatalExit("Failed to load private server RSA host key", err)
+ dlog.Server.FatalPanic("Failed to load private server RSA host key", err)
}
return pem
}
diff --git a/internal/ssh/server/publickeycallback.go b/internal/ssh/server/publickeycallback.go
index e81f019..f7655b4 100644
--- a/internal/ssh/server/publickeycallback.go
+++ b/internal/ssh/server/publickeycallback.go
@@ -4,67 +4,94 @@ import (
"fmt"
"io/ioutil"
"os"
- osUser "os/user"
+ goUser "os/user"
"github.com/mimecast/dtail/internal/config"
- "github.com/mimecast/dtail/internal/io/logger"
+ "github.com/mimecast/dtail/internal/io/dlog"
user "github.com/mimecast/dtail/internal/user/server"
gossh "golang.org/x/crypto/ssh"
)
-// PublicKeyCallback is for the server to check whether a public SSH key is authorized ot not.
-func PublicKeyCallback(c gossh.ConnMetadata, offeredPubKey gossh.PublicKey) (*gossh.Permissions, error) {
- user := user.New(c.User(), c.RemoteAddr().String())
- logger.Info(user, "Incoming authorization")
+// PublicKeyCallback is for the server to check whether a public SSH key is
+// authorized ot not.
+func PublicKeyCallback(c gossh.ConnMetadata,
+ offeredPubKey gossh.PublicKey) (*gossh.Permissions, error) {
- cwd, err := os.Getwd()
+ user, err := user.New(c.User(), c.RemoteAddr().String())
if err != nil {
- return nil, fmt.Errorf("Unable to get current working directory|%s|", err.Error())
- }
-
- if config.ServerRelaxedAuthEnable {
- logger.Fatal(user, "Granting permissions via relaxed-auth")
- return nil, nil
+ return nil, err
}
+ dlog.Server.Info(user, "Incoming authorization")
- authorizedKeysFile := fmt.Sprintf("%s/%s/%s.authorized_keys", cwd, config.Common.CacheDir, user.Name)
- if _, err := os.Stat(authorizedKeysFile); os.IsNotExist(err) {
- user, err := osUser.Lookup(user.Name)
- if err != nil {
- return nil, fmt.Errorf("Unable to authorize|%s|%s|", user, err.Error())
- }
- // Fallback to ~
- authorizedKeysFile = user.HomeDir + "/.ssh/authorized_keys"
+ authorizedKeysFile, err := authorizedKeysFile(user)
+ if err != nil {
+ return nil, err
}
- logger.Info(user, "Reading", authorizedKeysFile)
+ dlog.Server.Info(user, "Reading", authorizedKeysFile)
authorizedKeysBytes, err := ioutil.ReadFile(authorizedKeysFile)
if err != nil {
- return nil, fmt.Errorf("Unable to read authorized keys file|%s|%s|%s", authorizedKeysFile, user, err.Error())
+ return nil, fmt.Errorf("Unable to read authorized keys file|%s|%s|%s",
+ authorizedKeysFile, user, err.Error())
}
+ return verifyAuthorizedKeys(user, authorizedKeysBytes, offeredPubKey)
+}
+
+func verifyAuthorizedKeys(user *user.User, authorizedKeysBytes []byte,
+ offeredPubKey gossh.PublicKey) (*gossh.Permissions, error) {
+
authorizedKeysMap := map[string]bool{}
for len(authorizedKeysBytes) > 0 {
authorizedPubKey, _, _, restBytes, err := gossh.ParseAuthorizedKey(authorizedKeysBytes)
if err != nil {
- return nil, fmt.Errorf("Unable to parse authorized keys bytes|%s|%s", user, err.Error())
+ return nil, fmt.Errorf("unable to parse authorized keys bytes|%s|%s",
+ user, err.Error())
}
authorizedKeysMap[string(authorizedPubKey.Marshal())] = true
authorizedKeysBytes = restBytes
-
- logger.Debug(user, "Authorized public key fingerprint", gossh.FingerprintSHA256(authorizedPubKey))
+ dlog.Server.Debug(user, "Authorized public key fingerprint",
+ gossh.FingerprintSHA256(authorizedPubKey))
}
- logger.Debug(user, "Offered public key fingerprint", gossh.FingerprintSHA256(offeredPubKey))
-
+ dlog.Server.Debug(user, "Offered public key fingerprint", gossh.FingerprintSHA256(offeredPubKey))
if authorizedKeysMap[string(offeredPubKey.Marshal())] {
return &gossh.Permissions{
- Extensions: map[string]string{
- "pubkey-fp": gossh.FingerprintSHA256(offeredPubKey),
- },
+ Extensions: map[string]string{"pubkey-fp": gossh.FingerprintSHA256(offeredPubKey)},
}, nil
}
- return nil, fmt.Errorf("%s|Public key of user not authorized", user)
+ return nil, fmt.Errorf("%s|public key of user not authorized", user)
+}
+
+func authorizedKeysFile(user *user.User) (string, error) {
+ if config.Env("DTAIL_INTEGRATION_TEST_RUN_MODE") {
+ // In this case, we expect a pub key in the current directory.
+ return "./id_rsa.pub", nil
+ }
+
+ cwd, err := os.Getwd()
+ if err != nil {
+ return "", err
+ }
+
+ // Check for cached version in the dserver directory.
+ authorizedKeysFile := fmt.Sprintf("%s/%s/%s.authorized_keys", cwd,
+ config.Common.CacheDir, user.Name)
+ if _, err = os.Stat(authorizedKeysFile); err == nil {
+ return authorizedKeysFile, nil
+ }
+
+ // As the last option, check the regular SSH path.
+ osUser, err := goUser.Lookup(user.Name)
+ if err != nil {
+ return "", err
+ }
+ authorizedKeysFile = fmt.Sprintf("%s/.ssh/authorized_keys", osUser.HomeDir)
+ if _, err = os.Stat(authorizedKeysFile); err == nil {
+ return authorizedKeysFile, nil
+ }
+
+ return "", fmt.Errorf("unable to find a any authorized keys file")
}