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
b9d9db0e
Unverified
Commit
b9d9db0e
authored
Apr 06, 2018
by
老广
Committed by
GitHub
Apr 06, 2018
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #44 from jumpserver/dev
Dev
parents
59ef8545
b9394717
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
446 additions
and
91 deletions
+446
-91
connection.py
coco/connection.py
+126
-0
httpd.py
coco/httpd.py
+22
-1
interface.py
coco/interface.py
+1
-1
proxy.py
coco/proxy.py
+9
-86
sftp.py
coco/sftp.py
+278
-0
sshd.py
coco/sshd.py
+7
-0
requirements.txt
requirements/requirements.txt
+1
-1
rpm_requirements.txt
requirements/rpm_requirements.txt
+2
-2
No files found.
coco/connection.py
0 → 100644
View file @
b9d9db0e
# -*- coding: utf-8 -*-
#
import
weakref
import
os
import
socket
import
paramiko
from
paramiko.ssh_exception
import
SSHException
from
.utils
import
get_logger
,
get_private_key_fingerprint
logger
=
get_logger
(
__file__
)
TIMEOUT
=
10
class
SSHConnection
:
def
__init__
(
self
,
app
):
self
.
_app
=
weakref
.
ref
(
app
)
@property
def
app
(
self
):
return
self
.
_app
()
def
get_ssh_client
(
self
,
asset
,
system_user
):
ssh
=
paramiko
.
SSHClient
()
ssh
.
set_missing_host_key_policy
(
paramiko
.
AutoAddPolicy
())
sock
=
None
self
.
get_system_user_auth
(
system_user
)
if
asset
.
domain
:
sock
=
self
.
get_proxy_sock
(
asset
)
try
:
ssh
.
connect
(
asset
.
ip
,
port
=
asset
.
port
,
username
=
system_user
.
username
,
password
=
system_user
.
password
,
pkey
=
system_user
.
private_key
,
timeout
=
TIMEOUT
,
compress
=
True
,
auth_timeout
=
TIMEOUT
,
look_for_keys
=
False
,
sock
=
sock
)
except
(
paramiko
.
AuthenticationException
,
paramiko
.
BadAuthenticationType
,
SSHException
)
as
e
:
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
(
system_user
.
username
,
asset
.
ip
,
asset
.
port
,
password_short
,
key_fingerprint
,
))
return
None
,
str
(
e
)
except
(
socket
.
error
,
TimeoutError
)
as
e
:
return
None
,
str
(
e
)
return
ssh
,
None
def
get_transport
(
self
,
asset
,
system_user
):
ssh
,
msg
=
self
.
get_ssh_client
(
asset
,
system_user
)
if
ssh
:
return
ssh
.
get_transport
(),
None
else
:
return
None
,
msg
def
get_channel
(
self
,
asset
,
system_user
,
term
=
"xterm"
,
width
=
80
,
height
=
24
):
ssh
,
msg
=
self
.
get_ssh_client
(
asset
,
system_user
)
if
ssh
:
chan
=
ssh
.
invoke_shell
(
term
,
width
=
width
,
height
=
height
)
return
chan
,
None
else
:
return
None
,
msg
def
get_sftp
(
self
,
asset
,
system_user
):
ssh
,
msg
=
self
.
get_ssh_client
(
asset
,
system_user
)
if
ssh
:
return
ssh
.
open_sftp
(),
None
else
:
return
None
,
msg
def
get_system_user_auth
(
self
,
system_user
):
"""
获取系统用户的认证信息,密码或秘钥
: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_proxy_sock
(
self
,
asset
):
sock
=
None
domain
=
self
.
app
.
service
.
get_domain_detail_with_gateway
(
asset
.
domain
)
if
not
domain
.
has_ssh_gateway
():
return
None
for
i
in
domain
.
gateways
:
gateway
=
domain
.
random_ssh_gateway
()
proxy_command
=
[
"ssh"
,
"-o"
,
"StrictHostKeyChecking=no"
,
"-p"
,
str
(
gateway
.
port
),
"{}@{}"
.
format
(
gateway
.
username
,
gateway
.
ip
),
"-W"
,
"{}:{}"
.
format
(
asset
.
ip
,
asset
.
port
),
"-q"
,
]
if
gateway
.
password
:
proxy_command
.
insert
(
0
,
"sshpass -p {}"
.
format
(
gateway
.
password
))
if
gateway
.
private_key
:
gateway
.
set_key_dir
(
os
.
path
.
join
(
self
.
app
.
root_path
,
'keys'
))
proxy_command
.
append
(
"-i {}"
.
format
(
gateway
.
private_key_file
))
proxy_command
=
' '
.
join
(
proxy_command
)
try
:
sock
=
paramiko
.
ProxyCommand
(
proxy_command
)
break
except
(
paramiko
.
AuthenticationException
,
paramiko
.
BadAuthenticationType
,
SSHException
,
TimeoutError
)
as
e
:
logger
.
error
(
e
)
continue
return
sock
coco/httpd.py
View file @
b9d9db0e
...
@@ -159,15 +159,36 @@ class ProxyNamespace(BaseNamespace):
...
@@ -159,15 +159,36 @@ class ProxyNamespace(BaseNamespace):
def
on_token
(
self
,
message
):
def
on_token
(
self
,
message
):
# 此处获取token含有的主机的信息
# 此处获取token含有的主机的信息
logger
.
debug
(
"On token trigger"
)
logger
.
debug
(
"On token trigger"
)
logger
.
debug
(
message
)
token
=
message
.
get
(
'token'
,
None
)
token
=
message
.
get
(
'token'
,
None
)
secret
=
message
.
get
(
'secret'
,
None
)
secret
=
message
.
get
(
'secret'
,
None
)
host
=
self
.
app
.
service
.
get_token_asset
(
token
)
.
json
()
connection
=
str
(
uuid
.
uuid4
())
self
.
emit
(
'room'
,
{
'room'
:
connection
,
'secret'
:
secret
})
if
not
(
token
or
secret
):
logger
.
debug
(
"token or secret is None"
)
self
.
emit
(
'data'
,
{
'data'
:
"
\n
Operation not permitted!"
,
'room'
:
connection
})
self
.
emit
(
'disconnect'
)
return
None
host
=
self
.
app
.
service
.
get_token_asset
(
token
)
logger
.
debug
(
host
)
logger
.
debug
(
host
)
if
not
host
:
logger
.
debug
(
"host is None"
)
self
.
emit
(
'data'
,
{
'data'
:
"
\n
Operation not permitted!"
,
'room'
:
connection
})
self
.
emit
(
'disconnect'
)
return
None
user_id
=
host
.
get
(
'user'
,
None
)
logger
.
debug
(
"self.current_user"
)
self
.
current_user
=
self
.
app
.
service
.
get_user_profile
(
user_id
)
logger
.
debug
(
self
.
current_user
)
# {
# {
# "user": {UUID},
# "user": {UUID},
# "asset": {UUID},
# "asset": {UUID},
# "system_user": {UUID}
# "system_user": {UUID}
# }
# }
self
.
on_host
({
'secret'
:
secret
,
'uuid'
:
host
[
'asset'
],
'userid'
:
host
[
'system_user'
]})
self
.
on_host
({
'secret'
:
secret
,
'uuid'
:
host
[
'asset'
],
'userid'
:
host
[
'system_user'
]})
def
on_resize
(
self
,
message
):
def
on_resize
(
self
,
message
):
...
...
coco/interface.py
View file @
b9d9db0e
...
@@ -147,7 +147,7 @@ class SSHInterface(paramiko.ServerInterface):
...
@@ -147,7 +147,7 @@ class SSHInterface(paramiko.ServerInterface):
self
.
request
.
type
.
append
(
'subsystem'
)
self
.
request
.
type
.
append
(
'subsystem'
)
self
.
request
.
meta
.
update
({
'channel'
:
channel
.
get_id
(),
'name'
:
name
})
self
.
request
.
meta
.
update
({
'channel'
:
channel
.
get_id
(),
'name'
:
name
})
self
.
event
.
set
()
self
.
event
.
set
()
return
False
return
super
()
.
check_channel_subsystem_request
(
channel
,
name
)
def
check_channel_window_change_request
(
self
,
channel
,
width
,
height
,
def
check_channel_window_change_request
(
self
,
channel
,
width
,
height
,
pixelwidth
,
pixelheight
):
pixelwidth
,
pixelheight
):
...
...
coco/proxy.py
View file @
b9d9db0e
...
@@ -2,19 +2,17 @@
...
@@ -2,19 +2,17 @@
# -*- coding: utf-8 -*-
# -*- coding: utf-8 -*-
#
#
import
socket
import
threading
import
threading
import
time
import
time
import
weakref
import
weakref
import
os
import
paramiko
from
paramiko.ssh_exception
import
SSHException
from
paramiko.ssh_exception
import
SSHException
from
.session
import
Session
from
.session
import
Session
from
.models
import
Server
from
.models
import
Server
from
.connection
import
SSHConnection
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
,
get_logger
get_logger
logger
=
get_logger
(
__file__
)
logger
=
get_logger
(
__file__
)
...
@@ -62,20 +60,11 @@ class ProxyServer:
...
@@ -62,20 +60,11 @@ class ProxyServer:
self
.
client
.
user
.
id
,
asset
.
id
,
system_user
.
id
self
.
client
.
user
.
id
,
asset
.
id
,
system_user
.
id
)
)
def
get_system_user_auth
(
self
,
system_user
):
"""
获取系统用户的认证信息,密码或秘钥
: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
):
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'
))
return
None
return
None
self
.
get_system_user_auth
(
system_user
)
if
True
:
if
True
:
server
=
self
.
get_ssh_server_conn
(
asset
,
system_user
)
server
=
self
.
get_ssh_server_conn
(
asset
,
system_user
)
else
:
else
:
...
@@ -86,84 +75,18 @@ class ProxyServer:
...
@@ -86,84 +75,18 @@ class ProxyServer:
def
get_telnet_server_conn
(
self
,
asset
,
system_user
):
def
get_telnet_server_conn
(
self
,
asset
,
system_user
):
pass
pass
def
get_proxy_sock
(
self
,
asset
):
sock
=
None
domain
=
self
.
app
.
service
.
get_domain_detail_with_gateway
(
asset
.
domain
)
if
not
domain
.
has_ssh_gateway
():
return
None
for
i
in
domain
.
gateways
:
gateway
=
domain
.
random_ssh_gateway
()
proxy_command
=
[
"ssh"
,
"-p"
,
str
(
gateway
.
port
),
"{}@{}"
.
format
(
gateway
.
username
,
gateway
.
ip
),
"-W"
,
"{}:{}"
.
format
(
asset
.
ip
,
asset
.
port
),
"-q"
,
]
if
gateway
.
password
:
proxy_command
.
insert
(
0
,
"sshpass -p {}"
.
format
(
gateway
.
password
))
if
gateway
.
private_key
:
gateway
.
set_key_dir
(
os
.
path
.
join
(
self
.
app
.
root_path
,
'keys'
))
proxy_command
.
append
(
"-i {}"
.
format
(
gateway
.
private_key_file
))
proxy_command
=
' '
.
join
(
proxy_command
)
try
:
sock
=
paramiko
.
ProxyCommand
(
proxy_command
)
break
except
(
paramiko
.
AuthenticationException
,
paramiko
.
BadAuthenticationType
,
SSHException
,
TimeoutError
)
as
e
:
logger
.
error
(
e
)
continue
return
sock
def
get_ssh_server_conn
(
self
,
asset
,
system_user
):
def
get_ssh_server_conn
(
self
,
asset
,
system_user
):
ssh
=
paramiko
.
SSHClient
()
ssh
=
SSHConnection
(
self
.
app
)
ssh
.
set_missing_host_key_policy
(
paramiko
.
AutoAddPolicy
())
sock
=
None
if
asset
.
domain
:
sock
=
self
.
get_proxy_sock
(
asset
)
try
:
ssh
.
connect
(
asset
.
ip
,
port
=
asset
.
port
,
username
=
system_user
.
username
,
password
=
system_user
.
password
,
pkey
=
system_user
.
private_key
,
timeout
=
TIMEOUT
,
compress
=
True
,
auth_timeout
=
TIMEOUT
,
look_for_keys
=
False
,
sock
=
sock
)
except
(
paramiko
.
AuthenticationException
,
paramiko
.
BadAuthenticationType
,
SSHException
):
admins
=
self
.
app
.
config
[
'ADMINS'
]
or
'administrator'
self
.
client
.
send
(
warning
(
wr
(
"Authenticate with server failed, contact {}"
.
format
(
admins
),
before
=
1
,
after
=
0
)))
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
(
system_user
.
username
,
asset
.
ip
,
asset
.
port
,
password_short
,
key_fingerprint
,
))
return
None
except
(
socket
.
error
,
TimeoutError
)
as
e
:
self
.
client
.
send
(
wr
(
" {}"
.
format
(
e
)))
return
None
finally
:
self
.
connecting
=
False
self
.
client
.
send
(
b
'
\r\n
'
)
request
=
self
.
client
.
request
request
=
self
.
client
.
request
term
=
request
.
meta
.
get
(
'term'
,
'xterm'
)
term
=
request
.
meta
.
get
(
'term'
,
'xterm'
)
width
=
request
.
meta
.
get
(
'width'
,
80
)
width
=
request
.
meta
.
get
(
'width'
,
80
)
height
=
request
.
meta
.
get
(
'height'
,
24
)
height
=
request
.
meta
.
get
(
'height'
,
24
)
chan
=
ssh
.
invoke_shell
(
term
,
width
=
width
,
height
=
height
)
chan
,
msg
=
ssh
.
get_channel
(
asset
,
system_user
,
term
=
term
,
width
=
width
,
height
=
height
)
if
not
chan
:
self
.
client
.
send
(
warning
(
wr
(
msg
,
before
=
1
,
after
=
0
)))
self
.
connecting
=
False
self
.
client
.
send
(
b
'
\r\n
'
)
return
Server
(
chan
,
asset
,
system_user
)
return
Server
(
chan
,
asset
,
system_user
)
def
watch_win_size_change
(
self
):
def
watch_win_size_change
(
self
):
...
...
coco/sftp.py
0 → 100644
View file @
b9d9db0e
import
os
import
tempfile
import
paramiko
import
time
from
datetime
import
datetime
from
.connection
import
SSHConnection
class
SFTPServer
(
paramiko
.
SFTPServerInterface
):
root
=
'/tmp'
def
__init__
(
self
,
server
,
**
kwargs
):
super
()
.
__init__
(
server
,
**
kwargs
)
self
.
server
=
server
self
.
_sftp
=
{}
self
.
hosts
=
self
.
get_perm_hosts
()
def
get_host_sftp
(
self
,
host
,
su
):
asset
=
self
.
hosts
.
get
(
host
)
system_user
=
None
for
s
in
self
.
get_asset_system_users
(
host
):
if
s
.
name
==
su
:
system_user
=
s
break
if
not
asset
or
not
system_user
:
raise
OSError
(
"No asset or system user explicit"
)
if
host
not
in
self
.
_sftp
:
ssh
=
SSHConnection
(
self
.
server
.
app
)
sftp
,
msg
=
ssh
.
get_sftp
(
asset
,
system_user
)
if
sftp
:
self
.
_sftp
[
host
]
=
sftp
return
sftp
else
:
raise
OSError
(
"Can not connect asset sftp server"
)
else
:
return
self
.
_sftp
[
host
]
def
get_perm_hosts
(
self
):
assets
=
self
.
server
.
app
.
service
.
get_user_assets
(
self
.
server
.
request
.
user
)
return
{
asset
.
hostname
:
asset
for
asset
in
assets
}
def
parse_path
(
self
,
path
):
data
=
path
.
lstrip
(
'/'
)
.
split
(
'/'
)
su
=
rpath
=
''
if
len
(
data
)
==
1
:
host
=
data
[
0
]
elif
len
(
data
)
==
2
:
host
,
su
=
data
rpath
=
self
.
root
else
:
host
,
su
,
*
rpath
=
data
rpath
=
os
.
path
.
join
(
self
.
root
,
'/'
.
join
(
rpath
))
return
host
,
su
,
rpath
def
get_sftp_rpath
(
self
,
path
):
host
,
su
,
rpath
=
self
.
parse_path
(
path
)
sftp
=
self
.
get_host_sftp
(
host
,
su
)
if
host
and
su
else
None
return
sftp
,
rpath
def
get_asset_system_users
(
self
,
host
):
asset
=
self
.
hosts
.
get
(
host
)
if
not
asset
:
return
[]
return
[
su
for
su
in
asset
.
system_users_granted
if
su
.
protocol
==
"ssh"
]
def
su_in_asset
(
self
,
su
,
host
):
system_users
=
self
.
get_asset_system_users
(
host
)
if
su
in
[
s
.
name
for
s
in
system_users
]:
return
True
else
:
return
False
def
create_ftp_log
(
self
,
path
,
operate
,
is_success
=
True
,
filename
=
None
):
host
,
su
,
rpath
=
self
.
parse_path
(
path
)
date_start
=
datetime
.
utcnow
()
.
strftime
(
"
%
Y-
%
m-
%
d
%
H:
%
M:
%
S"
)
+
" +0000"
,
data
=
{
"user"
:
self
.
server
.
request
.
user
.
username
,
"asset"
:
host
,
"system_user"
:
su
,
"remote_addr"
:
self
.
server
.
request
.
addr
[
0
],
"operate"
:
operate
,
"filename"
:
filename
or
rpath
,
"date_start"
:
date_start
,
"is_success"
:
is_success
,
}
for
i
in
range
(
1
,
4
):
ok
=
self
.
server
.
app
.
service
.
create_ftp_log
(
data
)
if
ok
:
break
else
:
time
.
sleep
(
0.5
)
continue
@staticmethod
def
stat_host_dir
():
tmp
=
tempfile
.
TemporaryDirectory
()
attr
=
paramiko
.
SFTPAttributes
.
from_stat
(
os
.
stat
(
tmp
.
name
))
tmp
.
cleanup
()
return
attr
def
list_folder
(
self
,
path
):
output
=
[]
host
,
su
,
rpath
=
self
.
parse_path
(
path
)
if
not
host
:
for
hostname
in
self
.
hosts
:
attr
=
self
.
stat_host_dir
()
attr
.
filename
=
hostname
output
.
append
(
attr
)
elif
not
su
:
for
su
in
self
.
get_asset_system_users
(
host
):
attr
=
self
.
stat_host_dir
()
attr
.
filename
=
su
.
name
output
.
append
(
attr
)
else
:
sftp
,
rpath
=
self
.
get_sftp_rpath
(
path
)
file_list
=
sftp
.
listdir
(
rpath
)
for
filename
in
file_list
:
attr
=
sftp
.
stat
(
os
.
path
.
join
(
rpath
,
filename
))
attr
.
filename
=
filename
output
.
append
(
attr
)
return
output
def
stat
(
self
,
path
):
host
,
su
,
rpath
=
self
.
parse_path
(
path
)
e
=
OSError
(
"Not that dir"
)
if
host
and
host
not
in
self
.
hosts
:
return
paramiko
.
SFTPServer
.
convert_errno
(
e
.
errno
)
if
su
and
not
self
.
su_in_asset
(
su
,
host
):
return
paramiko
.
SFTPServer
.
convert_errno
(
e
.
errno
)
if
not
rpath
or
rpath
==
"/"
:
attr
=
self
.
stat_host_dir
()
attr
.
filename
=
su
or
host
return
attr
else
:
sftp
=
self
.
get_host_sftp
(
host
,
su
)
return
sftp
.
stat
(
rpath
)
def
lstat
(
self
,
path
):
host
,
su
,
rpath
=
self
.
parse_path
(
path
)
if
not
rpath
or
rpath
==
"/"
:
attr
=
self
.
stat_host_dir
()
attr
.
filename
=
su
or
host
else
:
sftp
=
self
.
get_host_sftp
(
host
,
su
)
attr
=
sftp
.
stat
(
rpath
)
attr
.
filename
=
os
.
path
.
basename
(
path
)
return
attr
def
open
(
self
,
path
,
flags
,
attr
):
binary_flag
=
getattr
(
os
,
'O_BINARY'
,
0
)
flags
|=
binary_flag
success
=
False
if
flags
&
os
.
O_WRONLY
:
if
flags
&
os
.
O_APPEND
:
mode
=
'ab'
else
:
mode
=
'wb'
elif
flags
&
os
.
O_RDWR
:
if
flags
&
os
.
O_APPEND
:
mode
=
'a+b'
else
:
mode
=
'r+b'
else
:
mode
=
'rb'
sftp
,
rpath
=
self
.
get_sftp_rpath
(
path
)
if
'r'
in
mode
:
operate
=
"Download"
else
:
operate
=
"Upload"
result
=
None
if
sftp
is
not
None
:
try
:
f
=
sftp
.
open
(
rpath
,
mode
,
bufsize
=
4096
)
obj
=
paramiko
.
SFTPHandle
(
flags
)
obj
.
filename
=
rpath
obj
.
readfile
=
f
obj
.
writefile
=
f
result
=
obj
success
=
True
except
OSError
:
pass
self
.
create_ftp_log
(
path
,
operate
,
success
)
return
result
def
remove
(
self
,
path
):
sftp
,
rpath
=
self
.
get_sftp_rpath
(
path
)
success
=
False
if
sftp
is
not
None
:
try
:
sftp
.
remove
(
rpath
)
except
OSError
as
e
:
result
=
paramiko
.
SFTPServer
.
convert_errno
(
e
.
errno
)
else
:
result
=
paramiko
.
SFTP_OK
success
=
True
else
:
result
=
paramiko
.
SFTP_FAILURE
self
.
create_ftp_log
(
path
,
"Delete"
,
success
)
return
result
def
rename
(
self
,
src
,
dest
):
host1
,
su1
,
rsrc
=
self
.
parse_path
(
src
)
host2
,
su2
,
rdest
=
self
.
parse_path
(
dest
)
success
=
False
if
host1
==
host2
and
su1
==
su2
and
host1
:
sftp
=
self
.
get_host_sftp
(
host1
,
su1
)
try
:
sftp
.
rename
(
rsrc
,
rdest
)
success
=
True
except
OSError
as
e
:
result
=
paramiko
.
SFTPServer
.
convert_errno
(
e
.
errno
)
else
:
result
=
paramiko
.
SFTP_OK
else
:
result
=
paramiko
.
SFTP_FAILURE
filename
=
"{}=>{}"
.
format
(
rsrc
,
rdest
)
self
.
create_ftp_log
(
rsrc
,
"Rename"
,
success
,
filename
=
filename
)
return
result
def
mkdir
(
self
,
path
,
attr
):
sftp
,
rpath
=
self
.
get_sftp_rpath
(
path
)
success
=
False
if
sftp
is
not
None
and
rpath
!=
'/'
:
try
:
sftp
.
mkdir
(
rpath
)
success
=
True
except
OSError
as
e
:
result
=
paramiko
.
SFTPServer
.
convert_errno
(
e
.
errno
)
else
:
result
=
paramiko
.
SFTP_OK
else
:
result
=
paramiko
.
SFTP_FAILURE
self
.
create_ftp_log
(
path
,
"Mkdir"
,
success
)
return
result
def
rmdir
(
self
,
path
):
sftp
,
rpath
=
self
.
get_sftp_rpath
(
path
)
success
=
False
if
sftp
is
not
None
:
try
:
sftp
.
rmdir
(
rpath
)
success
=
True
except
OSError
as
e
:
result
=
paramiko
.
SFTPServer
.
convert_errno
(
e
.
errno
)
else
:
result
=
paramiko
.
SFTP_OK
else
:
result
=
paramiko
.
SFTP_FAILURE
self
.
create_ftp_log
(
path
,
"Rmdir"
,
success
)
return
result
# def chattr(self, path, attr):
# sftp, rpath = self.get_sftp_rpath(path)
# if sftp is not None:
# if attr._flags & attr.FLAG_PERMISSIONS:
# sftp.chmod(rpath, attr.st_mode)
# if attr._flags & attr.FLAG_UIDGID:
# sftp.chown(rpath, attr.st_uid, attr.st_gid)
# if attr._flags & attr.FLAG_AMTIME:
# sftp.utime(rpath, (attr.st_atime, attr.st_mtime))
# if attr._flags & attr.FLAG_SIZE:
# sftp.truncate(rpath, attr.st_size)
# return paramiko.SFTP_OK
coco/sshd.py
View file @
b9d9db0e
...
@@ -11,6 +11,7 @@ from .utils import ssh_key_gen, get_logger
...
@@ -11,6 +11,7 @@ from .utils import ssh_key_gen, get_logger
from
.interface
import
SSHInterface
from
.interface
import
SSHInterface
from
.interactive
import
InteractiveServer
from
.interactive
import
InteractiveServer
from
.models
import
Client
,
Request
from
.models
import
Client
,
Request
from
.sftp
import
SFTPServer
logger
=
get_logger
(
__file__
)
logger
=
get_logger
(
__file__
)
BACKLOG
=
5
BACKLOG
=
5
...
@@ -60,6 +61,9 @@ class SSHServer:
...
@@ -60,6 +61,9 @@ class SSHServer:
logger
.
warning
(
"Failed load moduli -- gex will be unsupported"
)
logger
.
warning
(
"Failed load moduli -- gex will be unsupported"
)
transport
.
add_server_key
(
self
.
host_key
)
transport
.
add_server_key
(
self
.
host_key
)
transport
.
set_subsystem_handler
(
'sftp'
,
paramiko
.
SFTPServer
,
SFTPServer
)
request
=
Request
(
addr
)
request
=
Request
(
addr
)
server
=
SSHInterface
(
self
.
app
,
request
)
server
=
SSHInterface
(
self
.
app
,
request
)
try
:
try
:
...
@@ -100,7 +104,10 @@ class SSHServer:
...
@@ -100,7 +104,10 @@ class SSHServer:
if
'pty'
in
request_type
:
if
'pty'
in
request_type
:
logger
.
info
(
"Request type `pty`, dispatch to interactive mode"
)
logger
.
info
(
"Request type `pty`, dispatch to interactive mode"
)
InteractiveServer
(
self
.
app
,
client
)
.
interact
()
InteractiveServer
(
self
.
app
,
client
)
.
interact
()
elif
'subsystem'
in
request_type
:
pass
else
:
else
:
logger
.
info
(
"Request type `{}`"
.
format
(
request_type
))
client
.
send
(
"Not support request type:
%
s"
%
request_type
)
client
.
send
(
"Not support request type:
%
s"
%
request_type
)
def
shutdown
(
self
):
def
shutdown
(
self
):
...
...
requirements/requirements.txt
View file @
b9d9db0e
...
@@ -20,7 +20,7 @@ Jinja2==2.10
...
@@ -20,7 +20,7 @@ Jinja2==2.10
jmespath==0.9.3
jmespath==0.9.3
jms-es-sdk==0.5.2
jms-es-sdk==0.5.2
jms-storage==0.0.12
jms-storage==0.0.12
jumpserver-python-sdk==0.0.3
5
jumpserver-python-sdk==0.0.3
9
MarkupSafe==1.0
MarkupSafe==1.0
oss2==2.4.0
oss2==2.4.0
paramiko==2.4.0
paramiko==2.4.0
...
...
requirements/rpm_requirements.txt
View file @
b9d9db0e
libffi-devel
libffi-devel sshpass
\ No newline at end of file
\ No newline at end of file
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