diff --git a/backend/app/api/v1/host.go b/backend/app/api/v1/host.go
index 7bd794138..3dc2a0aba 100644
--- a/backend/app/api/v1/host.go
+++ b/backend/app/api/v1/host.go
@@ -245,11 +245,13 @@ func (b *BaseApi) UpdateHost(c *gin.Context) {
upMap["port"] = req.Port
upMap["user"] = req.User
upMap["auth_mode"] = req.AuthMode
+ upMap["remember_password"] = req.RememberPassword
if len(req.Password) != 0 {
upMap["password"] = req.Password
}
if len(req.PrivateKey) != 0 {
upMap["private_key"] = req.PrivateKey
+ upMap["pass_phrase"] = req.PassPhrase
}
upMap["description"] = req.Description
if err := hostService.Update(req.ID, upMap); err != nil {
diff --git a/backend/app/api/v1/terminal.go b/backend/app/api/v1/terminal.go
index 52d5b933c..736d16338 100644
--- a/backend/app/api/v1/terminal.go
+++ b/backend/app/api/v1/terminal.go
@@ -44,6 +44,9 @@ func (b *BaseApi) WsSsh(c *gin.Context) {
var connInfo ssh.ConnInfo
_ = copier.Copy(&connInfo, &host)
connInfo.PrivateKey = []byte(host.PrivateKey)
+ if len(host.PassPhrase) != 0 {
+ connInfo.PassPhrase = []byte(host.PassPhrase)
+ }
wsConn, err := upGrader.Upgrade(c.Writer, c.Request, nil)
if err != nil {
diff --git a/backend/app/dto/host.go b/backend/app/dto/host.go
index 3d510404f..9853d8f34 100644
--- a/backend/app/dto/host.go
+++ b/backend/app/dto/host.go
@@ -5,15 +5,17 @@ import (
)
type HostOperate struct {
- ID uint `json:"id"`
- GroupID uint `json:"groupID"`
- Name string `json:"name"`
- Addr string `json:"addr" validate:"required"`
- Port uint `json:"port" validate:"required,number,max=65535,min=1"`
- User string `json:"user" validate:"required"`
- AuthMode string `json:"authMode" validate:"oneof=password key"`
- PrivateKey string `json:"privateKey"`
- Password string `json:"password"`
+ ID uint `json:"id"`
+ GroupID uint `json:"groupID"`
+ Name string `json:"name"`
+ Addr string `json:"addr" validate:"required"`
+ Port uint `json:"port" validate:"required,number,max=65535,min=1"`
+ User string `json:"user" validate:"required"`
+ AuthMode string `json:"authMode" validate:"oneof=password key"`
+ Password string `json:"password"`
+ PrivateKey string `json:"privateKey"`
+ PassPhrase string `json:"passPhrase"`
+ RememberPassword bool `json:"rememberPassword"`
Description string `json:"description"`
}
@@ -23,8 +25,9 @@ type HostConnTest struct {
Port uint `json:"port" validate:"required,number,max=65535,min=1"`
User string `json:"user" validate:"required"`
AuthMode string `json:"authMode" validate:"oneof=password key"`
- PrivateKey string `json:"privateKey"`
Password string `json:"password"`
+ PrivateKey string `json:"privateKey"`
+ PassPhrase string `json:"passPhrase"`
}
type SearchHostWithPage struct {
@@ -43,15 +46,19 @@ type ChangeHostGroup struct {
}
type HostInfo struct {
- ID uint `json:"id"`
- CreatedAt time.Time `json:"createdAt"`
- GroupID uint `json:"groupID"`
- GroupBelong string `json:"groupBelong"`
- Name string `json:"name"`
- Addr string `json:"addr"`
- Port uint `json:"port"`
- User string `json:"user"`
- AuthMode string `json:"authMode"`
+ ID uint `json:"id"`
+ CreatedAt time.Time `json:"createdAt"`
+ GroupID uint `json:"groupID"`
+ GroupBelong string `json:"groupBelong"`
+ Name string `json:"name"`
+ Addr string `json:"addr"`
+ Port uint `json:"port"`
+ User string `json:"user"`
+ AuthMode string `json:"authMode"`
+ Password string `json:"password"`
+ PrivateKey string `json:"privateKey"`
+ PassPhrase string `json:"passPhrase"`
+ RememberPassword bool `json:"rememberPassword"`
Description string `json:"description"`
}
diff --git a/backend/app/model/host.go b/backend/app/model/host.go
index b25a57b82..a4fe6aedd 100644
--- a/backend/app/model/host.go
+++ b/backend/app/model/host.go
@@ -2,14 +2,17 @@ package model
type Host struct {
BaseModel
- GroupID uint `gorm:"type:decimal;not null" json:"group_id"`
- Name string `gorm:"type:varchar(64);not null" json:"name"`
- Addr string `gorm:"type:varchar(16);not null" json:"addr"`
- Port int `gorm:"type:decimal;not null" json:"port"`
- User string `gorm:"type:varchar(64);not null" json:"user"`
- AuthMode string `gorm:"type:varchar(16);not null" json:"authMode"`
- Password string `gorm:"type:varchar(64)" json:"password"`
- PrivateKey string `gorm:"type:varchar(256)" json:"privateKey"`
+
+ GroupID uint `gorm:"type:decimal;not null" json:"group_id"`
+ Name string `gorm:"type:varchar(64);not null" json:"name"`
+ Addr string `gorm:"type:varchar(16);not null" json:"addr"`
+ Port int `gorm:"type:decimal;not null" json:"port"`
+ User string `gorm:"type:varchar(64);not null" json:"user"`
+ AuthMode string `gorm:"type:varchar(16);not null" json:"authMode"`
+ Password string `gorm:"type:varchar(64)" json:"password"`
+ PrivateKey string `gorm:"type:varchar(256)" json:"privateKey"`
+ PassPhrase string `gorm:"type:varchar(256)" json:"passPhrase"`
+ RememberPassword bool `json:"rememberPassword"`
Description string `gorm:"type:varchar(256)" json:"description"`
}
diff --git a/backend/app/service/host.go b/backend/app/service/host.go
index 5286c5312..d928f16ba 100644
--- a/backend/app/service/host.go
+++ b/backend/app/service/host.go
@@ -52,11 +52,15 @@ func (u *HostService) TestByInfo(req dto.HostConnTest) bool {
req.Password = host.Password
req.AuthMode = host.AuthMode
req.PrivateKey = host.PrivateKey
+ req.PassPhrase = host.PassPhrase
}
var connInfo ssh.ConnInfo
_ = copier.Copy(&connInfo, &req)
connInfo.PrivateKey = []byte(req.PrivateKey)
+ if len(req.PassPhrase) != 0 {
+ connInfo.PassPhrase = []byte(req.PassPhrase)
+ }
client, err := connInfo.NewClient()
if err != nil {
return false
@@ -85,6 +89,10 @@ func (u *HostService) TestLocalConn(id uint) bool {
if err := copier.Copy(&connInfo, &host); err != nil {
return false
}
+ connInfo.PrivateKey = []byte(host.PrivateKey)
+ if len(host.PassPhrase) != 0 {
+ connInfo.PassPhrase = []byte(host.PassPhrase)
+ }
client, err := connInfo.NewClient()
if err != nil {
return false
@@ -115,6 +123,11 @@ func (u *HostService) SearchWithPage(search dto.SearchHostWithPage) (int64, inte
}
group, _ := groupRepo.Get(commonRepo.WithByID(host.GroupID))
item.GroupBelong = group.Name
+ if !item.RememberPassword {
+ item.Password = ""
+ item.PrivateKey = ""
+ item.PassPhrase = ""
+ }
dtoHosts = append(dtoHosts, item)
}
return total, dtoHosts, err
@@ -182,6 +195,8 @@ func (u *HostService) Create(req dto.HostOperate) (*dto.HostInfo, error) {
upMap["auth_mode"] = req.AuthMode
upMap["password"] = req.Password
upMap["private_key"] = req.PrivateKey
+ upMap["pass_phrase"] = req.PassPhrase
+ upMap["remember_password"] = req.RememberPassword
upMap["description"] = req.Description
if err := hostRepo.Update(sameHostID, upMap); err != nil {
return nil, err
diff --git a/backend/init/migration/migrate.go b/backend/init/migration/migrate.go
index 0b37edaff..db2d247ea 100644
--- a/backend/init/migration/migrate.go
+++ b/backend/init/migration/migrate.go
@@ -23,6 +23,7 @@ func Init() {
migrations.AddDefaultGroup,
migrations.AddTableRuntime,
migrations.UpdateTableApp,
+ migrations.UpdateTableHost,
})
if err := m.Migrate(); err != nil {
global.LOG.Error(err)
diff --git a/backend/init/migration/migrations/init.go b/backend/init/migration/migrations/init.go
index 1b3dc6e1c..e7b7ea5e0 100644
--- a/backend/init/migration/migrations/init.go
+++ b/backend/init/migration/migrations/init.go
@@ -264,3 +264,13 @@ var UpdateTableApp = &gormigrate.Migration{
return nil
},
}
+
+var UpdateTableHost = &gormigrate.Migration{
+ ID: "20230410-update-table-host",
+ Migrate: func(tx *gorm.DB) error {
+ if err := tx.AutoMigrate(&model.Host{}); err != nil {
+ return err
+ }
+ return nil
+ },
+}
diff --git a/backend/utils/ssh/ssh.go b/backend/utils/ssh/ssh.go
index a1cd69659..bbe6d2377 100644
--- a/backend/utils/ssh/ssh.go
+++ b/backend/utils/ssh/ssh.go
@@ -127,20 +127,8 @@ func (w *wsBufferWriter) Write(p []byte) (int, error) {
}
func makePrivateKeySigner(privateKey []byte, passPhrase []byte) (gossh.Signer, error) {
- var signer gossh.Signer
- if passPhrase != nil {
- s, err := gossh.ParsePrivateKeyWithPassphrase(privateKey, passPhrase)
- if err != nil {
- return nil, fmt.Errorf("error parsing SSH key: '%v'", err)
- }
- signer = s
- } else {
- s, err := gossh.ParsePrivateKey(privateKey)
- if err != nil {
- return nil, fmt.Errorf("error parsing SSH key: '%v'", err)
- }
- signer = s
+ if len(passPhrase) != 0 {
+ return gossh.ParsePrivateKeyWithPassphrase(privateKey, passPhrase)
}
-
- return signer, nil
+ return gossh.ParsePrivateKey(privateKey)
}
diff --git a/frontend/src/api/interface/host.ts b/frontend/src/api/interface/host.ts
index 70f3a2929..8fc9273d9 100644
--- a/frontend/src/api/interface/host.ts
+++ b/frontend/src/api/interface/host.ts
@@ -18,6 +18,10 @@ export namespace Host {
port: number;
user: string;
authMode: string;
+ password: string;
+ privateKey: string;
+ passPhrase: string;
+ rememberPassword: boolean;
description: string;
}
export interface HostOperate {
@@ -28,8 +32,10 @@ export namespace Host {
port: number;
user: string;
authMode: string;
- privateKey: string;
password: string;
+ privateKey: string;
+ passPhrase: string;
+ rememberPassword: boolean;
description: string;
}
diff --git a/frontend/src/lang/modules/en.ts b/frontend/src/lang/modules/en.ts
index 7e12c906e..96fe81819 100644
--- a/frontend/src/lang/modules/en.ts
+++ b/frontend/src/lang/modules/en.ts
@@ -674,10 +674,12 @@ const message = {
port: 'Port',
user: 'Username',
authMode: 'Auth Mode',
- passwordMode: 'password',
+ passwordMode: 'Password',
+ rememberPassword: 'Remember password',
keyMode: 'PrivateKey',
password: 'Password',
- key: 'Private Key',
+ key: 'Private key',
+ keyPassword: 'Private key password',
emptyTerminal: 'No terminal is currently connected',
},
logs: {
diff --git a/frontend/src/lang/modules/zh.ts b/frontend/src/lang/modules/zh.ts
index 87e4a814b..373016a30 100644
--- a/frontend/src/lang/modules/zh.ts
+++ b/frontend/src/lang/modules/zh.ts
@@ -673,10 +673,12 @@ const message = {
port: '端口',
user: '用户名',
authMode: '认证方式',
- passwordMode: '密码输入',
- keyMode: '密钥输入',
+ passwordMode: '密码认证',
+ rememberPassword: '记住密码',
+ keyMode: '私钥认证',
password: '密码',
- key: '密钥',
+ key: '私钥',
+ keyPassword: '私钥密码',
emptyTerminal: '暂无终端连接',
},
logs: {
diff --git a/frontend/src/views/host/terminal/host/operate/index.vue b/frontend/src/views/host/terminal/host/operate/index.vue
index d1f8b0e5b..d0645d92f 100644
--- a/frontend/src/views/host/terminal/host/operate/index.vue
+++ b/frontend/src/views/host/terminal/host/operate/index.vue
@@ -36,7 +36,22 @@
>
-
+
+
+
+
+ {{ $t('terminal.rememberPassword') }}
+
+
diff --git a/frontend/src/views/host/terminal/terminal/host-create.vue b/frontend/src/views/host/terminal/terminal/host-create.vue
index 3f4662120..c24d4e665 100644
--- a/frontend/src/views/host/terminal/terminal/host-create.vue
+++ b/frontend/src/views/host/terminal/terminal/host-create.vue
@@ -40,7 +40,17 @@
-
+
+
+
+
+ {{ $t('terminal.rememberPassword') }}
+
+
@@ -91,6 +101,8 @@ let hostInfo = reactive({
authMode: 'password',
password: '',
privateKey: '',
+ passPhrase: '',
+ rememberPassword: false,
description: '',
});