docker4ssh/server/ssh/config.go
2021-12-19 17:30:51 +01:00

69 lines
1.9 KiB
Go

package ssh
import (
c "docker4ssh/config"
"docker4ssh/database"
"fmt"
"golang.org/x/crypto/ssh"
"io/ioutil"
)
func NewSSHConfig(config *c.Config) (*ssh.ServerConfig, error) {
db := database.GetDatabase()
sshConfig := &ssh.ServerConfig{
MaxAuthTries: 3,
PasswordCallback: func(conn ssh.ConnMetadata, password []byte) (*ssh.Permissions, error) {
if containerID, exists := db.GetContainerByAuth(database.NewUnsafeAuth(conn.User(), password)); exists && containerID != "" {
return &ssh.Permissions{
CriticalOptions: map[string]string{
"containerID": containerID,
},
}, nil
} else if profile, ok := profiles.Match(conn.User(), password); ok {
return &ssh.Permissions{
CriticalOptions: map[string]string{
"profile": profile.Name(),
},
}, nil
} else if config.Profile.Dynamic.Enable && dynamicProfile.Match(conn.User(), password) {
return &ssh.Permissions{
CriticalOptions: map[string]string{
"profile": "dynamic",
"image": conn.User(),
},
}, nil
}
// i think logging the wrong password is a bit unsafe.
// if you have e.g. just a type in it isn't very well to see your nearly correct password in the logs
return nil, fmt.Errorf("%s tried to connect with user %s but entered wrong a password", conn.RemoteAddr().String(), conn.User())
},
}
sshConfig.SetDefaults()
key, err := parseSSHPrivateKey(config.SSH.Keyfile, []byte(config.SSH.Passphrase))
if err != nil {
return nil, err
}
sshConfig.AddHostKey(key)
return sshConfig, nil
}
func parseSSHPrivateKey(path string, password []byte) (ssh.Signer, error) {
keyBytes, err := ioutil.ReadFile(path)
if err != nil {
return nil, err
}
var key ssh.Signer
if len(password) == 0 {
key, err = ssh.ParsePrivateKey(keyBytes)
} else {
key, err = ssh.ParsePrivateKeyWithPassphrase(keyBytes, password)
}
if err != nil {
return nil, err
}
return key, nil
}