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
08b15983
Unverified
Commit
08b15983
authored
Jan 20, 2018
by
老广
Committed by
GitHub
Jan 20, 2018
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #29 from jumpserver/dev
Merge to master
parents
9698e4f8
c1288ecd
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
106 additions
and
58 deletions
+106
-58
app.py
coco/app.py
+2
-2
httpd.py
coco/httpd.py
+34
-17
interactive.py
coco/interactive.py
+22
-6
models.py
coco/models.py
+3
-3
proxy.py
coco/proxy.py
+16
-7
sshd.py
coco/sshd.py
+18
-10
utils.py
coco/utils.py
+9
-4
logo.txt
logo.txt
+1
-8
requirements.txt
requirements/requirements.txt
+1
-1
No files found.
coco/app.py
View file @
08b15983
...
@@ -150,10 +150,10 @@ class Coco:
...
@@ -150,10 +150,10 @@ class Coco:
for
s
in
self
.
sessions
:
for
s
in
self
.
sessions
:
if
not
s
.
stop_evt
.
is_set
():
if
not
s
.
stop_evt
.
is_set
():
continue
continue
if
s
.
date_
finishe
d
is
None
:
if
s
.
date_
en
d
is
None
:
self
.
remove_session
(
s
)
self
.
remove_session
(
s
)
continue
continue
delta
=
datetime
.
datetime
.
now
()
-
s
.
date_
finishe
d
delta
=
datetime
.
datetime
.
now
()
-
s
.
date_
en
d
if
delta
>
datetime
.
timedelta
(
seconds
=
interval
*
5
):
if
delta
>
datetime
.
timedelta
(
seconds
=
interval
*
5
):
self
.
remove_session
(
s
)
self
.
remove_session
(
s
)
time
.
sleep
(
interval
)
time
.
sleep
(
interval
)
...
...
coco/httpd.py
View file @
08b15983
...
@@ -26,7 +26,6 @@ class BaseWebSocketHandler:
...
@@ -26,7 +26,6 @@ class BaseWebSocketHandler:
def
prepare
(
self
,
request
):
def
prepare
(
self
,
request
):
# self.app = self.settings["app"]
# self.app = self.settings["app"]
child
,
parent
=
socket
.
socketpair
()
if
request
.
headers
.
getlist
(
"X-Forwarded-For"
):
if
request
.
headers
.
getlist
(
"X-Forwarded-For"
):
remote_ip
=
request
.
headers
.
getlist
(
"X-Forwarded-For"
)[
0
]
remote_ip
=
request
.
headers
.
getlist
(
"X-Forwarded-For"
)[
0
]
else
:
else
:
...
@@ -36,10 +35,6 @@ class BaseWebSocketHandler:
...
@@ -36,10 +35,6 @@ class BaseWebSocketHandler:
self
.
clients
[
request
.
sid
][
"request"
]
.
meta
=
{
"width"
:
self
.
clients
[
request
.
sid
][
"cols"
],
self
.
clients
[
request
.
sid
][
"request"
]
.
meta
=
{
"width"
:
self
.
clients
[
request
.
sid
][
"cols"
],
"height"
:
self
.
clients
[
request
.
sid
][
"rows"
]}
"height"
:
self
.
clients
[
request
.
sid
][
"rows"
]}
# self.request.__dict__.update(request.__dict__)
# self.request.__dict__.update(request.__dict__)
self
.
clients
[
request
.
sid
][
"client"
]
=
Client
(
parent
,
self
.
clients
[
request
.
sid
][
"request"
])
self
.
clients
[
request
.
sid
][
"proxy"
]
=
WSProxy
(
self
,
child
,
self
.
clients
[
request
.
sid
][
"room"
])
self
.
app
.
clients
.
append
(
self
.
clients
[
request
.
sid
][
"client"
])
self
.
clients
[
request
.
sid
][
"forwarder"
]
=
ProxyServer
(
self
.
app
,
self
.
clients
[
request
.
sid
][
"client"
])
def
check_origin
(
self
,
origin
):
def
check_origin
(
self
,
origin
):
return
True
return
True
...
@@ -64,9 +59,10 @@ class SSHws(Namespace, BaseWebSocketHandler):
...
@@ -64,9 +59,10 @@ class SSHws(Namespace, BaseWebSocketHandler):
"cols"
:
int
(
request
.
cookies
.
get
(
'cols'
,
80
)),
"cols"
:
int
(
request
.
cookies
.
get
(
'cols'
,
80
)),
"rows"
:
int
(
request
.
cookies
.
get
(
'rows'
,
24
)),
"rows"
:
int
(
request
.
cookies
.
get
(
'rows'
,
24
)),
"room"
:
room
,
"room"
:
room
,
"chan"
:
None
,
# "chan": dict(),
"proxy"
:
None
,
"proxy"
:
dict
(),
"client"
:
None
,
"client"
:
dict
(),
"forwarder"
:
dict
(),
"request"
:
None
,
"request"
:
None
,
}
}
self
.
rooms
[
room
]
=
{
self
.
rooms
[
room
]
=
{
...
@@ -80,18 +76,31 @@ class SSHws(Namespace, BaseWebSocketHandler):
...
@@ -80,18 +76,31 @@ class SSHws(Namespace, BaseWebSocketHandler):
self
.
prepare
(
request
)
self
.
prepare
(
request
)
def
on_data
(
self
,
message
):
def
on_data
(
self
,
message
):
if
self
.
clients
[
request
.
sid
][
"proxy"
]:
if
message
[
'room'
]
and
self
.
clients
[
request
.
sid
][
"proxy"
][
message
[
'room'
]
]:
self
.
clients
[
request
.
sid
][
"proxy"
]
.
send
({
"data"
:
message
})
self
.
clients
[
request
.
sid
][
"proxy"
]
[
message
[
'room'
]]
.
send
({
"data"
:
message
[
'data'
]
})
def
on_host
(
self
,
message
):
def
on_host
(
self
,
message
):
# 此处获取主机的信息
# 此处获取主机的信息
uuid
=
message
.
get
(
'uuid'
,
None
)
connection
=
str
(
uuid
.
uuid4
())
assetID
=
message
.
get
(
'uuid'
,
None
)
userid
=
message
.
get
(
'userid'
,
None
)
userid
=
message
.
get
(
'userid'
,
None
)
if
uuid
and
userid
:
self
.
emit
(
'room'
,
{
'room'
:
connection
,
'secret'
:
message
[
'secret'
]})
asset
=
self
.
app
.
service
.
get_asset
(
uuid
)
if
assetID
and
userid
:
asset
=
self
.
app
.
service
.
get_asset
(
assetID
)
system_user
=
self
.
app
.
service
.
get_system_user
(
userid
)
system_user
=
self
.
app
.
service
.
get_system_user
(
userid
)
if
system_user
:
if
system_user
:
self
.
socketio
.
start_background_task
(
self
.
clients
[
request
.
sid
][
"forwarder"
]
.
proxy
,
asset
,
system_user
)
child
,
parent
=
socket
.
socketpair
()
self
.
clients
[
request
.
sid
][
"client"
][
connection
]
=
Client
(
parent
,
self
.
clients
[
request
.
sid
][
"request"
])
self
.
clients
[
request
.
sid
][
"proxy"
][
connection
]
=
WSProxy
(
self
,
child
,
self
.
clients
[
request
.
sid
][
"room"
],
connection
)
self
.
app
.
clients
.
append
(
self
.
clients
[
request
.
sid
][
"client"
][
connection
])
self
.
clients
[
request
.
sid
][
"forwarder"
][
connection
]
=
ProxyServer
(
self
.
app
,
self
.
clients
[
request
.
sid
][
"client"
][
connection
])
self
.
socketio
.
start_background_task
(
self
.
clients
[
request
.
sid
][
"forwarder"
][
connection
]
.
proxy
,
asset
,
system_user
)
# self.forwarder.proxy(self.asset, system_user)
# self.forwarder.proxy(self.asset, system_user)
else
:
else
:
self
.
on_disconnect
()
self
.
on_disconnect
()
...
@@ -125,13 +134,21 @@ class SSHws(Namespace, BaseWebSocketHandler):
...
@@ -125,13 +134,21 @@ class SSHws(Namespace, BaseWebSocketHandler):
def
on_disconnect
(
self
):
def
on_disconnect
(
self
):
self
.
on_leave
(
self
.
clients
[
request
.
sid
][
"room"
])
self
.
on_leave
(
self
.
clients
[
request
.
sid
][
"room"
])
try
:
try
:
# todo: there maybe have bug
del
self
.
clients
[
request
.
sid
]
self
.
clients
[
request
.
sid
][
"proxy"
]
.
close
()
except
:
except
:
pass
pass
# self.ssh.close()
# self.ssh.close()
pass
pass
def
on_logout
(
self
,
connection
):
print
(
"logout"
,
connection
)
if
connection
:
self
.
clients
[
request
.
sid
][
"proxy"
][
connection
]
.
close
()
del
self
.
clients
[
request
.
sid
][
"proxy"
][
connection
]
del
self
.
clients
[
request
.
sid
][
"forwarder"
][
connection
]
self
.
clients
[
request
.
sid
][
"client"
][
connection
]
.
close
()
del
self
.
clients
[
request
.
sid
][
"client"
][
connection
]
class
HttpServer
:
class
HttpServer
:
# prepare may be rewrite it
# prepare may be rewrite it
...
@@ -155,7 +172,7 @@ class HttpServer:
...
@@ -155,7 +172,7 @@ class HttpServer:
port
=
self
.
app
.
config
[
"HTTPD_PORT"
]
port
=
self
.
app
.
config
[
"HTTPD_PORT"
]
print
(
'Starting websocket server at {}:{}'
.
format
(
host
,
port
))
print
(
'Starting websocket server at {}:{}'
.
format
(
host
,
port
))
self
.
socketio
.
on_namespace
(
SSHws
(
'/ssh'
)
.
app
(
self
.
app
))
self
.
socketio
.
on_namespace
(
SSHws
(
'/ssh'
)
.
app
(
self
.
app
))
self
.
socketio
.
init_app
(
self
.
flask
)
self
.
socketio
.
init_app
(
self
.
flask
,
async_mode
=
"threading"
)
self
.
socketio
.
run
(
self
.
flask
,
port
=
port
,
host
=
host
)
self
.
socketio
.
run
(
self
.
flask
,
port
=
port
,
host
=
host
)
def
shutdown
(
self
):
def
shutdown
(
self
):
...
...
coco/interactive.py
View file @
08b15983
...
@@ -28,7 +28,7 @@ class InteractiveServer:
...
@@ -28,7 +28,7 @@ class InteractiveServer:
self
.
client
=
client
self
.
client
=
client
self
.
request
=
client
.
request
self
.
request
=
client
.
request
self
.
assets
=
None
self
.
assets
=
None
self
.
search_result
=
None
self
.
_
search_result
=
None
self
.
asset_groups
=
None
self
.
asset_groups
=
None
self
.
get_user_assets_async
()
self
.
get_user_assets_async
()
self
.
get_user_asset_groups_async
()
self
.
get_user_asset_groups_async
()
...
@@ -37,6 +37,18 @@ class InteractiveServer:
...
@@ -37,6 +37,18 @@ class InteractiveServer:
def
app
(
self
):
def
app
(
self
):
return
self
.
_app
()
return
self
.
_app
()
@property
def
search_result
(
self
):
if
self
.
_search_result
:
return
self
.
_search_result
else
:
return
None
@search_result.setter
def
search_result
(
self
,
value
):
value
=
self
.
filter_system_users
(
value
)
self
.
_search_result
=
value
def
display_banner
(
self
):
def
display_banner
(
self
):
self
.
client
.
send
(
char
.
CLEAR_CHAR
)
self
.
client
.
send
(
char
.
CLEAR_CHAR
)
logo_path
=
os
.
path
.
join
(
self
.
app
.
root_path
,
"logo.txt"
)
logo_path
=
os
.
path
.
join
(
self
.
app
.
root_path
,
"logo.txt"
)
...
@@ -173,12 +185,17 @@ class InteractiveServer:
...
@@ -173,12 +185,17 @@ class InteractiveServer:
line
=
header
+
'{0.comment:
%
s}'
%
(
comment_length
//
2
)
# comment中可能有中文
line
=
header
+
'{0.comment:
%
s}'
%
(
comment_length
//
2
)
# comment中可能有中文
header
+=
"{0.comment:
%
s}"
%
comment_length
header
+=
"{0.comment:
%
s}"
%
comment_length
self
.
client
.
send
(
title
(
header
.
format
(
fake_group
,
"ID"
)))
self
.
client
.
send
(
title
(
header
.
format
(
fake_group
,
"ID"
)))
for
index
,
group
in
enumerate
(
self
.
asset_groups
):
for
index
,
group
in
enumerate
(
self
.
asset_groups
,
1
):
self
.
client
.
send
(
wr
(
line
.
format
(
group
,
index
)))
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
):
def
display_group_assets
(
self
,
_id
):
self
.
search_result
=
self
.
asset_groups
[
_id
]
.
assets_granted
if
_id
>
len
(
self
.
asset_groups
)
or
_id
<=
0
:
self
.
client
.
send
(
wr
(
warning
(
"Not match group, select again"
)))
self
.
display_asset_groups
()
return
self
.
search_result
=
self
.
asset_groups
[
_id
-
1
]
.
assets_granted
self
.
display_search_result
()
self
.
display_search_result
()
def
display_search_result
(
self
):
def
display_search_result
(
self
):
...
@@ -214,14 +231,13 @@ class InteractiveServer:
...
@@ -214,14 +231,13 @@ class InteractiveServer:
def
filter_system_users
(
assets
):
def
filter_system_users
(
assets
):
for
asset
in
assets
:
for
asset
in
assets
:
system_users_granted
=
asset
.
system_users_granted
system_users_granted
=
asset
.
system_users_granted
high_priority
=
max
([
s
.
priority
for
s
in
system_users_granted
])
high_priority
=
max
([
s
.
priority
for
s
in
system_users_granted
])
if
system_users_granted
else
1
system_users_cleaned
=
[
s
for
s
in
system_users_granted
if
s
.
priority
==
high_priority
]
system_users_cleaned
=
[
s
for
s
in
system_users_granted
if
s
.
priority
==
high_priority
]
asset
.
system_users_granted
=
system_users_cleaned
asset
.
system_users_granted
=
system_users_cleaned
return
assets
return
assets
def
get_user_assets
(
self
):
def
get_user_assets
(
self
):
assets
=
self
.
app
.
service
.
get_user_assets
(
self
.
client
.
user
)
self
.
assets
=
self
.
app
.
service
.
get_user_assets
(
self
.
client
.
user
)
self
.
assets
=
self
.
filter_system_users
(
assets
)
logger
.
debug
(
"Get user {} assets total: {}"
.
format
(
self
.
client
.
user
,
len
(
self
.
assets
)))
logger
.
debug
(
"Get user {} assets total: {}"
.
format
(
self
.
client
.
user
,
len
(
self
.
assets
)))
def
get_user_assets_async
(
self
):
def
get_user_assets_async
(
self
):
...
...
coco/models.py
View file @
08b15983
...
@@ -186,7 +186,7 @@ class WSProxy:
...
@@ -186,7 +186,7 @@ class WSProxy:
```
```
"""
"""
def
__init__
(
self
,
ws
,
child
,
room
):
def
__init__
(
self
,
ws
,
child
,
room
,
connection
):
"""
"""
:param ws: websocket instance or handler, have write_message method
:param ws: websocket instance or handler, have write_message method
:param child: sock child pair
:param child: sock child pair
...
@@ -196,6 +196,7 @@ class WSProxy:
...
@@ -196,6 +196,7 @@ class WSProxy:
self
.
stop_event
=
threading
.
Event
()
self
.
stop_event
=
threading
.
Event
()
self
.
room
=
room
self
.
room
=
room
self
.
auto_forward
()
self
.
auto_forward
()
self
.
connection
=
connection
def
send
(
self
,
msg
):
def
send
(
self
,
msg
):
"""
"""
...
@@ -215,7 +216,7 @@ class WSProxy:
...
@@ -215,7 +216,7 @@ class WSProxy:
data
=
self
.
child
.
recv
(
BUF_SIZE
)
data
=
self
.
child
.
recv
(
BUF_SIZE
)
if
len
(
data
)
==
0
:
if
len
(
data
)
==
0
:
self
.
close
()
self
.
close
()
self
.
ws
.
emit
(
"data"
,
data
.
decode
(
"utf-8"
)
,
room
=
self
.
room
)
self
.
ws
.
emit
(
"data"
,
{
'data'
:
data
.
decode
(
"utf-8"
),
'room'
:
self
.
connection
}
,
room
=
self
.
room
)
def
auto_forward
(
self
):
def
auto_forward
(
self
):
thread
=
threading
.
Thread
(
target
=
self
.
forward
,
args
=
())
thread
=
threading
.
Thread
(
target
=
self
.
forward
,
args
=
())
...
@@ -225,4 +226,3 @@ class WSProxy:
...
@@ -225,4 +226,3 @@ class WSProxy:
def
close
(
self
):
def
close
(
self
):
self
.
stop_event
.
set
()
self
.
stop_event
.
set
()
self
.
child
.
close
()
self
.
child
.
close
()
self
.
ws
.
on_disconnect
()
coco/proxy.py
View file @
08b15983
...
@@ -7,12 +7,13 @@ import threading
...
@@ -7,12 +7,13 @@ import threading
import
logging
import
logging
import
time
import
time
import
weakref
import
weakref
import
paramiko
import
paramiko
from
paramiko.ssh_exception
import
SSHException
from
.session
import
Session
from
.session
import
Session
from
.models
import
Server
from
.models
import
Server
from
.utils
import
wrap_with_line_feed
as
wr
,
wrap_with_warning
as
warning
from
.utils
import
wrap_with_line_feed
as
wr
,
wrap_with_warning
as
warning
,
\
get_private_key_fingerprint
logger
=
logging
.
getLogger
(
__file__
)
logger
=
logging
.
getLogger
(
__file__
)
...
@@ -69,7 +70,6 @@ class ProxyServer:
...
@@ -69,7 +70,6 @@ class ProxyServer:
def
get_server_conn
(
self
,
asset
,
system_user
):
def
get_server_conn
(
self
,
asset
,
system_user
):
logger
.
info
(
"Connect to {}"
.
format
(
asset
.
hostname
))
logger
.
info
(
"Connect to {}"
.
format
(
asset
.
hostname
))
if
not
self
.
validate_permission
(
asset
,
system_user
):
if
not
self
.
validate_permission
(
asset
,
system_user
):
# self.client.send(warning(_('No permission')))
self
.
client
.
send
(
warning
(
'No permission'
))
self
.
client
.
send
(
warning
(
'No permission'
))
return
None
return
None
self
.
get_system_user_auth
(
system_user
)
self
.
get_system_user_auth
(
system_user
)
...
@@ -93,16 +93,22 @@ class ProxyServer:
...
@@ -93,16 +93,22 @@ class ProxyServer:
timeout
=
TIMEOUT
,
compress
=
True
,
auth_timeout
=
10
,
timeout
=
TIMEOUT
,
compress
=
True
,
auth_timeout
=
10
,
look_for_keys
=
False
look_for_keys
=
False
)
)
except
paramiko
.
AuthenticationException
:
except
(
paramiko
.
AuthenticationException
,
paramiko
.
BadAuthenticationType
)
:
admins
=
self
.
app
.
config
[
'ADMINS'
]
or
'administrator'
admins
=
self
.
app
.
config
[
'ADMINS'
]
or
'administrator'
self
.
client
.
send
(
warning
(
wr
(
self
.
client
.
send
(
warning
(
wr
(
"Authenticate with server failed, contact {}"
.
format
(
admins
),
"Authenticate with server failed, contact {}"
.
format
(
admins
),
before
=
1
,
after
=
0
before
=
1
,
after
=
0
)))
)))
key_fingerprint
=
system_user
.
private_key
.
get_hex
()
if
system_user
.
private_key
else
None
password_short
=
"None"
key_fingerprint
=
"None"
if
system_user
.
password
:
password_short
=
system_user
.
password
[:
5
]
+
(
len
(
system_user
.
password
)
-
5
)
*
'*'
if
system_user
.
private_key
:
key_fingerprint
=
get_private_key_fingerprint
(
system_user
.
private_key
)
logger
.
error
(
"Connect {}@{}:{} auth failed, password: {}, key: {}"
.
format
(
logger
.
error
(
"Connect {}@{}:{} auth failed, password: {}, key: {}"
.
format
(
system_user
.
username
,
asset
.
ip
,
asset
.
port
,
system_user
.
username
,
asset
.
ip
,
asset
.
port
,
system_user
.
password
,
key_fingerprint
,
password_short
,
key_fingerprint
,
))
))
return
None
return
None
except
socket
.
error
as
e
:
except
socket
.
error
as
e
:
...
@@ -124,7 +130,10 @@ class ProxyServer:
...
@@ -124,7 +130,10 @@ class ProxyServer:
width
=
self
.
request
.
meta
.
get
(
'width'
,
80
)
width
=
self
.
request
.
meta
.
get
(
'width'
,
80
)
height
=
self
.
request
.
meta
.
get
(
'height'
,
24
)
height
=
self
.
request
.
meta
.
get
(
'height'
,
24
)
logger
.
debug
(
"Change win size:
%
s -
%
s"
%
(
width
,
height
))
logger
.
debug
(
"Change win size:
%
s -
%
s"
%
(
width
,
height
))
self
.
server
.
chan
.
resize_pty
(
width
=
width
,
height
=
height
)
try
:
self
.
server
.
chan
.
resize_pty
(
width
=
width
,
height
=
height
)
except
SSHException
:
break
def
watch_win_size_change_async
(
self
):
def
watch_win_size_change_async
(
self
):
thread
=
threading
.
Thread
(
target
=
self
.
watch_win_size_change
)
thread
=
threading
.
Thread
(
target
=
self
.
watch_win_size_change
)
...
...
coco/sshd.py
View file @
08b15983
...
@@ -9,6 +9,8 @@ import threading
...
@@ -9,6 +9,8 @@ import threading
import
paramiko
import
paramiko
import
sys
import
sys
import
time
from
.utils
import
ssh_key_gen
from
.utils
import
ssh_key_gen
from
.interface
import
SSHInterface
from
.interface
import
SSHInterface
from
.interactive
import
InteractiveServer
from
.interactive
import
InteractiveServer
...
@@ -48,13 +50,13 @@ class SSHServer:
...
@@ -48,13 +50,13 @@ class SSHServer:
try
:
try
:
sock
,
addr
=
self
.
sock
.
accept
()
sock
,
addr
=
self
.
sock
.
accept
()
logger
.
info
(
"Get ssh request from {}: {}"
.
format
(
addr
[
0
],
addr
[
1
]))
logger
.
info
(
"Get ssh request from {}: {}"
.
format
(
addr
[
0
],
addr
[
1
]))
thread
=
threading
.
Thread
(
target
=
self
.
handle
,
args
=
(
sock
,
addr
))
thread
=
threading
.
Thread
(
target
=
self
.
handle
_connection
,
args
=
(
sock
,
addr
))
thread
.
daemon
=
True
thread
.
daemon
=
True
thread
.
start
()
thread
.
start
()
except
Exception
as
e
:
except
Exception
as
e
:
logger
.
error
(
"Start SSH server error: {}"
.
format
(
e
))
logger
.
error
(
"Start SSH server error: {}"
.
format
(
e
))
def
handle
(
self
,
sock
,
addr
):
def
handle
_connection
(
self
,
sock
,
addr
):
transport
=
paramiko
.
Transport
(
sock
,
gss_kex
=
False
)
transport
=
paramiko
.
Transport
(
sock
,
gss_kex
=
False
)
try
:
try
:
transport
.
load_server_moduli
()
transport
.
load_server_moduli
()
...
@@ -73,17 +75,23 @@ class SSHServer:
...
@@ -73,17 +75,23 @@ class SSHServer:
logger
.
warning
(
"Handle EOF Error"
)
logger
.
warning
(
"Handle EOF Error"
)
return
return
chan
=
transport
.
accept
(
10
)
while
True
:
if
chan
is
None
:
chan
=
transport
.
accept
()
logger
.
warning
(
"No ssh channel get"
)
if
chan
is
None
:
return
continue
server
.
event
.
wait
(
5
)
if
not
server
.
event
.
is_set
():
logger
.
warning
(
"Client not request a valid request, exiting"
)
return
server
.
event
.
wait
(
5
)
t
=
threading
.
Thread
(
target
=
self
.
handle_chan
,
args
=
(
chan
,
request
))
if
not
server
.
event
.
is_set
():
t
.
daemon
=
True
logger
.
warning
(
"Client not request a valid request, exiting"
)
t
.
start
()
return
def
handle_chan
(
self
,
chan
,
request
):
client
=
Client
(
chan
,
request
)
client
=
Client
(
chan
,
request
)
print
(
chan
)
print
(
request
)
self
.
app
.
add_client
(
client
)
self
.
app
.
add_client
(
client
)
self
.
dispatch
(
client
)
self
.
dispatch
(
client
)
...
...
coco/utils.py
View file @
08b15983
...
@@ -14,6 +14,7 @@ import time
...
@@ -14,6 +14,7 @@ import time
import
datetime
import
datetime
import
gettext
import
gettext
from
io
import
StringIO
from
io
import
StringIO
from
binascii
import
hexlify
import
paramiko
import
paramiko
import
pyte
import
pyte
...
@@ -26,16 +27,15 @@ from .exception import NoAppException
...
@@ -26,16 +27,15 @@ from .exception import NoAppException
BASE_DIR
=
os
.
path
.
abspath
(
os
.
path
.
dirname
(
os
.
path
.
dirname
(
__file__
)))
BASE_DIR
=
os
.
path
.
abspath
(
os
.
path
.
dirname
(
os
.
path
.
dirname
(
__file__
)))
def
ssh_key_string_to_obj
(
text
):
def
ssh_key_string_to_obj
(
text
,
password
=
None
):
key_f
=
StringIO
(
text
)
key
=
None
key
=
None
try
:
try
:
key
=
paramiko
.
RSAKey
.
from_private_key
(
key_f
)
key
=
paramiko
.
RSAKey
.
from_private_key
(
StringIO
(
text
),
password
=
password
)
except
paramiko
.
SSHException
:
except
paramiko
.
SSHException
:
pass
pass
try
:
try
:
key
=
paramiko
.
DSSKey
.
from_private_key
(
key_f
)
key
=
paramiko
.
DSSKey
.
from_private_key
(
StringIO
(
text
),
password
=
password
)
except
paramiko
.
SSHException
:
except
paramiko
.
SSHException
:
pass
pass
return
key
return
key
...
@@ -357,6 +357,11 @@ def _gettext():
...
@@ -357,6 +357,11 @@ def _gettext():
return
gettext
.
gettext
return
gettext
.
gettext
def
get_private_key_fingerprint
(
key
):
line
=
hexlify
(
key
.
get_fingerprint
())
return
b
':'
.
join
([
line
[
i
:
i
+
2
]
for
i
in
range
(
0
,
len
(
line
),
2
)])
def
make_message
():
def
make_message
():
os
.
makedirs
(
os
.
path
.
join
(
BASE_DIR
,
"locale"
,
"zh_CN"
))
os
.
makedirs
(
os
.
path
.
join
(
BASE_DIR
,
"locale"
,
"zh_CN"
))
pass
pass
...
...
logo.txt
View file @
08b15983
___
|_ |
| |_ _ _ __ ___ _ __ ___ ___ _ ____ _____ _ __
| | | | | '_ ` _ \| '_ \/ __|/ _ \ '__\ \ / / _ \ '__|
/\__/ / |_| | | | | | | |_) \__ \ __/ | \ V / __/ |
\____/ \__,_|_| |_| |_| .__/|___/\___|_| \_/ \___|_|
| |
|_|
requirements/requirements.txt
View file @
08b15983
...
@@ -28,4 +28,4 @@ tornado==4.5.2
...
@@ -28,4 +28,4 @@ tornado==4.5.2
urllib3==1.22
urllib3==1.22
wcwidth==0.1.7
wcwidth==0.1.7
werkzeug==0.12.2
werkzeug==0.12.2
jumpserver-python-sdk==0.0.2
2
jumpserver-python-sdk==0.0.2
3
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