Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
C
coco
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
coco
Commits
8452d75d
Commit
8452d75d
authored
Nov 12, 2017
by
ibuler
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Finished SDK
parent
cb232113
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
72 additions
and
27 deletions
+72
-27
forward.py
coco/forward.py
+13
-7
interactive.py
coco/interactive.py
+41
-15
utils.py
coco/utils.py
+18
-5
No files found.
coco/forward.py
View file @
8452d75d
...
...
@@ -9,6 +9,7 @@ import time
from
.session
import
Session
from
.models
import
Server
from
.utils
import
wrap_with_line_feed
as
wr
logger
=
logging
.
getLogger
(
__file__
)
...
...
@@ -24,7 +25,7 @@ class ProxyServer:
self
.
connecting
=
True
def
proxy
(
self
,
asset
,
system_user
):
self
.
send_connecting_message
()
self
.
send_connecting_message
(
asset
,
system_user
)
self
.
server
=
self
.
get_server_conn
(
asset
,
system_user
)
if
self
.
server
is
None
:
return
...
...
@@ -41,23 +42,28 @@ class ProxyServer:
system user
:return: True or False
"""
return
True
return
self
.
app
.
service
.
validate_user_asset_permission
(
self
.
client
.
user
.
id
,
asset
.
id
,
system_user
.
id
)
def
get_system_user_auth
(
self
,
system_user
):
"""
Get the system user auth ..., using this to connect asset
:return: system user have full info
"""
system_user
.
password
,
system_user
.
private_key
=
\
self
.
app
.
service
.
get_system_user_auth_info
(
system_user
)
def
get_server_conn
(
self
,
asset
,
system_user
):
logger
.
info
(
"Connect to
%
s"
%
asset
.
hostname
)
if
not
self
.
validate_permission
(
asset
,
system_user
):
self
.
client
.
send
(
b
'No permission'
)
self
.
client
.
send
(
_
(
'No permission'
)
)
return
None
self
.
get_system_user_auth
(
system_user
)
ssh
=
paramiko
.
SSHClient
()
ssh
.
set_missing_host_key_policy
(
paramiko
.
AutoAddPolicy
())
print
(
asset
.
ip
,
asset
.
port
,
system_user
.
username
,
system_user
.
password
,
system_user
.
private_key
)
try
:
ssh
.
connect
(
asset
.
ip
,
port
=
asset
.
port
,
username
=
system_user
.
username
,
...
...
@@ -65,10 +71,10 @@ class ProxyServer:
pkey
=
system_user
.
private_key
,
timeout
=
TIMEOUT
)
except
paramiko
.
AuthenticationException
as
e
:
self
.
client
.
send
(
"[Errno 66] Authentication failed: {}"
.
format
(
e
)
.
encode
(
"utf-8"
))
self
.
client
.
send
(
wr
(
"[Errno 66] {}"
.
format
(
e
)
))
return
None
except
socket
.
error
as
e
:
self
.
client
.
send
(
" {}"
.
format
(
e
)
.
encode
(
"utf-8"
))
self
.
client
.
send
(
wr
(
" {}"
.
format
(
e
)
))
return
None
finally
:
self
.
connecting
=
False
...
...
@@ -93,10 +99,10 @@ class ProxyServer:
thread
.
daemon
=
True
thread
.
start
()
def
send_connecting_message
(
self
):
def
send_connecting_message
(
self
,
asset
,
system_user
):
def
func
():
delay
=
0.0
self
.
client
.
send
(
'Connecting to {}
{:.1f}'
.
format
(
self
.
server
,
delay
)
.
encode
(
'utf-8'
))
self
.
client
.
send
(
'Connecting to {}
@{} {:.1f}'
.
format
(
system_user
,
asset
,
delay
))
while
self
.
connecting
and
delay
<
TIMEOUT
:
self
.
client
.
send
(
'
\x08\x08\x08
{:.1f}'
.
format
(
delay
)
.
encode
(
'utf-8'
))
time
.
sleep
(
0.1
)
...
...
coco/interactive.py
View file @
8452d75d
...
...
@@ -9,7 +9,8 @@ from jms.models import Asset, SystemUser, AssetGroup
from
.
import
char
from
.utils
import
wrap_with_line_feed
as
wr
,
wrap_with_title
as
title
,
\
wrap_with_primary
as
primary
,
wrap_with_warning
as
warning
,
\
is_obj_attr_has
,
is_obj_attr_eq
,
sort_assets
,
TtyIOParser
is_obj_attr_has
,
is_obj_attr_eq
,
sort_assets
,
TtyIOParser
,
\
ugettext
as
_
from
.forward
import
ProxyServer
from
.session
import
Session
...
...
@@ -31,7 +32,7 @@ class InteractiveServer:
def
display_banner
(
self
):
self
.
client
.
send
(
char
.
CLEAR_CHAR
)
banner
=
"""
\n
{title} {user}, 欢迎使用Jumpserver开源跳板机系统 {end}
\r\n\r
banner
=
_
(
"""
\n
{title} {user}, 欢迎使用Jumpserver开源跳板机系统 {end}
\r\n\r
1) 输入 {green}ID{end} 直接登录 或 输入{green}部分 IP,主机名,备注{end} 进行搜索登录(如果唯一).
\r
2) 输入 {green}/{end} + {green}IP, 主机名 or 备注 {end}搜索. 如: /ip
\r
3) 输入 {green}P/p{end} 显示您有权限的主机.
\r
...
...
@@ -41,13 +42,13 @@ class InteractiveServer:
7) 输入 {green}U/u{end} 批量上传文件.(未完成)
\r
8) 输入 {green}D/d{end} 批量下载文件.(未完成)
\r
9) 输入 {green}H/h{end} 帮助.
\r
0) 输入 {green}Q/q{end} 退出.
\r\n
"""
.
format
(
0) 输入 {green}Q/q{end} 退出.
\r\n
"""
)
.
format
(
title
=
"
\033
[1;32m"
,
green
=
"
\033
[32m"
,
end
=
"
\033
[0m"
,
user
=
self
.
client
.
user
)
self
.
client
.
send
(
banner
)
def
get_choice
(
self
,
prompt
=
b
'Opt> '
):
def
get_choice
(
self
,
prompt
=
'Opt> '
):
"""实现了一个ssh input, 提示用户输入, 获取并返回
:return user input string
...
...
@@ -150,10 +151,10 @@ class InteractiveServer:
self
.
get_user_asset_groups
()
if
len
(
self
.
asset_groups
)
==
0
:
self
.
client
.
send
(
warning
(
"Nothing"
))
self
.
client
.
send
(
warning
(
_
(
"Nothing"
)
))
return
fake_group
=
AssetGroup
(
name
=
"Name"
,
assets_amount
=
"Assets"
,
comment
=
"Comment"
)
fake_group
=
AssetGroup
(
name
=
_
(
"Name"
),
assets_amount
=
_
(
"Assets"
),
comment
=
_
(
"Comment"
)
)
id_max_length
=
max
(
len
(
str
(
len
(
self
.
asset_groups
))),
5
)
name_max_length
=
max
(
max
([
len
(
group
.
name
)
for
group
in
self
.
asset_groups
]),
15
)
amount_max_length
=
max
(
len
(
str
(
max
([
group
.
assets_amount
for
group
in
self
.
asset_groups
]))),
10
)
...
...
@@ -164,7 +165,7 @@ class InteractiveServer:
self
.
client
.
send
(
title
(
header
.
format
(
fake_group
,
"ID"
)))
for
index
,
group
in
enumerate
(
self
.
asset_groups
):
self
.
client
.
send
(
wr
(
line
.
format
(
group
,
index
)))
self
.
client
.
send
(
wr
(
"Total: {}"
.
format
(
len
(
self
.
asset_groups
)),
before
=
1
))
self
.
client
.
send
(
wr
(
_
(
"Total: {}"
)
.
format
(
len
(
self
.
asset_groups
)),
before
=
1
))
def
display_group_assets
(
self
,
_id
):
self
.
search_result
=
self
.
asset_groups
[
_id
]
.
assets_granted
...
...
@@ -176,7 +177,7 @@ class InteractiveServer:
return
self
.
search_result
=
sort_assets
(
self
.
search_result
,
self
.
app
.
config
[
"ASSET_LIST_SORT_BY"
])
fake_asset
=
Asset
(
hostname
=
"Hostname"
,
ip
=
"IP"
,
system_users_join
=
"LoginAs"
,
comment
=
"Comment"
)
fake_asset
=
Asset
(
hostname
=
_
(
"Hostname"
),
ip
=
_
(
"IP"
),
system_users_join
=
_
(
"LoginAs"
),
comment
=
_
(
"Comment"
)
)
id_max_length
=
max
(
len
(
str
(
len
(
self
.
search_result
))),
3
)
hostname_max_length
=
max
(
max
([
len
(
asset
.
hostname
)
for
asset
in
self
.
search_result
+
[
fake_asset
]]),
15
)
sysuser_max_length
=
max
([
len
(
asset
.
system_users_join
)
for
asset
in
self
.
search_result
+
[
fake_asset
]])
...
...
@@ -188,7 +189,7 @@ class InteractiveServer:
self
.
client
.
send
(
wr
(
title
(
header
.
format
(
fake_asset
,
"ID"
))))
for
index
,
asset
in
enumerate
(
self
.
search_result
,
1
):
self
.
client
.
send
(
wr
(
line
.
format
(
asset
,
index
)))
self
.
client
.
send
(
wr
(
"Total: {}"
.
format
(
len
(
self
.
search_result
)),
before
=
1
))
self
.
client
.
send
(
wr
(
_
(
"Total: {}"
)
.
format
(
len
(
self
.
search_result
)),
before
=
1
))
def
search_and_display
(
self
,
q
):
self
.
search_assets
(
q
)
...
...
@@ -209,14 +210,39 @@ class InteractiveServer:
thread
.
start
()
def
choose_system_user
(
self
,
system_users
):
pass
if
len
(
system_users
)
==
1
:
return
system_users
[
0
]
elif
len
(
system_users
)
==
0
:
return
None
def
search_and_proxy
(
self
,
opt
,
from_result
=
False
):
asset
=
Asset
(
id
=
1
,
hostname
=
"testserver"
,
ip
=
"123.57.183.135"
,
port
=
8022
)
system_user
=
SystemUser
(
id
=
2
,
username
=
"web"
,
password
=
"redhat123"
,
name
=
"web"
)
self
.
proxy
(
asset
,
system_user
)
while
True
:
self
.
client
.
send
(
wr
(
_
(
"Choose one to login: "
)))
self
.
display_system_users
(
system_users
)
opt
=
self
.
get_choice
(
"ID> "
)
if
opt
.
isdigit
()
and
len
(
system_users
)
>
int
(
opt
):
return
system_users
[
int
(
opt
)]
elif
opt
in
[
'q'
,
'Q'
]:
break
else
:
for
system_user
in
system_users
:
if
system_user
.
username
==
opt
:
return
system_user
def
display_system_users
(
self
,
system_users
):
for
index
,
system_user
in
enumerate
(
system_users
):
self
.
client
.
send
(
wr
(
"{} {}"
.
format
(
index
,
system_user
.
username
)))
def
search_and_proxy
(
self
,
opt
):
self
.
search_assets
(
opt
)
if
len
(
self
.
search_result
)
==
1
:
self
.
proxy
(
self
.
search_result
[
0
])
else
:
self
.
display_search_result
()
def
proxy
(
self
,
asset
,
system_user
):
def
proxy
(
self
,
asset
):
system_user
=
self
.
choose_system_user
(
asset
.
system_users_granted
)
if
system_user
is
None
:
self
.
client
.
send
(
_
(
"No user"
))
forwarder
=
ProxyServer
(
self
.
app
,
self
.
client
)
forwarder
.
proxy
(
asset
,
system_user
)
...
...
coco/utils.py
View file @
8452d75d
...
...
@@ -10,18 +10,16 @@ import base64
import
calendar
import
time
import
datetime
import
gettext
from
io
import
StringIO
import
paramiko
import
pyte
import
pytz
from
email.utils
import
formatdate
from
queue
import
Queue
,
Empty
try
:
from
Queue
import
Queue
,
Empty
except
ImportError
:
from
queue
import
Queue
,
Empty
BASE_DIR
=
os
.
path
.
abspath
(
os
.
path
.
dirname
(
os
.
path
.
dirname
(
__file__
)))
def
ssh_key_string_to_obj
(
text
):
...
...
@@ -348,4 +346,19 @@ class MultiQueue(Queue):
return
items
def
_gettext
():
gettext
.
bindtextdomain
(
"coco"
,
os
.
path
.
join
(
BASE_DIR
,
"locale"
))
gettext
.
textdomain
(
"coco"
)
return
gettext
.
gettext
def
make_message
():
os
.
makedirs
(
os
.
path
.
join
(
BASE_DIR
,
"locale"
,
"zh_CN"
))
pass
def
compile_message
():
pass
ugettext
=
_gettext
()
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