Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v3.5.0 #229

Merged
merged 4 commits into from
Jul 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 6 additions & 8 deletions pkg/jms-sdk-go/model/platform.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,12 @@ type PlatformProtocol struct {
Setting ProtocolSetting `json:"setting"`
}
type ProtocolSetting struct {
Security string `json:"security"`
Console bool `json:"console"`
SftpEnabled bool `json:"sftp_enabled"`
SftpHome string `json:"sftp_home"`
AutoFill bool `json:"auto_fill"`
UsernameSelector string `json:"username_selector"`
PasswordSelector string `json:"password_selector"`
SubmitSelector string `json:"submit_selector"`
Security string `json:"security"`
Console bool `json:"console"`
SftpEnabled bool `json:"sftp_enabled"`
SftpHome string `json:"sftp_home"`
AutoFill bool `json:"auto_fill"`
AdDomain string `json:"ad_domain"`
}

/*
Expand Down
8 changes: 7 additions & 1 deletion pkg/session/configuration.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,13 @@ func (r RDPConfiguration) GetGuacdConfiguration() guacd.Configuration {
//if r.SystemUser.AdDomain != "" {
// conf.SetParameter(guacd.RDPDomain, r.SystemUser.AdDomain)
//}

if r.Platform != nil {
if rdpSetting, ok := r.Platform.GetProtocolSetting("rdp"); ok {
if rdpSetting.Setting.AdDomain != "" {
conf.SetParameter(guacd.RDPDomain, rdpSetting.Setting.AdDomain)
}
}
}
// 设置 录像路径
if r.TerminalConfig.ReplayStorage.TypeName != "null" {
recordDirPath := filepath.Join(config.GlobalConfig.RecordPath,
Expand Down
16 changes: 10 additions & 6 deletions pkg/tunnel/conn.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ func (t *Connection) Run(ctx *gin.Context) (err error) {
switch instruction.Opcode {
case guacd.InstructionServerDisconnect,
guacd.InstructionServerError:
logger.Infof("Session[%s] receive guacamole server disconnect opcode", t)
logger.Infof("Session[%s] receive guacamole server disconnect: %s", t, instruction.String())
case guacd.InstructionStreamingAck:
select {
case activeChan <- struct{}{}:
Expand Down Expand Up @@ -179,17 +179,21 @@ func (t *Connection) Run(ctx *gin.Context) (err error) {
continue
}

switch ret.Opcode {
case guacd.InstructionKey:
userInputMessageChan <- &session.Message{
Opcode: ret.Opcode, Body: ret.Args,
Meta: meta}
default:

}

switch ret.Opcode {
case guacd.InstructionClientSync,
guacd.InstructionClientNop,
guacd.InstructionStreamingAck:
case guacd.InstructionClientDisconnect:
logger.Errorf("Session[%s] receive web client disconnect opcode", t)
case guacd.InstructionKey:
userInputMessageChan <- &session.Message{
Opcode: ret.Opcode, Body: ret.Args,
Meta: meta}
fallthrough
default:
select {
case activeChan <- struct{}{}:
Expand Down
12 changes: 9 additions & 3 deletions pkg/tunnel/monitor.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
)

type MonitorCon struct {
Id string
guacdTunnel Tunneler

ws *websocket.Conn
Expand Down Expand Up @@ -53,7 +54,8 @@ func (m *MonitorCon) Run(ctx context.Context) (err error) {
for {
instruction, err := t.readTunnelInstruction()
if err != nil {
logger.Error(err)
_ = t.writeWsMessage([]byte(ErrDisconnect.String()))
logger.Infof("Monitor[%s] guacd tunnel read err: %+v", t.Id, err)
exit <- err
break
}
Expand All @@ -70,6 +72,8 @@ func (m *MonitorCon) Run(ctx context.Context) (err error) {
for {
_, message, err := t.ws.ReadMessage()
if err != nil {
logger.Infof("Monitor[%s] ws read err: %+v", t.Id, err)

exit <- err
break
}
Expand All @@ -82,11 +86,11 @@ func (m *MonitorCon) Run(ctx context.Context) (err error) {
continue
}
} else {
logger.Errorf("Parse instruction err %s", err)
logger.Errorf("Monitor[%s] parse instruction err %s", t.Id, err)
}
_, err = t.writeTunnelMessage(message)
if err != nil {
logger.Errorf("Guacamole server write err: %+v", err)
logger.Errorf("Monitor[%s] guacamole tunnel write err: %+v", t.Id, err)
exit <- err
break
}
Expand All @@ -97,8 +101,10 @@ func (m *MonitorCon) Run(ctx context.Context) (err error) {
for {
select {
case err = <-exit:
logger.Infof("Monitor[%s] exit: %+v", m.Id, err)
return err
case <-ctx.Done():
logger.Info("Monitor[%s] done", m.Id)
return nil
}
}
Expand Down
1 change: 1 addition & 0 deletions pkg/tunnel/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,7 @@ func (g *GuacamoleTunnelServer) Monitor(ctx *gin.Context) {
}
defer tunnelCon.Close()
conn := MonitorCon{
Id: sessionId,
guacdTunnel: tunnelCon,
ws: ws,
}
Expand Down
2 changes: 2 additions & 0 deletions pkg/tunnel/ws_error.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,6 @@ var (
ErrGuacamoleServer = NewJMSGuacamoleError(1008, "Connect guacamole server failed")

ErrPermission = NewJMSGuacamoleError(256, "No permission")

ErrDisconnect = NewJMSGuacamoleError(1009, "Disconnect by client")
)
6 changes: 3 additions & 3 deletions ui/src/components/GuacamoleConnect.vue
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
<RightPanel>
<Settings :settings="settings" :title="$t('Settings')">
<el-button type="text" class="item-button el-icon-c-scale-to-original">
{{ $t('Display') }}
{{ $t('Display') }}
</el-button>
<div class="content"> <i class="el-icon-remove-outline" @click="decreaseScale" />
<span>{{ scaleValue }}%</span>
Expand Down Expand Up @@ -62,7 +62,7 @@ import GuacFileSystem from './GuacFileSystem'
import RightPanel from './RightPanel'
import Settings from './Settings'
import { default as i18n, getLanguage } from '@/i18n'
import { ErrorStatusCodes, ConvertAPIError } from '@/utils'
import { ErrorStatusCodes, ConvertAPIError, ConvertGuacamoleError } from '@/utils'
import { localStorageGet } from '@/utils/common'

const pixelDensity = 1
Expand Down Expand Up @@ -505,7 +505,7 @@ export default {
const code = status.code
let msg = status.message
const currentLang = getLanguage()
msg = ErrorStatusCodes[code] ? this.$t(ErrorStatusCodes[code]) : status.message
msg = ErrorStatusCodes[code] ? this.$t(ErrorStatusCodes[code]) : this.$t(ConvertGuacamoleError(status.message))
switch (code) {
case 1005:
// 管理员终断会话,特殊处理
Expand Down
8 changes: 3 additions & 5 deletions ui/src/components/GuacamoleMonitor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@ import { getMonitorConnectParams } from '@/utils/common'
import { getSupportedMimetypes } from '@/utils/image'
import { getSupportedGuacAudios } from '@/utils/audios'
import { getSupportedGuacVideos } from '@/utils/video'
import { getLanguage } from '@/i18n'
import { ErrorStatusCodes } from '@/utils/status'
import { ConvertGuacamoleError, ErrorStatusCodes } from '@/utils/status'

const pixelDensity = window.devicePixelRatio || 1
export default {
Expand Down Expand Up @@ -220,9 +219,7 @@ export default {
this.$log.debug(status, i18n.locale)
const code = status.code
let msg = status.message
if (getLanguage() === 'cn') {
msg = ErrorStatusCodes[code] ? this.$t(ErrorStatusCodes[code]) : status.message
}
msg = ErrorStatusCodes[code] ? this.$t(ErrorStatusCodes[code]) : this.$t(ConvertGuacamoleError(status.message))
this.$alert(msg, this.$t('ErrTitle'), {
confirmButtonText: this.$t('OK'),
callback: action => {
Expand All @@ -239,6 +236,7 @@ export default {
const tunnel = new Guacamole.WebSocketTunnel(wsURL)
const client = new Guacamole.Client(tunnel)
const vm = this
tunnel.receiveTimeout = 60 * 1000
tunnel.onerror = function tunnelError(status) {
vm.$log.debug('tunnelError ', status)
display.innerHTML = ''
Expand Down
24 changes: 23 additions & 1 deletion ui/src/i18n/lang/cn.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ const message = {
JMSErrAPIFailed: 'Core API 发生错误',
JMSErrGatewayFailed: '网关连接失败',
JMSErrGuacamoleServer: '无法连接 Guacamole 服务器',
JMSErrDisconnected: '会话连接已断开',
GuaErrUpstreamNotFound: '无法连接到远程桌面服务器(网络不可达 | 安全策略错误)',
GuaErrSessionConflict: '因与另一个连接冲突,远程桌面服务器关闭了本连接。请稍后重试。',
GuaErrClientUnauthorized: '用户名和密码认证错误,登录失败',
Expand All @@ -34,7 +35,28 @@ const message = {
Settings: '设置',
UploadSuccess: '上传成功',
Display: '显示',
AutoFit: '自动适应'
AutoFit: '自动适应',

GuacamoleErrDisconnected: '远程连接断开',
GuacamoleErrCredentialsExpired: '远程连接的凭证过期',
GuacamoleErrSecurityNegotiationFailed: '远程连接的安全协商失败',
GuacamoleErrAccessDenied: '远程连接的访问被拒绝',
GuacamoleErrAuthenticationFailure: '远程连接的认证失败',
GuacamoleErrSSLTLSConnectionFailed: '远程连接的 SSL/TLS 连接失败',
GuacamoleErrDNSLookupFailed: '远程连接的 DNS 查询失败',
GuacamoleErrServerRefusedConnectionBySecurityType: '远程连接的服务器拒绝连接,可能安全类型不匹配',
GuacamoleErrConnectionFailed: '远程连接失败',
GuacamoleErrUpstreamError: '远程连接的服务器发生错误',
GuacamoleErrForciblyDisconnected: '远程连接被强制断开',
GuacamoleErrLoggedOff: '远程连接的用户已注销',
GuacamoleErrIdleSessionTimeLimitExceeded: '远程连接的空闲时间超过限制',
GuacamoleErrActiveSessionTimeLimitExceeded: '远程连接的活动时间超过限制',
GuacamoleErrDisconnectedByOtherConnection: '远程连接被其他连接断开',
GuacamoleErrServerRefusedConnection: '远程连接的服务器拒绝连接',
GuacamoleErrInsufficientPrivileges: '远程连接的用户权限不足',
GuacamoleErrManuallyDisconnected: '远程连接被手动断开',
GuacamoleErrManuallyLoggedOff: '远程连接的用户被手动注销',
GuacamoleErrUnsupportedCredentialTypeRequested: '远程连接的凭证类型不支持'
}

export default {
Expand Down
24 changes: 23 additions & 1 deletion ui/src/i18n/lang/en.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ const message = {
JMSErrAPIFailed: 'Core API failed',
JMSErrGatewayFailed: 'Gateway not available',
JMSErrGuacamoleServer: 'Connect guacamole server failed',
JMSErrDisconnected: 'Session Disconnected',
GuaErrUpstreamNotFound: 'The remote desktop server does not appear to exist, or cannot be reached over the network.',
GuaErrSessionConflict: 'The session has ended because it conflicts with another session.',
GuaErrClientUnauthorized: 'User failed to logged in. (username and password are incorrect)',
Expand All @@ -33,7 +34,28 @@ const message = {
Settings: 'Settings',
UploadSuccess: 'Upload success',
Display: 'Display',
AutoFit: 'Auto Fit'
AutoFit: 'Auto Fit',

GuacamoleErrDisconnected: 'Disconnected.',
GuacamoleErrCredentialsExpired: 'Credentials expired.',
GuacamoleErrSecurityNegotiationFailed: 'Security negotiation failed (wrong security type?)',
GuacamoleErrAccessDenied: 'Access denied by server (account locked/disabled?)',
GuacamoleErrAuthenticationFailure: 'Authentication failure (invalid credentials?)',
GuacamoleErrSSLTLSConnectionFailed: 'SSL/TLS connection failed (untrusted/self-signed certificate?)',
GuacamoleErrDNSLookupFailed: 'DNS lookup failed (incorrect hostname?)',
GuacamoleErrServerRefusedConnectionBySecurityType: 'Server refused connection (wrong security type?)',
GuacamoleErrConnectionFailed: 'Connection failed (server unreachable?)',
GuacamoleErrUpstreamError: 'Upstream error.',
GuacamoleErrForciblyDisconnected: 'Forcibly disconnected.',
GuacamoleErrLoggedOff: 'Logged off.',
GuacamoleErrIdleSessionTimeLimitExceeded: 'Idle session time limit exceeded.',
GuacamoleErrActiveSessionTimeLimitExceeded: 'Active session time limit exceeded.',
GuacamoleErrDisconnectedByOtherConnection: 'Disconnected by other connection.',
GuacamoleErrServerRefusedConnection: 'Server refused connection.',
GuacamoleErrInsufficientPrivileges: 'Insufficient privileges.',
GuacamoleErrManuallyDisconnected: 'Manually disconnected.',
GuacamoleErrManuallyLoggedOff: 'Manually logged off.',
GuacamoleErrUnsupportedCredentialTypeRequested: 'Unsupported credential type requested.'
}

export default {
Expand Down
34 changes: 33 additions & 1 deletion ui/src/utils/status.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ export const ErrorStatusCodes = {
1005: 'JMSErrTerminatedByAdmin',
1006: 'JMSErrAPIFailed',
1007: 'JMSErrGatewayFailed',
1008: 'JMSErrGuacamoleServer'
1008: 'JMSErrGuacamoleServer',
1009: 'JMSErrDisconnected'
}

export function ConvertAPIError(errMsg) {
Expand All @@ -32,3 +33,34 @@ export const APIErrorType = {
'unsupported protocol': 'JMSErrBadParams',
'permission deny': 'JMSErrPermission'
}

export function ConvertGuacamoleError(errMsg) {
if (typeof errMsg !== 'string') {
return errMsg
}
return GuacamoleErrMsg[errMsg] || errMsg
}

export const GuacamoleErrMsg = {
'Disconnected.': 'GuacamoleErrDisconnected',
'Credentials expired.': 'GuacamoleErrCredentialsExpired',
'Security negotiation failed (wrong security type?)': 'GuacamoleErrSecurityNegotiationFailed',
'Access denied by server (account locked/disabled?)': 'GuacamoleErrAccessDenied',
'Authentication failure (invalid credentials?)': 'GuacamoleErrAuthenticationFailure',
'SSL/TLS connection failed (untrusted/self-signed certificate?)': 'GuacamoleErrSSLTLSConnectionFailed',
'DNS lookup failed (incorrect hostname?)': 'GuacamoleErrDNSLookupFailed',
'Server refused connection (wrong security type?)': 'GuacamoleErrServerRefusedConnectionBySecurityType',
'Connection failed (server unreachable?)': 'GuacamoleErrConnectionFailed',
'Upstream error.': 'GuacamoleErrUpstreamError',
'Forcibly disconnected.': 'GuacamoleErrForciblyDisconnected',
'Logged off.': 'GuacamoleErrLoggedOff',
'Idle session time limit exceeded.': 'GuacamoleErrIdleSessionTimeLimitExceeded',
'Active session time limit exceeded.': 'GuacamoleErrActiveSessionTimeLimitExceeded',
'Disconnected by other connection.': 'GuacamoleErrDisconnectedByOtherConnection',
'Server refused connection.': 'GuacamoleErrServerRefusedConnection',
'Insufficient privileges.': 'GuacamoleErrInsufficientPrivileges',
'Manually disconnected.': 'GuacamoleErrManuallyDisconnected',
'Manually logged off.': 'GuacamoleErrManuallyLoggedOff',

'Unsupported credential type requested.': 'GuacamoleErrUnsupportedCredentialTypeRequested'
}