diff --git a/pkg/api/asset.go b/pkg/api/asset.go index 9c8c0fe..f1f9577 100644 --- a/pkg/api/asset.go +++ b/pkg/api/asset.go @@ -1,9 +1,9 @@ package api import ( + "github.com/labstack/echo/v4" "next-terminal/pkg/model" "next-terminal/pkg/utils" - "github.com/labstack/echo/v4" "strconv" "strings" ) @@ -51,6 +51,21 @@ func AssetUpdateEndpoint(c echo.Context) error { if err := c.Bind(&item); err != nil { return err } + switch item.AccountType { + case "credential": + item.Username = "-" + item.Password = "-" + item.PrivateKey = "-" + item.Passphrase = "-" + case "private-key": + item.Username = "-" + item.Password = "-" + item.CredentialId = "-" + case "custom": + item.PrivateKey = "-" + item.Passphrase = "-" + item.CredentialId = "-" + } model.UpdateAssetById(&item, id) diff --git a/pkg/api/session.go b/pkg/api/session.go index fcf432f..ce8c0c5 100644 --- a/pkg/api/session.go +++ b/pkg/api/session.go @@ -125,16 +125,18 @@ func SessionCreateEndpoint(c echo.Context) error { } session := &model.Session{ - ID: utils.UUID(), - AssetId: asset.ID, - Username: asset.Username, - Password: asset.Password, - Protocol: asset.Protocol, - IP: asset.IP, - Port: asset.Port, - Status: model.NoConnect, - Creator: user.ID, - ClientIP: c.RealIP(), + ID: utils.UUID(), + AssetId: asset.ID, + Username: asset.Username, + Password: asset.Password, + PrivateKey: asset.PrivateKey, + Passphrase: asset.Passphrase, + Protocol: asset.Protocol, + IP: asset.IP, + Port: asset.Port, + Status: model.NoConnect, + Creator: user.ID, + ClientIP: c.RealIP(), } if asset.AccountType == "credential" { diff --git a/pkg/api/ssh.go b/pkg/api/ssh.go index 1f63959..5b2ff9f 100644 --- a/pkg/api/ssh.go +++ b/pkg/api/ssh.go @@ -2,15 +2,14 @@ package api import ( "bytes" - "next-terminal/pkg/model" "fmt" "github.com/gorilla/websocket" "github.com/labstack/echo/v4" "github.com/pkg/sftp" "golang.org/x/crypto/ssh" "log" - "net" "net/http" + "next-terminal/pkg/model" "strconv" "sync" "time" @@ -57,32 +56,7 @@ func SSHEndpoint(c echo.Context) error { width, _ := strconv.Atoi(c.QueryParam("width")) height, _ := strconv.Atoi(c.QueryParam("height")) - asset, err := model.FindAssetById(assetId) - if err != nil { - return err - } - - if asset.AccountType == "credential" { - credential, err := model.FindCredentialById(asset.CredentialId) - if err != nil { - return err - } - asset.Username = credential.Username - asset.Password = credential.Password - } - - config := &ssh.ClientConfig{ - Timeout: 1 * time.Second, - User: asset.Username, - Auth: []ssh.AuthMethod{ssh.Password(asset.Password)}, - HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error { - return nil - }, - } - - addr := fmt.Sprintf("%s:%d", asset.IP, asset.Port) - - sshClient, err := ssh.Dial("tcp", addr, config) + sshClient, err := CreateSshClient(assetId) if err != nil { return err } @@ -143,6 +117,55 @@ func SSHEndpoint(c echo.Context) error { return err } +func CreateSshClient(assetId string) (*ssh.Client, error) { + asset, err := model.FindAssetById(assetId) + if err != nil { + return nil, err + } + + var authMethod ssh.AuthMethod + if asset.AccountType == "credential" { + credential, err := model.FindCredentialById(asset.CredentialId) + if err != nil { + return nil, err + } + asset.Username = credential.Username + asset.Password = credential.Password + authMethod = ssh.Password(asset.Password) + } else if asset.AccountType == "private-key" { + var key ssh.Signer + if len(asset.Passphrase) > 0 { + key, err = ssh.ParsePrivateKeyWithPassphrase([]byte(asset.PrivateKey), []byte(asset.Passphrase)) + if err != nil { + return nil, err + } + } else { + key, err = ssh.ParsePrivateKey([]byte(asset.PrivateKey)) + if err != nil { + return nil, err + } + } + authMethod = ssh.PublicKeys(key) + } else { + authMethod = ssh.Password(asset.Password) + } + + config := &ssh.ClientConfig{ + Timeout: 1 * time.Second, + User: asset.Username, + Auth: []ssh.AuthMethod{authMethod}, + HostKeyCallback: ssh.InsecureIgnoreHostKey(), + } + + addr := fmt.Sprintf("%s:%d", asset.IP, asset.Port) + + sshClient, err := ssh.Dial("tcp", addr, config) + if err != nil { + return nil, err + } + return sshClient, nil +} + func WriteMessage(ws *websocket.Conn, message string) { WriteByteMessage(ws, []byte(message)) } @@ -154,19 +177,8 @@ func WriteByteMessage(ws *websocket.Conn, p []byte) { } } -func CreateSftpClient(username, password, ip string, port int) (sftpClient *sftp.Client, err error) { - clientConfig := &ssh.ClientConfig{ - Timeout: 1 * time.Second, - User: username, - Auth: []ssh.AuthMethod{ssh.Password(password)}, - HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error { - return nil - }, - } - - addr := fmt.Sprintf("%s:%d", ip, port) - - sshClient, err := ssh.Dial("tcp", addr, clientConfig) +func CreateSftpClient(assetId string) (sftpClient *sftp.Client, err error) { + sshClient, err := CreateSshClient(assetId) if err != nil { return nil, err } diff --git a/pkg/api/tunnel.go b/pkg/api/tunnel.go index fca9342..ea79e4b 100644 --- a/pkg/api/tunnel.go +++ b/pkg/api/tunnel.go @@ -80,10 +80,15 @@ func TunEndpoint(c echo.Context) error { configuration.SetParameter("enable-sftp", "") break case "ssh": - configuration.SetParameter("username", session.Username) - configuration.SetParameter("password", session.Password) + if session.PrivateKey == "-" { + configuration.SetParameter("username", session.Username) + configuration.SetParameter("password", session.Password) + } else { + configuration.SetParameter("private-key", session.PrivateKey) + configuration.SetParameter("passphrase", session.Passphrase) + } - sftpClient, err = CreateSftpClient(session.Username, session.Password, session.IP, session.Port) + sftpClient, err = CreateSftpClient(session.AssetId) if err != nil { return err } diff --git a/pkg/model/session.go b/pkg/model/session.go index f0624ab..e5b4044 100644 --- a/pkg/model/session.go +++ b/pkg/model/session.go @@ -27,6 +27,8 @@ type Session struct { Height int `json:"height"` Status string `json:"status"` Recording string `json:"recording"` + PrivateKey string `json:"privateKey"` + Passphrase string `json:"passphrase"` ConnectedTime utils.JsonTime `json:"connectedTime"` DisconnectedTime utils.JsonTime `json:"disconnectedTime"` } diff --git a/web/public/bg.svg b/web/public/bg.svg new file mode 100644 index 0000000..89c2597 --- /dev/null +++ b/web/public/bg.svg @@ -0,0 +1,69 @@ + + \ No newline at end of file diff --git a/web/public/index.html b/web/public/index.html index cd03fc2..668ce47 100644 --- a/web/public/index.html +++ b/web/public/index.html @@ -14,7 +14,7 @@ -->