Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
J
jumpserver
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
ops
jumpserver
Commits
12f33176
Commit
12f33176
authored
Nov 22, 2015
by
ibuler
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'dev' into exec_cmd
parents
4cdc7f33
eb779e5b
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
66 additions
and
126 deletions
+66
-126
connect.py
connect.py
+46
-116
run_websocket.py
run_websocket.py
+20
-10
No files found.
connect.py
View file @
12f33176
...
@@ -19,14 +19,13 @@ import struct, fcntl, signal, socket, select
...
@@ -19,14 +19,13 @@ import struct, fcntl, signal, socket, select
os
.
environ
[
'DJANGO_SETTINGS_MODULE'
]
=
'jumpserver.settings'
os
.
environ
[
'DJANGO_SETTINGS_MODULE'
]
=
'jumpserver.settings'
if
django
.
get_version
()
!=
'1.6'
:
if
django
.
get_version
()
!=
'1.6'
:
django
.
setup
()
django
.
setup
()
from
jumpserver.api
import
ServerError
,
User
,
Asset
,
AssetGroup
,
get_object
,
mkdir
,
get_asset_info
,
get_role
from
jumpserver.api
import
ServerError
,
User
,
Asset
,
PermRole
,
AssetGroup
,
get_object
,
mkdir
,
get_asset_info
,
get_role
from
jumpserver.api
import
logger
,
Log
,
TtyLog
,
get_role_key
from
jumpserver.api
import
logger
,
Log
,
TtyLog
,
get_role_key
from
jperm.perm_api
import
gen_resource
,
get_group_asset_perm
,
get_group_user_perm
from
jperm.perm_api
import
gen_resource
,
get_group_asset_perm
,
get_group_user_perm
from
jumpserver.settings
import
LOG_DIR
from
jumpserver.settings
import
LOG_DIR
from
jperm.ansible_api
import
Command
from
jperm.ansible_api
import
Command
login_user
=
get_object
(
User
,
username
=
getpass
.
getuser
())
login_user
=
get_object
(
User
,
username
=
getpass
.
getuser
())
VIM_FLAG
=
False
try
:
try
:
import
termios
import
termios
...
@@ -52,23 +51,6 @@ def color_print(msg, color='red', exits=False):
...
@@ -52,23 +51,6 @@ def color_print(msg, color='red', exits=False):
sys
.
exit
()
sys
.
exit
()
def
check_vim_status
(
command
,
ssh
):
global
SSH_TTY
print
command
if
command
==
''
:
return
True
else
:
command_str
=
'ps -ef |grep "
%
s" | grep "
%
s"|grep -v grep |wc -l'
%
(
command
,
SSH_TTY
)
print
command_str
stdin
,
stdout
,
stderr
=
ssh
.
exec_command
(
command_str
)
ps_num
=
stdout
.
read
()
print
ps_num
if
int
(
ps_num
)
==
0
:
return
True
else
:
return
False
class
Tty
(
object
):
class
Tty
(
object
):
"""
"""
A virtual tty class
A virtual tty class
...
@@ -86,6 +68,9 @@ class Tty(object):
...
@@ -86,6 +68,9 @@ class Tty(object):
self
.
ssh
=
None
self
.
ssh
=
None
self
.
connect_info
=
None
self
.
connect_info
=
None
self
.
login_type
=
'ssh'
self
.
login_type
=
'ssh'
self
.
vim_flag
=
False
self
.
ps1_pattern
=
re
.
compile
(
'
\
[.*@.*
\
][
\
$#]'
)
self
.
vim_data
=
''
@staticmethod
@staticmethod
def
is_output
(
strings
):
def
is_output
(
strings
):
...
@@ -95,33 +80,24 @@ class Tty(object):
...
@@ -95,33 +80,24 @@ class Tty(object):
return
True
return
True
return
False
return
False
@staticmethod
def
deal_command
(
self
,
str_r
):
def
deal_command
(
str_r
,
ssh
):
"""
"""
处理命令中特殊字符
处理命令中特殊字符
"""
"""
str_r
=
re
.
sub
(
'
\x07
'
,
''
,
str_r
)
#
删除响铃
str_r
=
re
.
sub
(
'
\x07
'
,
''
,
str_r
)
#
删除响铃
patch_char
=
re
.
compile
(
'
\x08\x1b
\
[C'
)
#
删除方向左右一起的按键
patch_char
=
re
.
compile
(
'
\x08\x1b
\
[C'
)
#
删除方向左右一起的按键
while
patch_char
.
search
(
str_r
):
while
patch_char
.
search
(
str_r
):
str_r
=
patch_char
.
sub
(
''
,
str_r
.
rstrip
())
str_r
=
patch_char
.
sub
(
''
,
str_r
.
rstrip
())
result_command
=
''
#最后的结果
result_command
=
''
# 最后的结果
backspace_num
=
0
#光标移动的个数
backspace_num
=
0
# 光标移动的个数
backspace_list
=
[]
reach_backspace_flag
=
False
# 没有检测到光标键则为true
reach_backspace_flag
=
False
#没有检测到光标键则为true
pattern_str
=
''
reach_backspace_second_flag
=
False
pattern_list
=
[]
pattern_str
=
''
while
str_r
:
while
str_r
:
tmp
=
re
.
match
(
r'\s*\w+\s*'
,
str_r
)
#获取字符串,其它特殊字符匹配暂时还不知道。。
tmp
=
re
.
match
(
r'\s*\w+\s*'
,
str_r
)
if
tmp
:
if
tmp
:
if
reach_backspace_flag
:
if
reach_backspace_flag
:
if
not
reach_backspace_second_flag
:
pattern_str
+=
str
(
tmp
.
group
(
0
))
pattern_str
+=
str
(
tmp
.
group
(
0
))
else
:
pattern_list
.
append
(
pattern_str
)
pattern_str
=
str
(
tmp
.
group
(
0
))
reach_backspace_second_flag
=
False
str_r
=
str_r
[
len
(
str
(
tmp
.
group
(
0
))):]
str_r
=
str_r
[
len
(
str
(
tmp
.
group
(
0
))):]
continue
continue
else
:
else
:
...
@@ -129,65 +105,46 @@ class Tty(object):
...
@@ -129,65 +105,46 @@ class Tty(object):
str_r
=
str_r
[
len
(
str
(
tmp
.
group
(
0
))):]
str_r
=
str_r
[
len
(
str
(
tmp
.
group
(
0
))):]
continue
continue
tmp
=
re
.
match
(
r'\x1b\[K[\x08]*'
,
str_r
)
#遇到删除确认符,确定删除数据
tmp
=
re
.
match
(
r'\x1b\[K[\x08]*'
,
str_r
)
if
tmp
:
if
tmp
:
for
x
in
backspace_list
:
backspace_num
+=
int
(
x
)
if
backspace_num
>
0
:
if
backspace_num
>
0
:
if
backspace_num
>
len
(
result_command
)
:
if
backspace_num
>
len
(
result_command
):
result_command
+=
''
.
join
(
pattern_list
)
result_command
+=
pattern_str
result_command
+=
pattern_str
result_command
=
result_command
[
0
:
-
backspace_num
]
result_command
=
result_command
[
0
:
-
backspace_num
]
else
:
else
:
result_command
=
result_command
[
0
:
-
backspace_num
]
result_command
=
result_command
[
0
:
-
backspace_num
]
result_command
+=
''
.
join
(
pattern_list
)
result_command
+=
pattern_str
result_command
+=
pattern_str
del_len
=
len
(
str
(
tmp
.
group
(
0
)))
-
3
del_len
=
len
(
str
(
tmp
.
group
(
0
)))
-
3
if
del_len
>
0
:
if
del_len
>
0
:
result_command
=
result_command
[
0
:
-
del_len
]
result_command
=
result_command
[
0
:
-
del_len
]
reach_backspace_flag
=
False
reach_backspace_flag
=
False
reach_backspace_second_flag
=
False
backspace_num
=
0
backspace_num
=
0
pattern_str
=
''
del
pattern_list
[:]
del
backspace_list
[:]
pattern_str
=
''
str_r
=
str_r
[
len
(
str
(
tmp
.
group
(
0
))):]
str_r
=
str_r
[
len
(
str
(
tmp
.
group
(
0
))):]
continue
continue
tmp
=
re
.
match
(
r'\x08+'
,
str_r
)
#将遇到的退格数字存放到队列中
tmp
=
re
.
match
(
r'\x08+'
,
str_r
)
if
tmp
:
if
tmp
:
str_r
=
str_r
[
len
(
str
(
tmp
.
group
(
0
))):]
if
len
(
str_r
)
!=
0
:
if
reach_backspace_flag
:
if
reach_backspace_flag
:
reach_backspace_second_flag
=
True
result_command
=
result_command
[
0
:
-
backspace_num
]
+
pattern_str
pattern_str
=
''
else
:
else
:
reach_backspace_flag
=
True
reach_backspace_flag
=
True
str_r
=
str_r
[
len
(
str
(
tmp
.
group
(
0
))):]
backspace_num
=
len
(
str
(
tmp
.
group
(
0
)))
if
len
(
str_r
)
!=
0
:
#如果退格键在最后,则放弃
backspace_list
.
append
(
len
(
str
(
tmp
.
group
(
0
))))
continue
continue
else
:
break
if
reach_backspace_flag
:
if
reach_backspace_flag
:
if
not
reach_backspace_second_flag
:
pattern_str
+=
str_r
[
0
]
pattern_str
+=
str_r
[
0
]
else
:
else
:
pattern_list
.
append
(
pattern_str
)
pattern_str
=
str_r
[
0
]
reach_backspace_second_flag
=
False
else
:
result_command
+=
str_r
[
0
]
result_command
+=
str_r
[
0
]
str_r
=
str_r
[
1
:]
str_r
=
str_r
[
1
:]
if
pattern_str
!=
''
:
if
backspace_num
>
0
:
pattern_list
.
append
(
pattern_str
)
result_command
=
result_command
[
0
:
-
backspace_num
]
+
pattern_str
#退格队列中还有腿哥键,则进行删除操作
if
len
(
backspace_list
)
>
0
:
for
backspace
in
backspace_list
:
if
int
(
backspace
)
>=
len
(
result_command
):
result_command
=
pattern_list
[
0
]
else
:
result_command
=
result_command
[:
-
int
(
backspace
)]
result_command
+=
pattern_list
[
0
]
pattern_list
=
pattern_list
[
1
:]
control_char
=
re
.
compile
(
r"""
control_char
=
re
.
compile
(
r"""
\x1b[ #
%
()*+\-.\/]. |
\x1b[ #
%
()*+\-.\/]. |
...
@@ -199,44 +156,13 @@ class Tty(object):
...
@@ -199,44 +156,13 @@ class Tty(object):
[\x80-\x9f] | (?:\x1b\]0.*) | \[.*@.*\][\$#] | (.*mysql>.*) #匹配 所有控制字符
[\x80-\x9f] | (?:\x1b\]0.*) | \[.*@.*\][\$#] | (.*mysql>.*) #匹配 所有控制字符
"""
,
re
.
X
)
"""
,
re
.
X
)
result_command
=
control_char
.
sub
(
''
,
result_command
.
strip
())
result_command
=
control_char
.
sub
(
''
,
result_command
.
strip
())
global
VIM_FLAG
if
not
self
.
vim_flag
:
global
VIM_COMMAND
if
not
VIM_FLAG
:
if
result_command
.
startswith
(
'vi'
):
if
result_command
.
startswith
(
'vi'
):
VIM_FLAG
=
True
self
.
vim_flag
=
True
VIM_COMMAND
=
result_command
return
result_command
.
decode
(
'utf8'
,
"ignore"
)
return
result_command
.
decode
(
'utf8'
,
"ignore"
)
else
:
if
check_vim_status
(
VIM_COMMAND
,
ssh
):
VIM_FLAG
=
False
VIM_COMMAND
=
''
if
result_command
.
endswith
(
':wq'
)
or
result_command
.
endswith
(
':wq!'
)
or
result_command
.
endswith
(
':q!'
):
return
''
return
result_command
.
decode
(
'utf8'
,
"ignore"
)
else
:
else
:
return
''
return
''
@staticmethod
def
remove_control_char
(
str_r
):
"""
处理日志特殊字符
"""
control_char
=
re
.
compile
(
r"""
\x1b[ #
%
()*+\-.\/]. |
\r | #匹配 回车符(CR)
(?:\x1b\[|\x9b) [ -?]* [@-~] | #匹配 控制顺序描述符(CSI)... Cmd
(?:\x1b\]|\x9d) .*? (?:\x1b\\|[\a\x9c]) | \x07 | #匹配 操作系统指令(OSC)...终止符或振铃符(ST|BEL)
(?:\x1b[P^_]|[\x90\x9e\x9f]) .*? (?:\x1b\\|\x9c) | #匹配 设备控制串或私讯或应用程序命令(DCS|PM|APC)...终止符(ST)
\x1b. #匹配 转义过后的字符
[\x80-\x9f] #匹配 所有控制字符
"""
,
re
.
X
)
backspace
=
re
.
compile
(
r"[^\b][\b]"
)
line_filtered
=
control_char
.
sub
(
''
,
str_r
.
rstrip
())
while
backspace
.
search
(
line_filtered
):
line_filtered
=
backspace
.
sub
(
''
,
line_filtered
)
return
line_filtered
def
get_log
(
self
):
def
get_log
(
self
):
"""
"""
Logging user command and output.
Logging user command and output.
...
@@ -283,11 +209,6 @@ class Tty(object):
...
@@ -283,11 +209,6 @@ class Tty(object):
"""
"""
获取需要登陆的主机的信息和映射用户的账号密码
获取需要登陆的主机的信息和映射用户的账号密码
"""
"""
# 1. get ip, port
# 2. get 映射用户
# 3. get 映射用户的账号,密码或者key
# self.connect_info = {'user': '', 'asset': '', 'ip': '', 'port': 0, 'role_name': '', 'role_pass': '', 'role_key': ''}
asset_info
=
get_asset_info
(
self
.
asset
)
asset_info
=
get_asset_info
(
self
.
asset
)
self
.
connect_info
=
{
'user'
:
self
.
user
,
'asset'
:
self
.
asset
,
'ip'
:
asset_info
.
get
(
'ip'
),
self
.
connect_info
=
{
'user'
:
self
.
user
,
'asset'
:
self
.
asset
,
'ip'
:
asset_info
.
get
(
'ip'
),
'port'
:
int
(
asset_info
.
get
(
'port'
)),
'role_name'
:
self
.
role
.
name
,
'port'
:
int
(
asset_info
.
get
(
'port'
)),
'role_name'
:
self
.
role
.
name
,
...
@@ -374,7 +295,6 @@ class SshTty(Tty):
...
@@ -374,7 +295,6 @@ class SshTty(Tty):
pre_timestamp
=
time
.
time
()
pre_timestamp
=
time
.
time
()
data
=
''
data
=
''
input_mode
=
False
input_mode
=
False
try
:
try
:
tty
.
setraw
(
sys
.
stdin
.
fileno
())
tty
.
setraw
(
sys
.
stdin
.
fileno
())
tty
.
setcbreak
(
sys
.
stdin
.
fileno
())
tty
.
setcbreak
(
sys
.
stdin
.
fileno
())
...
@@ -391,6 +311,8 @@ class SshTty(Tty):
...
@@ -391,6 +311,8 @@ class SshTty(Tty):
x
=
self
.
channel
.
recv
(
1024
)
x
=
self
.
channel
.
recv
(
1024
)
if
len
(
x
)
==
0
:
if
len
(
x
)
==
0
:
break
break
if
self
.
vim_flag
:
self
.
vim_data
+=
x
sys
.
stdout
.
write
(
x
)
sys
.
stdout
.
write
(
x
)
sys
.
stdout
.
flush
()
sys
.
stdout
.
flush
()
now_timestamp
=
time
.
time
()
now_timestamp
=
time
.
time
()
...
@@ -409,12 +331,20 @@ class SshTty(Tty):
...
@@ -409,12 +331,20 @@ class SshTty(Tty):
if
sys
.
stdin
in
r
:
if
sys
.
stdin
in
r
:
x
=
os
.
read
(
sys
.
stdin
.
fileno
(),
1
)
x
=
os
.
read
(
sys
.
stdin
.
fileno
(),
1
)
input_mode
=
True
input_mode
=
True
if
str
(
x
)
in
[
'
\r
'
,
'
\n
'
,
'
\r\n
'
]:
if
str
(
x
)
in
[
'
\r
'
,
'
\n
'
,
'
\r\n
'
]:
data
=
self
.
deal_command
(
data
,
self
.
ssh
)
if
self
.
vim_flag
:
match
=
self
.
ps1_pattern
.
search
(
self
.
vim_data
)
if
match
:
self
.
vim_flag
=
False
data
=
self
.
deal_command
(
data
)[
0
:
200
]
if
len
(
data
)
>
0
:
TtyLog
(
log
=
log
,
datetime
=
datetime
.
datetime
.
now
(),
cmd
=
data
)
.
save
()
else
:
data
=
self
.
deal_command
(
data
)[
0
:
200
]
if
len
(
data
)
>
0
:
TtyLog
(
log
=
log
,
datetime
=
datetime
.
datetime
.
now
(),
cmd
=
data
)
.
save
()
TtyLog
(
log
=
log
,
datetime
=
datetime
.
datetime
.
now
(),
cmd
=
data
)
.
save
()
data
=
''
data
=
''
self
.
vim_data
=
''
input_mode
=
False
input_mode
=
False
if
len
(
x
)
==
0
:
if
len
(
x
)
==
0
:
...
...
run_websocket.py
View file @
12f33176
...
@@ -20,15 +20,9 @@ from tornado.websocket import WebSocketClosedError
...
@@ -20,15 +20,9 @@ from tornado.websocket import WebSocketClosedError
from
tornado.options
import
define
,
options
from
tornado.options
import
define
,
options
from
pyinotify
import
WatchManager
,
Notifier
,
ProcessEvent
,
IN_DELETE
,
IN_CREATE
,
IN_MODIFY
,
AsyncNotifier
from
pyinotify
import
WatchManager
,
Notifier
,
ProcessEvent
,
IN_DELETE
,
IN_CREATE
,
IN_MODIFY
,
AsyncNotifier
import
select
# from gevent import monkey
from
connect
import
Tty
,
User
,
Asset
,
PermRole
# monkey.patch_all()
# import gevent
# from gevent.socket import wait_read, wait_write
import
struct
,
fcntl
,
signal
,
socket
,
select
,
fnmatch
import
paramiko
from
connect
import
Tty
from
connect
import
TtyLog
,
Log
from
connect
import
TtyLog
,
Log
try
:
try
:
...
@@ -217,7 +211,10 @@ class WebTerminalHandler(tornado.websocket.WebSocketHandler):
...
@@ -217,7 +211,10 @@ class WebTerminalHandler(tornado.websocket.WebSocketHandler):
username
=
self
.
get_argument
(
'username'
,
''
)
username
=
self
.
get_argument
(
'username'
,
''
)
token
=
self
.
get_argument
(
'token'
,
''
)
token
=
self
.
get_argument
(
'token'
,
''
)
print
asset_name
,
username
,
token
print
asset_name
,
username
,
token
self
.
term
=
WebTty
(
'a'
,
'b'
)
user
=
User
.
objects
.
get
(
username
=
'lastimac'
)
asset
=
Asset
.
objects
.
get
(
ip
=
'192.168.244.129'
)
role
=
PermRole
.
objects
.
get
(
name
=
'dev'
)
self
.
term
=
WebTty
(
user
,
asset
,
role
)
self
.
term
.
get_connection
()
self
.
term
.
get_connection
()
self
.
term
.
channel
=
self
.
term
.
ssh
.
invoke_shell
(
term
=
'xterm'
)
self
.
term
.
channel
=
self
.
term
.
ssh
.
invoke_shell
(
term
=
'xterm'
)
WebTerminalHandler
.
tasks
.
append
(
MyThread
(
target
=
self
.
forward_outbound
))
WebTerminalHandler
.
tasks
.
append
(
MyThread
(
target
=
self
.
forward_outbound
))
...
@@ -236,7 +233,17 @@ class WebTerminalHandler(tornado.websocket.WebSocketHandler):
...
@@ -236,7 +233,17 @@ class WebTerminalHandler(tornado.websocket.WebSocketHandler):
if
data
.
get
(
'data'
):
if
data
.
get
(
'data'
):
self
.
term
.
input_mode
=
True
self
.
term
.
input_mode
=
True
if
str
(
data
[
'data'
])
in
[
'
\r
'
,
'
\n
'
,
'
\r\n
'
]:
if
str
(
data
[
'data'
])
in
[
'
\r
'
,
'
\n
'
,
'
\r\n
'
]:
TtyLog
(
log
=
self
.
log
,
datetime
=
datetime
.
datetime
.
now
(),
cmd
=
self
.
term
.
deal_command
(
self
.
term
.
data
,
self
.
term
.
ssh
))
.
save
()
if
self
.
term
.
vim_flag
:
match
=
self
.
term
.
ps1_pattern
.
search
(
self
.
term
.
vim_data
)
if
match
:
self
.
term
.
vim_flag
=
False
vim_data
=
self
.
term
.
deal_command
(
self
.
term
.
vim_data
)[
0
:
200
]
if
len
(
data
)
>
0
:
TtyLog
(
log
=
self
.
log
,
datetime
=
datetime
.
datetime
.
now
(),
cmd
=
vim_data
)
.
save
()
TtyLog
(
log
=
self
.
log
,
datetime
=
datetime
.
datetime
.
now
(),
cmd
=
self
.
term
.
deal_command
(
self
.
term
.
data
)[
0
:
200
])
.
save
()
self
.
term
.
vim_data
=
''
self
.
term
.
data
=
''
self
.
term
.
data
=
''
self
.
term
.
input_mode
=
False
self
.
term
.
input_mode
=
False
self
.
term
.
channel
.
send
(
data
[
'data'
])
self
.
term
.
channel
.
send
(
data
[
'data'
])
...
@@ -267,6 +274,8 @@ class WebTerminalHandler(tornado.websocket.WebSocketHandler):
...
@@ -267,6 +274,8 @@ class WebTerminalHandler(tornado.websocket.WebSocketHandler):
if
not
len
(
recv
):
if
not
len
(
recv
):
return
return
data
+=
recv
data
+=
recv
if
self
.
term
.
vim_flag
:
self
.
term
.
vim_data
+=
recv
try
:
try
:
self
.
write_message
(
json
.
dumps
({
'data'
:
data
}))
self
.
write_message
(
json
.
dumps
({
'data'
:
data
}))
now_timestamp
=
time
.
time
()
now_timestamp
=
time
.
time
()
...
@@ -290,4 +299,5 @@ if __name__ == '__main__':
...
@@ -290,4 +299,5 @@ if __name__ == '__main__':
server
.
bind
(
options
.
port
,
options
.
host
)
server
.
bind
(
options
.
port
,
options
.
host
)
# server.listen(options.port)
# server.listen(options.port)
server
.
start
(
num_processes
=
1
)
server
.
start
(
num_processes
=
1
)
print
"Run server on
%
s:
%
s"
%
(
options
.
host
,
options
.
port
)
tornado
.
ioloop
.
IOLoop
.
instance
()
.
start
()
tornado
.
ioloop
.
IOLoop
.
instance
()
.
start
()
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment