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
2486cc83
Commit
2486cc83
authored
Apr 04, 2018
by
ibuler
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[Feature] 支持sftp
parent
67ff6b5c
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
216 additions
and
237 deletions
+216
-237
connection.py
coco/connection.py
+126
-0
interface.py
coco/interface.py
+1
-1
proxy.py
coco/proxy.py
+9
-87
sftp.py
coco/sftp.py
+70
-149
sshd.py
coco/sshd.py
+10
-0
No files found.
coco/connection.py
0 → 100644
View file @
2486cc83
# -*- 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/interface.py
View file @
2486cc83
...
@@ -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 @
2486cc83
...
@@ -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,85 +75,18 @@ class ProxyServer:
...
@@ -86,85 +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"
,
"-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
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
View file @
2486cc83
# Copyright (C) 2003-2009 Robey Pointer <robeypointer@gmail.com>
#
# This file is part of paramiko.
#
# Paramiko is free software; you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free
# Software Foundation; either version 2.1 of the License, or (at your option)
# any later version.
#
# Paramiko is distrubuted in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with Paramiko; if not, write to the Free Software Foundation, Inc.,
# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
"""
A stub SFTP server for loopback SFTP testing.
"""
import
os
import
os
import
tempfile
import
tempfile
import
time
import
socket
import
argparse
import
sys
import
textwrap
import
paramiko
import
paramiko
paramiko
.
util
.
log_to_file
(
'/tmp/ftpserver.log'
,
'DEBUG'
)
from
.connection
import
SSHConnection
class
StubServer
(
paramiko
.
ServerInterface
):
def
check_auth_password
(
self
,
username
,
password
):
# all are allowed
return
paramiko
.
AUTH_SUCCESSFUL
def
check_auth_publickey
(
self
,
username
,
key
):
# all are allowed
return
paramiko
.
AUTH_SUCCESSFUL
def
check_channel_request
(
self
,
kind
,
chanid
):
class
SFTPServer
(
paramiko
.
SFTPServerInterface
):
return
paramiko
.
OPEN_SUCCEEDED
root
=
'/tmp'
def
get_allowed_auths
(
self
,
username
):
"""List availble auth mechanisms."""
return
"password,publickey"
def
__init__
(
self
,
server
,
**
kwargs
):
super
()
.
__init__
(
server
,
**
kwargs
)
self
.
server
=
server
self
.
_sftp
=
{}
self
.
hosts
=
self
.
get_perm_hosts
()
class
StubSFTPServer
(
paramiko
.
SFTPServerInterface
):
def
get_host_sftp
(
self
,
host
,
su
):
hosts
=
None
asset
=
self
.
hosts
.
get
(
host
)
system_user
=
None
for
system_user
in
self
.
get_asset_system_users
(
host
):
if
system_user
.
name
==
su
:
break
def
__init__
(
self
,
*
args
,
**
kwargs
):
if
not
asset
or
not
system_user
:
super
()
.
__init__
(
*
args
,
**
kwargs
)
raise
OSError
(
"No asset or system user explicit"
)
self
.
get_perm_hosts
()
self
.
_sftp
=
{}
def
get_host_sftp
(
self
,
host
):
if
host
not
in
self
.
_sftp
:
if
host
not
in
self
.
_sftp
:
t
=
paramiko
.
Transport
((
'192.168.244.176'
,
22
))
ssh
=
SSHConnection
(
self
.
server
.
app
)
t
.
connect
(
username
=
'root'
,
password
=
'redhat123'
)
sftp
,
msg
=
ssh
.
get_sftp
(
asset
,
system_user
)
sftp
=
paramiko
.
SFTPClient
.
from_transport
(
t
)
if
sftp
:
self
.
_sftp
[
host
]
=
sftp
self
.
_sftp
[
host
]
=
sftp
return
sftp
return
sftp
else
:
raise
OSError
(
"Can not connect asset sftp server"
)
else
:
else
:
return
self
.
_sftp
[
host
]
return
self
.
_sftp
[
host
]
def
get_perm_hosts
(
self
):
def
get_perm_hosts
(
self
):
self
.
hosts
=
[
'centos'
,
'localhost'
]
assets
=
self
.
server
.
app
.
service
.
get_user_assets
(
self
.
server
.
request
.
user
@staticmethod
)
def
parse_path
(
path
):
return
{
asset
.
hostname
:
asset
for
asset
in
assets
}
host
,
*
rpath
=
path
.
lstrip
(
'/'
)
.
split
(
'/'
)
rpath
=
'/'
+
'/'
.
join
(
rpath
)
def
parse_path
(
self
,
path
):
return
host
,
rpath
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
):
def
get_sftp_rpath
(
self
,
path
):
host
,
rpath
=
self
.
parse_path
(
path
)
host
,
su
,
rpath
=
self
.
parse_path
(
path
)
sftp
=
self
.
get_host_sftp
(
host
)
if
host
else
None
sftp
=
self
.
get_host_sftp
(
host
,
su
)
if
host
and
su
else
None
return
sftp
,
rpath
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"
]
@staticmethod
@staticmethod
def
stat_host_dir
():
def
stat_host_dir
():
tmp
=
tempfile
.
TemporaryDirectory
()
tmp
=
tempfile
.
TemporaryDirectory
()
...
@@ -90,10 +74,16 @@ class StubSFTPServer(paramiko.SFTPServerInterface):
...
@@ -90,10 +74,16 @@ class StubSFTPServer(paramiko.SFTPServerInterface):
def
list_folder
(
self
,
path
):
def
list_folder
(
self
,
path
):
output
=
[]
output
=
[]
if
path
==
"/"
:
host
,
su
,
rpath
=
self
.
parse_path
(
path
)
for
filename
in
self
.
hosts
:
if
not
host
:
for
hostname
in
self
.
hosts
:
attr
=
self
.
stat_host_dir
()
attr
=
self
.
stat_host_dir
()
attr
.
filename
=
filename
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
)
output
.
append
(
attr
)
else
:
else
:
sftp
,
rpath
=
self
.
get_sftp_rpath
(
path
)
sftp
,
rpath
=
self
.
get_sftp_rpath
(
path
)
...
@@ -105,23 +95,23 @@ class StubSFTPServer(paramiko.SFTPServerInterface):
...
@@ -105,23 +95,23 @@ class StubSFTPServer(paramiko.SFTPServerInterface):
return
output
return
output
def
stat
(
self
,
path
):
def
stat
(
self
,
path
):
host
,
rpath
=
self
.
parse_path
(
path
)
host
,
su
,
rpath
=
self
.
parse_path
(
path
)
if
host
and
not
rpath
:
if
not
rpath
or
rpath
==
"/"
:
attr
=
self
.
stat_host_dir
()
attr
=
self
.
stat_host_dir
()
attr
.
filename
=
host
attr
.
filename
=
su
or
host
return
attr
return
attr
else
:
else
:
sftp
=
self
.
get_host_sftp
(
host
)
sftp
=
self
.
get_host_sftp
(
host
,
su
)
return
sftp
.
stat
(
rpath
)
return
sftp
.
stat
(
rpath
)
def
lstat
(
self
,
path
):
def
lstat
(
self
,
path
):
host
,
rpath
=
self
.
parse_path
(
path
)
host
,
su
,
rpath
=
self
.
parse_path
(
path
)
if
host
==
''
:
if
not
rpath
or
rpath
==
"/"
:
attr
=
self
.
stat_host_dir
()
attr
=
self
.
stat_host_dir
()
attr
.
filename
=
host
attr
.
filename
=
su
or
host
else
:
else
:
sftp
=
self
.
get_host_sftp
(
host
)
sftp
=
self
.
get_host_sftp
(
host
,
su
)
attr
=
sftp
.
stat
(
rpath
)
attr
=
sftp
.
stat
(
rpath
)
attr
.
filename
=
os
.
path
.
basename
(
path
)
attr
.
filename
=
os
.
path
.
basename
(
path
)
return
attr
return
attr
...
@@ -165,11 +155,11 @@ class StubSFTPServer(paramiko.SFTPServerInterface):
...
@@ -165,11 +155,11 @@ class StubSFTPServer(paramiko.SFTPServerInterface):
return
paramiko
.
SFTP_FAILURE
return
paramiko
.
SFTP_FAILURE
def
rename
(
self
,
src
,
dest
):
def
rename
(
self
,
src
,
dest
):
host1
,
rsrc
=
self
.
parse_path
(
src
)
host1
,
su1
,
rsrc
=
self
.
parse_path
(
src
)
host2
,
rdest
=
self
.
parse_path
(
dest
)
host2
,
su2
,
rdest
=
self
.
parse_path
(
dest
)
if
host1
==
host2
and
host1
:
if
host1
==
host2
and
su1
==
su2
and
host1
:
sftp
=
self
.
get_host_sftp
(
host
2
)
sftp
=
self
.
get_host_sftp
(
host
1
,
su1
)
try
:
try
:
sftp
.
rename
(
rsrc
,
rdest
)
sftp
.
rename
(
rsrc
,
rdest
)
except
OSError
as
e
:
except
OSError
as
e
:
...
@@ -179,7 +169,7 @@ class StubSFTPServer(paramiko.SFTPServerInterface):
...
@@ -179,7 +169,7 @@ class StubSFTPServer(paramiko.SFTPServerInterface):
def
mkdir
(
self
,
path
,
attr
):
def
mkdir
(
self
,
path
,
attr
):
sftp
,
rpath
=
self
.
get_sftp_rpath
(
path
)
sftp
,
rpath
=
self
.
get_sftp_rpath
(
path
)
if
sftp
is
not
None
:
if
sftp
is
not
None
and
rpath
!=
'/'
:
try
:
try
:
sftp
.
mkdir
(
rpath
)
sftp
.
mkdir
(
rpath
)
except
OSError
as
e
:
except
OSError
as
e
:
...
@@ -188,7 +178,6 @@ class StubSFTPServer(paramiko.SFTPServerInterface):
...
@@ -188,7 +178,6 @@ class StubSFTPServer(paramiko.SFTPServerInterface):
return
paramiko
.
SFTP_FAILURE
return
paramiko
.
SFTP_FAILURE
def
rmdir
(
self
,
path
):
def
rmdir
(
self
,
path
):
print
(
"Call {}"
.
format
(
"Rmdir"
))
sftp
,
rpath
=
self
.
get_sftp_rpath
(
path
)
sftp
,
rpath
=
self
.
get_sftp_rpath
(
path
)
if
sftp
is
not
None
:
if
sftp
is
not
None
:
try
:
try
:
...
@@ -198,7 +187,6 @@ class StubSFTPServer(paramiko.SFTPServerInterface):
...
@@ -198,7 +187,6 @@ class StubSFTPServer(paramiko.SFTPServerInterface):
return
paramiko
.
SFTP_OK
return
paramiko
.
SFTP_OK
def
chattr
(
self
,
path
,
attr
):
def
chattr
(
self
,
path
,
attr
):
print
(
"Call {}"
.
format
(
"Chattr"
))
sftp
,
rpath
=
self
.
get_sftp_rpath
(
path
)
sftp
,
rpath
=
self
.
get_sftp_rpath
(
path
)
if
sftp
is
not
None
:
if
sftp
is
not
None
:
if
attr
.
_flags
&
attr
.
FLAG_PERMISSIONS
:
if
attr
.
_flags
&
attr
.
FLAG_PERMISSIONS
:
...
@@ -210,69 +198,3 @@ class StubSFTPServer(paramiko.SFTPServerInterface):
...
@@ -210,69 +198,3 @@ class StubSFTPServer(paramiko.SFTPServerInterface):
if
attr
.
_flags
&
attr
.
FLAG_SIZE
:
if
attr
.
_flags
&
attr
.
FLAG_SIZE
:
sftp
.
truncate
(
rpath
,
attr
.
st_size
)
sftp
.
truncate
(
rpath
,
attr
.
st_size
)
return
paramiko
.
SFTP_OK
return
paramiko
.
SFTP_OK
HOST
,
PORT
=
'localhost'
,
3373
BACKLOG
=
10
def
start_server
(
host
,
port
,
keyfile
,
level
):
paramiko_level
=
getattr
(
paramiko
.
common
,
level
)
paramiko
.
common
.
logging
.
basicConfig
(
level
=
paramiko_level
)
server_socket
=
socket
.
socket
(
socket
.
AF_INET
,
socket
.
SOCK_STREAM
)
server_socket
.
setsockopt
(
socket
.
SOL_SOCKET
,
socket
.
SO_REUSEADDR
,
True
)
server_socket
.
bind
((
host
,
port
))
server_socket
.
listen
(
BACKLOG
)
while
True
:
conn
,
addr
=
server_socket
.
accept
()
host_key
=
paramiko
.
RSAKey
.
from_private_key_file
(
keyfile
)
transport
=
paramiko
.
Transport
(
conn
)
transport
.
add_server_key
(
host_key
)
transport
.
set_subsystem_handler
(
'sftp'
,
paramiko
.
SFTPServer
,
StubSFTPServer
)
server
=
StubServer
()
transport
.
start_server
(
server
=
server
)
channel
=
transport
.
accept
()
while
transport
.
is_active
():
time
.
sleep
(
1
)
def
main
():
usage
=
"""
\
usage: sftpserver [options]
-k/--keyfile should be specified
"""
parser
=
argparse
.
ArgumentParser
(
usage
=
textwrap
.
dedent
(
usage
))
parser
.
add_argument
(
'--host'
,
dest
=
'host'
,
default
=
HOST
,
help
=
'listen on HOST [default:
%(default)
s]'
)
parser
.
add_argument
(
'-p'
,
'--port'
,
dest
=
'port'
,
type
=
int
,
default
=
PORT
,
help
=
'listen on PORT [default:
%(default)
d]'
)
parser
.
add_argument
(
'-l'
,
'--level'
,
dest
=
'level'
,
default
=
'INFO'
,
help
=
'Debug level: WARNING, INFO, DEBUG [default:
%(default)
s]'
)
parser
.
add_argument
(
'-k'
,
'--keyfile'
,
dest
=
'keyfile'
,
metavar
=
'FILE'
,
help
=
'Path to private key, for example /tmp/test_rsa.key'
)
args
=
parser
.
parse_args
()
if
args
.
keyfile
is
None
:
parser
.
print_help
()
sys
.
exit
(
-
1
)
start_server
(
args
.
host
,
args
.
port
,
args
.
keyfile
,
args
.
level
)
if
__name__
==
'__main__'
:
main
()
\ No newline at end of file
coco/sshd.py
View file @
2486cc83
...
@@ -6,15 +6,19 @@ import os
...
@@ -6,15 +6,19 @@ import os
import
socket
import
socket
import
threading
import
threading
import
paramiko
import
paramiko
import
time
from
.utils
import
ssh_key_gen
,
get_logger
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
paramiko
.
util
.
log_to_file
(
'/tmp/ftpserver.log'
,
'DEBUG'
)
class
SSHServer
:
class
SSHServer
:
...
@@ -60,6 +64,9 @@ class SSHServer:
...
@@ -60,6 +64,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
:
...
@@ -101,6 +108,9 @@ class SSHServer:
...
@@ -101,6 +108,9 @@ class SSHServer:
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
()
else
:
else
:
logger
.
info
(
"Request type `{}`"
.
format
(
request_type
))
print
(
request_type
)
time
.
sleep
(
100
)
client
.
send
(
"Not support request type:
%
s"
%
request_type
)
client
.
send
(
"Not support request type:
%
s"
%
request_type
)
def
shutdown
(
self
):
def
shutdown
(
self
):
...
...
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