Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
后端镜像
Tabby
提交
0c892225
T
Tabby
项目概览
后端镜像
/
Tabby
通知
41
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
T
Tabby
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
0c892225
编写于
2月 16, 2020
作者:
E
Eugene Pankov
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
nicer terminal messages for SSH
上级
851d92a1
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
57 addition
and
31 deletion
+57
-31
terminus-ssh/package.json
terminus-ssh/package.json
+2
-0
terminus-ssh/src/api.ts
terminus-ssh/src/api.ts
+10
-9
terminus-ssh/src/components/sshTab.component.ts
terminus-ssh/src/components/sshTab.component.ts
+19
-8
terminus-ssh/src/services/ssh.service.ts
terminus-ssh/src/services/ssh.service.ts
+8
-6
terminus-ssh/yarn.lock
terminus-ssh/yarn.lock
+10
-0
terminus-terminal/src/api/baseTerminalTab.component.ts
terminus-terminal/src/api/baseTerminalTab.component.ts
+8
-8
未找到文件。
terminus-ssh/package.json
浏览文件 @
0c892225
...
...
@@ -19,6 +19,8 @@
"devDependencies"
:
{
"@types/node"
:
"12.7.3"
,
"@types/ssh2"
:
"^0.5.35"
,
"ansi-colors"
:
"^4.1.1"
,
"cli-spinner"
:
"^0.2.10"
,
"ssh2"
:
"^0.8.2"
,
"ssh2-streams"
:
"^0.4.2"
,
"sshpk"
:
"^1.16.1"
,
...
...
terminus-ssh/src/api.ts
浏览文件 @
0c892225
import
colors
from
'
ansi-colors
'
import
{
BaseSession
}
from
'
terminus-terminal
'
import
{
Server
,
Socket
,
createServer
,
createConnection
}
from
'
net
'
import
{
Client
,
ClientChannel
}
from
'
ssh2
'
...
...
@@ -92,7 +93,7 @@ export class SSHSession extends BaseSession {
try
{
this
.
shell
=
await
this
.
openShellChannel
({
x11
:
this
.
connection
.
x11
})
}
catch
(
err
)
{
this
.
emitServiceMessage
(
`
Remote rejected opening a shell channel:
${
err
}
`
)
this
.
emitServiceMessage
(
colors
.
bgRed
.
black
(
'
X
'
)
+
`
Remote rejected opening a shell channel:
${
err
}
`
)
}
this
.
shell
.
on
(
'
greeting
'
,
greeting
=>
{
...
...
@@ -159,13 +160,13 @@ export class SSHSession extends BaseSession {
this
.
logger
.
info
(
`Incoming forwarded connection: (remote)
${
details
.
srcIP
}
:
${
details
.
srcPort
}
-> (local)
${
details
.
destIP
}
:
${
details
.
destPort
}
`
)
const
forward
=
this
.
forwardedPorts
.
find
(
x
=>
x
.
port
===
details
.
destPort
)
if
(
!
forward
)
{
this
.
emitServiceMessage
(
`
Rejected incoming forwarded connection for unrecognized port
${
details
.
destPort
}
`
)
this
.
emitServiceMessage
(
colors
.
bgRed
.
black
(
'
X
'
)
+
`
Rejected incoming forwarded connection for unrecognized port
${
details
.
destPort
}
`
)
return
reject
()
}
const
socket
=
new
Socket
()
socket
.
connect
(
forward
.
targetPort
,
forward
.
targetAddress
)
socket
.
on
(
'
error
'
,
e
=>
{
this
.
emitServiceMessage
(
`
Could not forward the remote connection to
${
forward
.
targetAddress
}
:
${
forward
.
targetPort
}
:
${
e
}
`
)
this
.
emitServiceMessage
(
colors
.
bgRed
.
black
(
'
X
'
)
+
`
Could not forward the remote connection to
${
forward
.
targetAddress
}
:
${
forward
.
targetPort
}
:
${
e
}
`
)
reject
()
})
socket
.
on
(
'
connect
'
,
()
=>
{
...
...
@@ -195,7 +196,7 @@ export class SSHSession extends BaseSession {
socket
.
connect
(
xPort
,
xHost
)
}
socket
.
on
(
'
error
'
,
e
=>
{
this
.
emitServiceMessage
(
`
Could not connect to the X server
${
xHost
}
:
${
xPort
}
:
${
e
}
`
)
this
.
emitServiceMessage
(
colors
.
bgRed
.
black
(
'
X
'
)
+
`
Could not connect to the X server
${
xHost
}
:
${
xPort
}
:
${
e
}
`
)
reject
()
})
socket
.
on
(
'
connect
'
,
()
=>
{
...
...
@@ -231,7 +232,7 @@ export class SSHSession extends BaseSession {
fw
.
targetPort
,
(
err
,
stream
)
=>
{
if
(
err
)
{
this
.
emitServiceMessage
(
`
Remote has rejected the forwaded connection via
${
fw
}
:
${
err
}
`
)
this
.
emitServiceMessage
(
colors
.
bgRed
.
black
(
'
X
'
)
+
`
Remote has rejected the forwaded connection via
${
fw
}
:
${
err
}
`
)
socket
.
destroy
()
return
}
...
...
@@ -246,10 +247,10 @@ export class SSHSession extends BaseSession {
}
)
}).
then
(()
=>
{
this
.
emitServiceMessage
(
`
Forwaded
${
fw
}
`
)
this
.
emitServiceMessage
(
colors
.
bgGreen
.
black
(
'
->
'
)
+
`
Forwaded
${
fw
}
`
)
this
.
forwardedPorts
.
push
(
fw
)
}).
catch
(
e
=>
{
this
.
emitServiceMessage
(
`
Failed to forward port
${
fw
}
:
${
e
}
`
)
this
.
emitServiceMessage
(
colors
.
bgRed
.
black
(
'
X
'
)
+
`
Failed to forward port
${
fw
}
:
${
e
}
`
)
throw
e
})
}
...
...
@@ -257,13 +258,13 @@ export class SSHSession extends BaseSession {
await
new
Promise
((
resolve
,
reject
)
=>
{
this
.
ssh
.
forwardIn
(
fw
.
host
,
fw
.
port
,
err
=>
{
if
(
err
)
{
this
.
emitServiceMessage
(
`
Remote rejected port forwarding for
${
fw
}
:
${
err
}
`
)
this
.
emitServiceMessage
(
colors
.
bgRed
.
black
(
'
X
'
)
+
`
Remote rejected port forwarding for
${
fw
}
:
${
err
}
`
)
return
reject
(
err
)
}
resolve
()
})
})
this
.
emitServiceMessage
(
`
Forwaded
${
fw
}
`
)
this
.
emitServiceMessage
(
colors
.
bgGreen
.
black
(
'
<-
'
)
+
`
Forwaded
${
fw
}
`
)
this
.
forwardedPorts
.
push
(
fw
)
}
}
...
...
terminus-ssh/src/components/sshTab.component.ts
浏览文件 @
0c892225
import
colors
from
'
ansi-colors
'
import
{
Spinner
}
from
'
cli-spinner
'
import
{
Component
}
from
'
@angular/core
'
import
{
NgbModal
}
from
'
@ng-bootstrap/ng-bootstrap
'
import
{
first
}
from
'
rxjs/operators
'
...
...
@@ -43,23 +45,32 @@ export class SSHTabComponent extends BaseTerminalTabComponent {
this
.
session
=
this
.
ssh
.
createSession
(
this
.
connection
)
this
.
session
.
serviceMessage$
.
subscribe
(
msg
=>
{
this
.
write
(
`\r\n[SSH]
${
msg
}
\r\n`
)
this
.
write
(
'
\r\n
'
+
colors
.
black
.
bgWhite
(
'
SSH
'
)
+
'
'
+
msg
+
'
\r\n
'
)
this
.
session
.
resize
(
this
.
size
.
columns
,
this
.
size
.
rows
)
})
this
.
attachSessionHandlers
()
this
.
write
(
`Connecting to
${
this
.
connection
.
host
}
`
)
const
interval
=
setInterval
(()
=>
this
.
write
(
'
.
'
),
500
)
const
spinner
=
new
Spinner
({
text
:
'
Connecting
'
,
stream
:
{
write
:
x
=>
this
.
write
(
x
),
},
})
spinner
.
setSpinnerString
(
6
)
spinner
.
start
()
try
{
await
this
.
ssh
.
connectSession
(
this
.
session
,
(
message
:
string
)
=>
{
this
.
write
(
'
\r\n
'
+
message
)
spinner
.
stop
(
true
)
this
.
write
(
message
+
'
\r\n
'
)
spinner
.
start
()
})
spinner
.
stop
(
true
)
}
catch
(
e
)
{
this
.
write
(
'
\r\n
'
)
this
.
write
(
e
.
message
)
spinner
.
stop
(
true
)
this
.
write
(
colors
.
black
.
bgRed
(
'
X
'
)
+
'
'
+
colors
.
red
(
e
.
message
)
+
'
\r\n
'
)
return
}
finally
{
clearInterval
(
interval
)
this
.
write
(
'
\r\n
'
)
}
await
this
.
session
.
start
()
this
.
session
.
resize
(
this
.
size
.
columns
,
this
.
size
.
rows
)
...
...
terminus-ssh/src/services/ssh.service.ts
浏览文件 @
0c892225
import
colors
from
'
ansi-colors
'
import
{
Injectable
,
NgZone
}
from
'
@angular/core
'
import
{
NgbModal
}
from
'
@ng-bootstrap/ng-bootstrap
'
import
{
Client
}
from
'
ssh2
'
...
...
@@ -65,17 +66,17 @@ export class SSHService {
if
(
!
privateKeyPath
)
{
const
userKeyPath
=
path
.
join
(
process
.
env
.
HOME
as
string
,
'
.ssh
'
,
'
id_rsa
'
)
if
(
await
fs
.
exists
(
userKeyPath
))
{
log
(
`Using user's default private key:
${
userKeyPath
}
`
)
log
(
'
Using user
\'
s default private key
'
)
privateKeyPath
=
userKeyPath
}
}
if
(
privateKeyPath
)
{
log
(
`Loading private key from
${
privateKeyPath
}
`
)
log
(
'
Loading private key from
'
+
colors
.
bgWhite
.
blackBright
(
'
'
+
privateKeyPath
+
'
'
)
)
try
{
privateKey
=
(
await
fs
.
readFile
(
privateKeyPath
)).
toString
()
}
catch
(
error
)
{
log
(
'
Could not read the private key file
'
)
log
(
colors
.
bgRed
.
black
(
'
X
'
)
+
'
Could not read the private key file
'
)
this
.
toastr
.
error
(
'
Could not read the private key file
'
)
}
...
...
@@ -86,7 +87,7 @@ export class SSHService {
}
catch
(
e
)
{
if
(
e
instanceof
sshpk
.
KeyEncryptedError
)
{
const
modal
=
this
.
ngbModal
.
open
(
PromptModalComponent
)
log
(
'
Key requires passphrase
'
)
log
(
colors
.
bgYellow
.
yellow
.
black
(
'
!
'
)
+
'
Key requires passphrase
'
)
modal
.
componentInstance
.
prompt
=
'
Private key passphrase
'
modal
.
componentInstance
.
password
=
true
let
passphrase
=
''
...
...
@@ -133,7 +134,7 @@ export class SSHService {
})
})
ssh
.
on
(
'
keyboard-interactive
'
,
(
name
,
instructions
,
instructionsLang
,
prompts
,
finish
)
=>
this
.
zone
.
run
(
async
()
=>
{
log
(
`
Keyboard-interactive auth requested:
${
name
}
`
)
log
(
colors
.
bgBlackBright
(
'
'
)
+
`
Keyboard-interactive auth requested:
${
name
}
`
)
this
.
logger
.
info
(
'
Keyboard-interactive auth:
'
,
name
,
instructions
,
instructionsLang
)
const
results
:
string
[]
=
[]
for
(
const
prompt
of
prompts
)
{
...
...
@@ -182,7 +183,8 @@ export class SSHService {
keepaliveCountMax
:
session
.
connection
.
keepaliveCountMax
,
readyTimeout
:
session
.
connection
.
readyTimeout
,
hostVerifier
:
digest
=>
{
log
(
'
SHA256 fingerprint:
'
+
digest
)
log
(
colors
.
bgWhite
(
'
'
)
+
'
Host key fingerprint:
'
)
log
(
colors
.
bgWhite
(
'
'
)
+
'
'
+
colors
.
black
.
bgWhite
(
'
SHA256
'
)
+
colors
.
bgBlackBright
(
'
'
+
digest
+
'
'
))
return
true
},
hostHash
:
'
sha256
'
as
any
,
...
...
terminus-ssh/yarn.lock
浏览文件 @
0c892225
...
...
@@ -27,6 +27,11 @@
"@types/node" "*"
"@types/ssh2-streams" "*"
ansi-colors@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348"
integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==
asn1@~0.2.0, asn1@~0.2.3:
version "0.2.4"
resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136"
...
...
@@ -46,6 +51,11 @@ bcrypt-pbkdf@^1.0.0, bcrypt-pbkdf@^1.0.2:
dependencies:
tweetnacl "^0.14.3"
cli-spinner@^0.2.10:
version "0.2.10"
resolved "https://registry.yarnpkg.com/cli-spinner/-/cli-spinner-0.2.10.tgz#f7d617a36f5c47a7bc6353c697fc9338ff782a47"
integrity sha512-U0sSQ+JJvSLi1pAYuJykwiA8Dsr15uHEy85iCJ6A+0DjVxivr3d+N2Wjvodeg89uP5K6TswFkKBfAD7B3YSn/Q==
dashdash@^1.12.0:
version "1.14.1"
resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0"
...
...
terminus-terminal/src/api/baseTerminalTab.component.ts
浏览文件 @
0c892225
...
...
@@ -174,6 +174,14 @@ export class BaseTerminalTabComponent extends BaseTabComponent implements OnInit
this
.
size
=
{
columns
,
rows
}
this
.
frontendReady
.
next
()
this
.
config
.
enabledServices
(
this
.
decorators
).
forEach
(
decorator
=>
{
try
{
decorator
.
attach
(
this
)
}
catch
(
e
)
{
this
.
logger
.
warn
(
'
Decorator attach() throws
'
,
e
)
}
})
setTimeout
(()
=>
{
this
.
session
.
resize
(
columns
,
rows
)
},
1000
)
...
...
@@ -204,14 +212,6 @@ export class BaseTerminalTabComponent extends BaseTabComponent implements OnInit
this
.
configure
()
this
.
config
.
enabledServices
(
this
.
decorators
).
forEach
((
decorator
)
=>
{
try
{
decorator
.
attach
(
this
)
}
catch
(
e
)
{
this
.
logger
.
warn
(
'
Decorator attach() throws
'
,
e
)
}
})
setTimeout
(()
=>
{
this
.
output
.
subscribe
(()
=>
{
this
.
displayActivity
()
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录