working dir to support v1
This commit is contained in:
parent
4c37ba232f
commit
ee76ceab6c
7 changed files with 213 additions and 49 deletions
|
|
@ -72,6 +72,12 @@ func installDrivers(piper *ssh.PiperConfig, config *piperdConfig, logger *log.Lo
|
|||
return upstream.Get(n)
|
||||
},
|
||||
func(plugin registry.Plugin) error {
|
||||
|
||||
v1, ok := plugin.(upstream.V1Provider)
|
||||
if ok {
|
||||
return v1.InstallUpstream(piper)
|
||||
}
|
||||
|
||||
handler := plugin.(upstream.Provider).GetHandler()
|
||||
|
||||
if handler == nil {
|
||||
|
|
|
|||
|
|
@ -55,6 +55,12 @@ type Provider interface {
|
|||
GetHandler() Handler
|
||||
}
|
||||
|
||||
// temp
|
||||
type V1Provider interface {
|
||||
registry.Plugin
|
||||
InstallUpstream(config *ssh.PiperConfig) error
|
||||
}
|
||||
|
||||
var (
|
||||
drivers = registry.NewRegistry()
|
||||
)
|
||||
|
|
|
|||
|
|
@ -2,10 +2,11 @@ package workingdir
|
|||
|
||||
var (
|
||||
config = struct {
|
||||
WorkingDir string `long:"upstream-workingdir" default:"/var/sshpiper" description:"Path to working directory" env:"SSHPIPERD_UPSTREAM_WORKINGDIR" ini-name:"upstream-workingdir"`
|
||||
AllowBadUsername bool `long:"upstream-workingdir-allowbadusername" description:"Disable username check while search the working directory" env:"SSHPIPERD_UPSTREAM_WORKINGDIR_ALLOWBADUSERNAME" ini-name:"upstream-workingdir-allowbadusername"`
|
||||
NoCheckPerm bool `long:"upstream-workingdir-nocheckperm" description:"Disable 0400 checking when using files in the working directory" env:"SSHPIPERD_UPSTREAM_WORKINGDIR_NOCHECKPERM" ini-name:"upstream-workingdir-nocheckperm"`
|
||||
FallbackUsername string `long:"upstream-workingdir-fallbackusername" description:"Fallback to a user when user does not exists in directory" env:"SSHPIPERD_UPSTREAM_WORKINGDIR_FALLBACKUSERNAME" ini-name:"upstream-workingdir-fallbackusername"`
|
||||
StrictHostKey bool `long:"upstream-workingdir-stricthostkey" description:"Upstream host public key must be in known_hosts file, otherwise drop the connection" env:"SSHPIPERD_UPSTREAM_WORKINGDIR_STRICTHOSTKEY" ini-name:"upstream-workingdir-stricthostkey"`
|
||||
WorkingDir string `long:"upstream-workingdir" default:"/var/sshpiper" description:"Path to working directory" env:"SSHPIPERD_UPSTREAM_WORKINGDIR" ini-name:"upstream-workingdir"`
|
||||
AllowBadUsername bool `long:"upstream-workingdir-allowbadusername" description:"Disable username check while search the working directory" env:"SSHPIPERD_UPSTREAM_WORKINGDIR_ALLOWBADUSERNAME" ini-name:"upstream-workingdir-allowbadusername"`
|
||||
NoCheckPerm bool `long:"upstream-workingdir-nocheckperm" description:"Disable 0400 checking when using files in the working directory" env:"SSHPIPERD_UPSTREAM_WORKINGDIR_NOCHECKPERM" ini-name:"upstream-workingdir-nocheckperm"`
|
||||
FallbackUsername string `long:"upstream-workingdir-fallbackusername" description:"Fallback to a user when user does not exists in directory" env:"SSHPIPERD_UPSTREAM_WORKINGDIR_FALLBACKUSERNAME" ini-name:"upstream-workingdir-fallbackusername"`
|
||||
StrictHostKey bool `long:"upstream-workingdir-stricthostkey" description:"Upstream host public key must be in known_hosts file, otherwise drop the connection" env:"SSHPIPERD_UPSTREAM_WORKINGDIR_STRICTHOSTKEY" ini-name:"upstream-workingdir-stricthostkey"`
|
||||
MatchPublicKeyInSubDir bool `long:"upstream-workingdir-matchpublickeyinsubdir" description:"Remap user in user's sub dir with publickey" env:"SSHPIPERD_UPSTREAM_WORKINGDIR_MATCHPUBLICKeYINSUBDIR" ini-name:"upstream-workingdir-matchpublickeyinsubdir"`
|
||||
}{}
|
||||
)
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import (
|
|||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
|
||||
"github.com/tg123/sshpiper/sshpiperd/upstream"
|
||||
)
|
||||
|
|
@ -20,7 +21,8 @@ func (p *plugin) ListPipe() ([]upstream.Pipe, error) {
|
|||
continue
|
||||
}
|
||||
|
||||
data, err := userUpstreamFile.read(file.Name())
|
||||
userUpstreamFile := userFile{filename: userUpstreamFile, userdir: path.Join(config.WorkingDir, file.Name())}
|
||||
data, err := userUpstreamFile.read()
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
|
@ -42,12 +44,14 @@ func (p *plugin) ListPipe() ([]upstream.Pipe, error) {
|
|||
}
|
||||
|
||||
func (p *plugin) CreatePipe(opt upstream.CreatePipeOption) error {
|
||||
err := os.MkdirAll(config.WorkingDir+"/"+opt.Username, 0775)
|
||||
userdir := path.Join(config.WorkingDir, opt.Username)
|
||||
err := os.MkdirAll(userdir, 0775)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
path := userUpstreamFile.realPath(opt.Username)
|
||||
userUpstreamFile := userFile{filename: userUpstreamFile, userdir: userdir}
|
||||
path := userUpstreamFile.realPath()
|
||||
if _, err := os.Stat(path); os.IsNotExist(err) {
|
||||
|
||||
upuser := opt.UpstreamUsername
|
||||
|
|
@ -66,7 +70,8 @@ func (p *plugin) CreatePipe(opt upstream.CreatePipeOption) error {
|
|||
}
|
||||
|
||||
func (p *plugin) RemovePipe(name string) error {
|
||||
path := userUpstreamFile.realPath(name)
|
||||
userUpstreamFile := userFile{filename: userUpstreamFile, userdir: path.Join(config.WorkingDir, name)}
|
||||
path := userUpstreamFile.realPath()
|
||||
if _, err := os.Stat(path); os.IsNotExist(err) {
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
133
sshpiperd/upstream/workingdir/v1.go
Normal file
133
sshpiperd/upstream/workingdir/v1.go
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
package workingdir
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/tg123/sshpiper/sshpiperd/v0bridge"
|
||||
"golang.org/x/crypto/ssh"
|
||||
"golang.org/x/crypto/ssh/knownhosts"
|
||||
)
|
||||
|
||||
func (p *plugin) InstallUpstream(piper *ssh.PiperConfig) error {
|
||||
v0bridge.InstallUpstream(piper, p.GetHandler())
|
||||
|
||||
piper.PublicKeyCallback = p.matchPublicKeyInSubDir
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *plugin) matchPublicKeyDir(conn ssh.ConnMetadata, key ssh.PublicKey, user, userdir string) (*ssh.Upstream, error) {
|
||||
if !checkUsername(user) {
|
||||
return nil, fmt.Errorf("downstream is not using a valid username")
|
||||
}
|
||||
|
||||
userUpstreamFile := userFile{filename: userUpstreamFile, userdir: userdir}
|
||||
err := userUpstreamFile.checkPerm()
|
||||
|
||||
if os.IsNotExist(err) && len(config.FallbackUsername) > 0 {
|
||||
user = config.FallbackUsername
|
||||
} else if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
data, err := userUpstreamFile.read()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
host, port, mappedUser, err := parseUpstreamFile(string(data))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
addr := fmt.Sprintf("%v:%v", host, port)
|
||||
|
||||
logger.Printf("mapping user [%v] to [%v@%v]", user, mappedUser, addr)
|
||||
|
||||
c, err := net.Dial("tcp", addr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
hostKeyCallback := ssh.InsecureIgnoreHostKey()
|
||||
|
||||
if config.StrictHostKey {
|
||||
userKnownHosts := userFile{filename: userKnownHosts, userdir: userdir}
|
||||
hostKeyCallback, err = knownhosts.New(userKnownHosts.realPath())
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
signer, err := mapPublicKeyFromUserfile(conn, user, userdir, key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if signer == nil {
|
||||
return nil, fmt.Errorf("cant find public key in user folder")
|
||||
}
|
||||
|
||||
return &ssh.Upstream{
|
||||
Conn: c,
|
||||
ClientConfig: ssh.ClientConfig{
|
||||
User: mappedUser,
|
||||
Auth: []ssh.AuthMethod{ssh.PublicKeys(signer)},
|
||||
HostKeyCallback: hostKeyCallback,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (p *plugin) matchPublicKeyInSubDir(conn ssh.ConnMetadata, key ssh.PublicKey, _ ssh.ChallengeContext) (*ssh.Upstream, error) {
|
||||
|
||||
{
|
||||
userdir := path.Join(config.WorkingDir, conn.User())
|
||||
u, err := p.matchPublicKeyDir(conn, key, conn.User(), userdir)
|
||||
if err != nil && !config.MatchPublicKeyInSubDir {
|
||||
logger.Errorf("cannot map private key in %v: %v", userdir, err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if u != nil {
|
||||
return u, nil
|
||||
}
|
||||
}
|
||||
|
||||
var upstream *ssh.Upstream
|
||||
|
||||
// search in working dir
|
||||
filepath.Walk(config.WorkingDir, func(path string, info os.FileInfo, err error) error {
|
||||
|
||||
logger.Debug("search public key in path: %v", path)
|
||||
if err != nil {
|
||||
logger.Debug("error walking path: ", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
if !info.IsDir() {
|
||||
return nil
|
||||
}
|
||||
|
||||
u, err := p.matchPublicKeyDir(conn, key, conn.User(), path)
|
||||
if err != nil {
|
||||
logger.Info("cannot map private key in %v: %v, search next", path, err)
|
||||
}
|
||||
|
||||
if u != nil {
|
||||
upstream = u
|
||||
return fmt.Errorf("stop")
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
if upstream != nil {
|
||||
return upstream, nil
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("no matching public key found in %v", config.WorkingDir)
|
||||
}
|
||||
|
|
@ -18,19 +18,24 @@ import (
|
|||
|
||||
"github.com/tg123/sshpiper/sshpiperd/upstream"
|
||||
"github.com/tg123/sshpiper/sshpiperd/v0bridge"
|
||||
"golang.org/x/crypto/ssh/knownhosts"
|
||||
|
||||
"golang.org/x/crypto/ssh"
|
||||
"golang.org/x/crypto/ssh/knownhosts"
|
||||
)
|
||||
|
||||
type userFile string
|
||||
type userFile struct {
|
||||
filename string
|
||||
userdir string
|
||||
}
|
||||
|
||||
const (
|
||||
userAuthorizedKeysFile = "authorized_keys"
|
||||
userKeyFile = "id_rsa"
|
||||
userUpstreamFile = "sshpiper_upstream"
|
||||
userKnownHosts = "known_hosts"
|
||||
)
|
||||
|
||||
var (
|
||||
userAuthorizedKeysFile userFile = "authorized_keys"
|
||||
userKeyFile userFile = "id_rsa"
|
||||
userUpstreamFile userFile = "sshpiper_upstream"
|
||||
userKnownHosts userFile = "known_hosts"
|
||||
|
||||
usernameRule *regexp.Regexp
|
||||
)
|
||||
|
||||
|
|
@ -41,21 +46,25 @@ func init() {
|
|||
usernameRule, _ = regexp.Compile("^[a-z_][-a-z0-9_]{0,31}$")
|
||||
}
|
||||
|
||||
func userSpecFile(user, file string) string {
|
||||
return path.Join(config.WorkingDir, user, file)
|
||||
func (file userFile) userSpecFile(filename string) string {
|
||||
p := file.userdir
|
||||
if p == "" {
|
||||
p = config.WorkingDir
|
||||
}
|
||||
return path.Join(p, filename)
|
||||
}
|
||||
|
||||
func (file userFile) read(user string) ([]byte, error) {
|
||||
return ioutil.ReadFile(userSpecFile(user, string(file)))
|
||||
func (file userFile) read() ([]byte, error) {
|
||||
return ioutil.ReadFile(file.userSpecFile(file.filename))
|
||||
}
|
||||
|
||||
func (file userFile) realPath(user string) string {
|
||||
return userSpecFile(user, string(file))
|
||||
func (file userFile) realPath() string {
|
||||
return file.userSpecFile(file.filename)
|
||||
}
|
||||
|
||||
// return error if other and group have access right
|
||||
func (file userFile) checkPerm(user string) error {
|
||||
filename := userSpecFile(user, string(file))
|
||||
func (file userFile) checkPerm() error {
|
||||
filename := file.userSpecFile(file.filename)
|
||||
f, err := os.Open(filename)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -114,14 +123,16 @@ func parseUpstreamFile(data string) (host string, port int, user string, err err
|
|||
return
|
||||
}
|
||||
|
||||
func findUpstreamFromUserfile(conn ssh.ConnMetadata, challengeContext ssh.ChallengeContext) (net.Conn, *v0bridge.AuthPipe, error) {
|
||||
func findUpstreamFromUserfile(conn ssh.ConnMetadata, _ ssh.ChallengeContext) (net.Conn, *v0bridge.AuthPipe, error) {
|
||||
user := conn.User()
|
||||
userdir := path.Join(config.WorkingDir, conn.User())
|
||||
|
||||
if !checkUsername(user) {
|
||||
return nil, nil, fmt.Errorf("downstream is not using a valid username")
|
||||
}
|
||||
|
||||
err := userUpstreamFile.checkPerm(user)
|
||||
userUpstreamFile := userFile{filename: userUpstreamFile, userdir: userdir}
|
||||
err := userUpstreamFile.checkPerm()
|
||||
|
||||
if os.IsNotExist(err) && len(config.FallbackUsername) > 0 {
|
||||
user = config.FallbackUsername
|
||||
|
|
@ -129,7 +140,7 @@ func findUpstreamFromUserfile(conn ssh.ConnMetadata, challengeContext ssh.Challe
|
|||
return nil, nil, err
|
||||
}
|
||||
|
||||
data, err := userUpstreamFile.read(user)
|
||||
data, err := userUpstreamFile.read()
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
|
@ -150,7 +161,8 @@ func findUpstreamFromUserfile(conn ssh.ConnMetadata, challengeContext ssh.Challe
|
|||
hostKeyCallback := ssh.InsecureIgnoreHostKey()
|
||||
|
||||
if config.StrictHostKey {
|
||||
hostKeyCallback, err = knownhosts.New(userKnownHosts.realPath(user))
|
||||
userKnownHosts := userFile{filename: userKnownHosts, userdir: userdir}
|
||||
hostKeyCallback, err = knownhosts.New(userKnownHosts.realPath())
|
||||
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
|
|
@ -161,7 +173,7 @@ func findUpstreamFromUserfile(conn ssh.ConnMetadata, challengeContext ssh.Challe
|
|||
User: mappedUser,
|
||||
|
||||
PublicKeyCallback: func(conn ssh.ConnMetadata, key ssh.PublicKey) (v0bridge.AuthPipeType, ssh.AuthMethod, error) {
|
||||
signer, err := mapPublicKeyFromUserfile(conn, key)
|
||||
signer, err := mapPublicKeyFromUserfile(conn, user, userdir, key)
|
||||
|
||||
if err != nil || signer == nil {
|
||||
// try one
|
||||
|
|
@ -175,20 +187,15 @@ func findUpstreamFromUserfile(conn ssh.ConnMetadata, challengeContext ssh.Challe
|
|||
}, nil
|
||||
}
|
||||
|
||||
func mapPublicKeyFromUserfile(conn ssh.ConnMetadata, key ssh.PublicKey) (signer ssh.Signer, err error) {
|
||||
user := conn.User()
|
||||
|
||||
if !checkUsername(user) {
|
||||
return nil, fmt.Errorf("downstream is not using a valid username")
|
||||
}
|
||||
|
||||
func mapPublicKeyFromUserfile(conn ssh.ConnMetadata, user, userdir string, key ssh.PublicKey) (signer ssh.Signer, err error) {
|
||||
defer func() { // print error when func exit
|
||||
if err != nil {
|
||||
logger.Printf("mapping private key error: %v, public key auth denied for [%v] from [%v]", err, user, conn.RemoteAddr())
|
||||
}
|
||||
}()
|
||||
|
||||
err = userAuthorizedKeysFile.checkPerm(user)
|
||||
userAuthorizedKeysFile := userFile{filename: userAuthorizedKeysFile, userdir: userdir}
|
||||
err = userAuthorizedKeysFile.checkPerm()
|
||||
|
||||
if os.IsNotExist(err) && len(config.FallbackUsername) > 0 {
|
||||
err = nil
|
||||
|
|
@ -200,11 +207,12 @@ func mapPublicKeyFromUserfile(conn ssh.ConnMetadata, key ssh.PublicKey) (signer
|
|||
keydata := key.Marshal()
|
||||
|
||||
var rest []byte
|
||||
rest, err = userAuthorizedKeysFile.read(user)
|
||||
rest, err = userAuthorizedKeysFile.read()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
userKeyFile := userFile{filename: userKeyFile, userdir: userdir}
|
||||
var authedPubkey ssh.PublicKey
|
||||
|
||||
for len(rest) > 0 {
|
||||
|
|
@ -215,13 +223,13 @@ func mapPublicKeyFromUserfile(conn ssh.ConnMetadata, key ssh.PublicKey) (signer
|
|||
}
|
||||
|
||||
if bytes.Equal(authedPubkey.Marshal(), keydata) {
|
||||
err = userKeyFile.checkPerm(user)
|
||||
err = userKeyFile.checkPerm()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var privateBytes []byte
|
||||
privateBytes, err = userKeyFile.read(user)
|
||||
privateBytes, err = userKeyFile.read()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -233,7 +241,7 @@ func mapPublicKeyFromUserfile(conn ssh.ConnMetadata, key ssh.PublicKey) (signer
|
|||
}
|
||||
|
||||
// in log may see this twice, one is for query the other is real sign again
|
||||
logger.Printf("auth succ, using mapped private key [%v] for user [%v] from [%v]", userKeyFile.realPath(user), user, conn.RemoteAddr())
|
||||
logger.Printf("auth succ, using mapped private key [%v] for user [%v] from [%v]", userKeyFile.realPath(), user, conn.RemoteAddr())
|
||||
return private, nil
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ func (p *proxy) CreateChallengeContext(conn ssh.ConnMetadata) (ssh.ChallengeCont
|
|||
return p, nil
|
||||
}
|
||||
|
||||
func (p *proxy) createUpstream(conn net.Conn, pipe *AuthPipe, authType AuthPipeType, oldMethod, mappedMethod ssh.AuthMethod) (*ssh.Upstream, error) {
|
||||
func CreateUpstream(conn net.Conn, pipe *AuthPipe, authType AuthPipeType, oldMethod, mappedMethod ssh.AuthMethod) (*ssh.Upstream, error) {
|
||||
|
||||
clientConfig := ssh.ClientConfig{
|
||||
User: pipe.User,
|
||||
|
|
@ -130,7 +130,7 @@ func (p *proxy) NoneAuthCallback(conn ssh.ConnMetadata, challengeCtx ssh.Challen
|
|||
}
|
||||
|
||||
if pipe.NoneAuthCallback == nil {
|
||||
return p.createUpstream(c, pipe, AuthPipeTypePassThrough, ssh.NoneAuth(), nil)
|
||||
return CreateUpstream(c, pipe, AuthPipeTypePassThrough, ssh.NoneAuth(), nil)
|
||||
}
|
||||
|
||||
t, m, err := pipe.NoneAuthCallback(conn)
|
||||
|
|
@ -138,7 +138,7 @@ func (p *proxy) NoneAuthCallback(conn ssh.ConnMetadata, challengeCtx ssh.Challen
|
|||
return nil, err
|
||||
}
|
||||
|
||||
return p.createUpstream(c, pipe, t, ssh.NoneAuth(), m)
|
||||
return CreateUpstream(c, pipe, t, ssh.NoneAuth(), m)
|
||||
}
|
||||
|
||||
func (p *proxy) PasswordCallback(conn ssh.ConnMetadata, password []byte, challengeCtx ssh.ChallengeContext) (*ssh.Upstream, error) {
|
||||
|
|
@ -148,7 +148,7 @@ func (p *proxy) PasswordCallback(conn ssh.ConnMetadata, password []byte, challen
|
|||
}
|
||||
|
||||
if pipe.PasswordCallback == nil {
|
||||
return p.createUpstream(c, pipe, AuthPipeTypePassThrough, ssh.Password(string(password)), nil)
|
||||
return CreateUpstream(c, pipe, AuthPipeTypePassThrough, ssh.Password(string(password)), nil)
|
||||
}
|
||||
|
||||
t, m, err := pipe.PasswordCallback(conn, password)
|
||||
|
|
@ -156,7 +156,7 @@ func (p *proxy) PasswordCallback(conn ssh.ConnMetadata, password []byte, challen
|
|||
return nil, err
|
||||
}
|
||||
|
||||
return p.createUpstream(c, pipe, t, ssh.Password(string(password)), m)
|
||||
return CreateUpstream(c, pipe, t, ssh.Password(string(password)), m)
|
||||
}
|
||||
|
||||
func (p *proxy) PublicKeyCallback(conn ssh.ConnMetadata, key ssh.PublicKey, challengeCtx ssh.ChallengeContext) (*ssh.Upstream, error) {
|
||||
|
|
@ -166,7 +166,7 @@ func (p *proxy) PublicKeyCallback(conn ssh.ConnMetadata, key ssh.PublicKey, chal
|
|||
}
|
||||
|
||||
if pipe.PublicKeyCallback == nil {
|
||||
return p.createUpstream(c, pipe, AuthPipeTypePassThrough, ssh.NoneAuth(), nil)
|
||||
return CreateUpstream(c, pipe, AuthPipeTypePassThrough, ssh.NoneAuth(), nil)
|
||||
}
|
||||
|
||||
t, m, err := pipe.PublicKeyCallback(conn, key)
|
||||
|
|
@ -174,10 +174,13 @@ func (p *proxy) PublicKeyCallback(conn ssh.ConnMetadata, key ssh.PublicKey, chal
|
|||
return nil, err
|
||||
}
|
||||
|
||||
return p.createUpstream(c, pipe, t, ssh.NoneAuth(), m) // cannt passthrough public key, use none instead
|
||||
return CreateUpstream(c, pipe, t, ssh.NoneAuth(), m) // cannt passthrough public key, use none instead
|
||||
}
|
||||
|
||||
func InstallUpstream(config *ssh.PiperConfig, handler func(conn ssh.ConnMetadata, challengeContext ssh.ChallengeContext) (net.Conn, *AuthPipe, error)) {
|
||||
func InstallUpstream(config *ssh.PiperConfig, handler func(conn ssh.ConnMetadata, challengeContext ssh.ChallengeContext) (net.Conn, *AuthPipe, error)) error {
|
||||
if handler == nil {
|
||||
return fmt.Errorf("handler is nil")
|
||||
}
|
||||
|
||||
p := &proxy{
|
||||
handler: handler,
|
||||
|
|
@ -192,4 +195,6 @@ func InstallUpstream(config *ssh.PiperConfig, handler func(conn ssh.ConnMetadata
|
|||
config.NoneAuthCallback = p.NoneAuthCallback
|
||||
config.PasswordCallback = p.PasswordCallback
|
||||
config.PublicKeyCallback = p.PublicKeyCallback
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue