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
9d650ca0
Commit
9d650ca0
authored
Oct 21, 2017
by
ibuler
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
完成session共享测试
parent
bbf38e4c
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
139 additions
and
65 deletions
+139
-65
app.py
coco/app.py
+15
-10
exception.py
coco/exception.py
+5
-0
forward.py
coco/forward.py
+42
-15
interactive.py
coco/interactive.py
+15
-8
logging.py
coco/logging.py
+4
-1
models.py
coco/models.py
+5
-1
session.py
coco/session.py
+44
-29
sshd.py
coco/sshd.py
+2
-0
manage.py
manage.py
+7
-1
No files found.
coco/app.py
View file @
9d650ca0
...
@@ -2,6 +2,7 @@ import os
...
@@ -2,6 +2,7 @@ import os
import
time
import
time
import
threading
import
threading
from
queue
import
Queue
from
queue
import
Queue
import
logging
from
.config
import
Config
from
.config
import
Config
from
.sshd
import
SSHServer
from
.sshd
import
SSHServer
...
@@ -11,6 +12,7 @@ from .logging import create_logger
...
@@ -11,6 +12,7 @@ from .logging import create_logger
__version__
=
'0.4.0'
__version__
=
'0.4.0'
BASE_DIR
=
os
.
path
.
dirname
(
os
.
path
.
dirname
(
__file__
))
BASE_DIR
=
os
.
path
.
dirname
(
os
.
path
.
dirname
(
__file__
))
logger
=
logging
.
getLogger
(
__file__
)
class
Coco
:
class
Coco
:
...
@@ -95,24 +97,27 @@ class Coco:
...
@@ -95,24 +97,27 @@ class Coco:
pass
pass
def
shutdown
(
self
):
def
shutdown
(
self
):
print
(
"Grace shutdown the server"
)
for
client
in
self
.
clients
:
self
.
remove_client
(
client
)
time
.
sleep
(
1
)
self
.
sshd
.
shutdown
()
self
.
sshd
.
shutdown
()
logger
.
info
(
"Grace shutdown the server"
)
def
add_client
(
self
,
client
):
def
add_client
(
self
,
client
):
with
self
.
lock
:
with
self
.
lock
:
self
.
clients
.
append
(
client
)
self
.
clients
.
append
(
client
)
print
(
"
%
s add client, now
%
d s"
%
(
self
.
name
,
len
(
self
.
clients
)))
logger
.
info
(
"New client
%
s join, total
%
d now"
%
(
client
,
len
(
self
.
clients
)))
def
remove_client
(
self
,
client
):
def
remove_client
(
self
,
client
):
with
self
.
lock
:
with
self
.
lock
:
self
.
clients
.
remove
(
client
)
try
:
print
(
"
%
s remove client, now
%
d s"
%
(
self
.
name
,
len
(
self
.
clients
))
)
self
.
clients
.
remove
(
client
)
logger
.
info
(
"Client
%
s leave, total
%
d now"
%
(
client
,
len
(
self
.
clients
)))
try
:
client
.
send
(
"Closed by server"
)
client
.
send
(
"Closed by server"
)
client
.
close
()
client
.
close
()
except
:
except
:
pass
pass
def
monitor_session
(
self
):
def
monitor_session
(
self
):
pass
pass
...
...
coco/exception.py
0 → 100644
View file @
9d650ca0
# coding: utf-8
class
PermissionFailed
(
Exception
):
pass
coco/forward.py
View file @
9d650ca0
...
@@ -3,21 +3,37 @@
...
@@ -3,21 +3,37 @@
import
socket
import
socket
import
paramiko
import
paramiko
import
time
from
.session
import
Session
from
.session
import
Session
from
.models
import
Server
from
.exception
import
PermissionFailed
class
ProxyServer
:
class
ProxyServer
:
def
__init__
(
self
,
app
,
request
,
clien
t
):
def
__init__
(
self
,
app
,
client
,
reques
t
):
self
.
app
=
app
self
.
app
=
app
self
.
request
=
request
self
.
request
=
request
self
.
client
=
client
self
.
client
=
client
self
.
server
=
None
self
.
server
=
None
def
proxy
(
self
,
asset
,
system_user
):
def
proxy
(
self
,
asset
,
system_user
):
self
.
server
=
self
.
get_server_conn
(
asset
,
system_user
)
try
:
session
=
Session
(
self
.
client
,
self
.
server
)
self
.
server
=
self
.
get_server_conn
(
asset
,
system_user
)
session
.
bridge
()
except
PermissionFailed
:
self
.
client
.
send
(
"No permission"
)
return
if
len
(
self
.
app
.
sessions
)
==
1
:
session
=
self
.
app
.
sessions
[
0
]
session
.
add_sharer
(
self
.
client
)
while
True
:
time
.
sleep
(
10
)
else
:
session
=
Session
(
self
.
client
,
self
.
server
)
self
.
app
.
sessions
.
append
(
session
)
session
.
bridge
()
self
.
app
.
sessions
.
remove
(
session
)
def
validate_permission
(
self
,
asset
,
system_user
):
def
validate_permission
(
self
,
asset
,
system_user
):
"""
"""
...
@@ -25,26 +41,37 @@ class ProxyServer:
...
@@ -25,26 +41,37 @@ class ProxyServer:
system user
system user
:return: True or False
:return: True or False
"""
"""
pass
return
True
def
get_system_user_
info
(
self
,
system_user
):
def
get_system_user_
auth
(
self
,
system_user
):
"""
"""
Get the system user auth ..., using this to connect asset
Get the system user auth ..., using this to connect asset
:return: system user have full info
:return: system user have full info
"""
"""
pass
def
get_server_conn
(
self
,
asset
,
system_user
):
def
get_server_conn
(
self
,
asset
,
system_user
):
self
.
ssh
=
ssh
=
paramiko
.
SSHClient
()
if
not
self
.
validate_permission
(
asset
,
system_user
):
raise
PermissionFailed
self
.
get_system_user_auth
(
system_user
)
ssh
=
paramiko
.
SSHClient
()
ssh
.
set_missing_host_key_policy
(
paramiko
.
AutoAddPolicy
())
ssh
.
set_missing_host_key_policy
(
paramiko
.
AutoAddPolicy
())
try
:
try
:
ssh
.
connect
(
asset
.
ip
,
port
=
asset
.
port
,
username
=
system_user
.
username
,
ssh
.
connect
(
asset
.
ip
,
port
=
asset
.
port
,
password
=
system_user
.
password
,
pkey
=
system_user
.
private_key
)
username
=
system_user
.
username
,
except
(
paramiko
.
AuthenticationException
,
paramiko
.
ssh_exception
.
NoValidConnectionsError
)
as
e
:
password
=
system_user
.
password
,
pass
pkey
=
system_user
.
private_key
)
except
paramiko
.
AuthenticationException
as
e
:
self
.
client
.
send
(
"Authentication failed:
%
s"
%
e
)
return
except
socket
.
error
:
except
socket
.
error
as
e
:
pass
self
.
client
.
send
(
"Connection server error:
%
s"
%
e
)
return
return
term
=
self
.
request
.
meta
.
get
(
'term'
,
'xterm'
)
width
=
self
.
request
.
meta
.
get
(
'width'
,
80
)
height
=
self
.
request
.
meta
.
get
(
'height'
,
24
)
chan
=
ssh
.
invoke_shell
(
term
,
width
=
width
,
height
=
height
)
return
Server
(
chan
,
asset
,
system_user
)
coco/interactive.py
View file @
9d650ca0
...
@@ -79,20 +79,25 @@ class InteractiveServer:
...
@@ -79,20 +79,25 @@ class InteractiveServer:
input_data
.
append
(
data
)
input_data
.
append
(
data
)
def
dispatch
(
self
,
opt
):
def
dispatch
(
self
,
opt
):
if
opt
in
[
'q'
,
'Q'
]:
if
opt
in
[
'q'
,
'Q'
,
'0'
]:
self
.
app
.
remove_client
(
self
.
client
)
self
.
app
.
remove_client
(
self
.
client
)
return
elif
opt
in
[
'h'
,
'H'
,
'9'
]:
self
.
display_banner
()
elif
opt
in
[
'p'
,
'P'
,
'3'
]:
self
.
display_assets
()
elif
opt
in
[
'g'
,
'G'
,
'5'
]:
self
.
display_asset_groups
()
else
:
else
:
self
.
client
.
send
(
"hello"
)
self
.
search_and_proxy
(
opt
)
asset
=
Asset
(
id
=
1
,
hostname
=
"123.57.183.135"
,
ip
=
"123.57.183.135"
,
port
=
8022
)
system_user
=
SystemUser
(
id
=
2
,
username
=
"web"
,
password
=
"redhat123"
,
name
=
"web"
)
self
.
connect
(
asset
,
system_user
)
def
search_assets
(
self
,
opt
,
from_result
=
False
):
def
search_assets
(
self
,
opt
,
from_result
=
False
):
pass
pass
def
display_assets
(
self
):
def
display_assets
(
self
):
"""
Display user all assets
:return:
"""
pass
pass
def
display_asset_groups
(
self
):
def
display_asset_groups
(
self
):
...
@@ -118,7 +123,9 @@ class InteractiveServer:
...
@@ -118,7 +123,9 @@ class InteractiveServer:
pass
pass
def
search_and_proxy
(
self
,
opt
,
from_result
=
False
):
def
search_and_proxy
(
self
,
opt
,
from_result
=
False
):
pass
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
.
connect
(
asset
,
system_user
)
def
connect
(
self
,
asset
,
system_user
):
def
connect
(
self
,
asset
,
system_user
):
forwarder
=
ProxyServer
(
self
.
app
,
self
.
client
,
self
.
request
)
forwarder
=
ProxyServer
(
self
.
app
,
self
.
client
,
self
.
request
)
...
...
coco/logging.py
View file @
9d650ca0
...
@@ -26,8 +26,11 @@ def create_logger(app):
...
@@ -26,8 +26,11 @@ def create_logger(app):
log_path
=
os
.
path
.
join
(
log_dir
,
'coco.log'
)
log_path
=
os
.
path
.
join
(
log_dir
,
'coco.log'
)
logger
=
logging
.
getLogger
()
logger
=
logging
.
getLogger
()
# main_formatter = logging.Formatter(
# fmt='%(asctime)s [%(module)s %(levelname)s] %(message)s',
# datefmt='%Y-%m-%d %H:%M:%S')
main_formatter
=
logging
.
Formatter
(
main_formatter
=
logging
.
Formatter
(
fmt
=
'
%(asctime)
s [
%(
module)
s
%(
levelname)
s]
%(message)
s'
,
fmt
=
'
%(asctime)
s [
%(levelname)
s]
%(message)
s'
,
datefmt
=
'
%
Y-
%
m-
%
d
%
H:
%
M:
%
S'
)
datefmt
=
'
%
Y-
%
m-
%
d
%
H:
%
M:
%
S'
)
console_handler
=
StreamHandler
()
console_handler
=
StreamHandler
()
file_handler
=
TimedRotatingFileHandler
(
file_handler
=
TimedRotatingFileHandler
(
...
...
coco/models.py
View file @
9d650ca0
...
@@ -99,7 +99,7 @@ class Server:
...
@@ -99,7 +99,7 @@ class Server:
self
.
system_user
=
system_user
self
.
system_user
=
system_user
def
fileno
(
self
):
def
fileno
(
self
):
return
self
.
chan
.
fileno
return
self
.
chan
.
fileno
()
def
send
(
self
,
b
):
def
send
(
self
,
b
):
return
self
.
chan
.
send
(
b
)
return
self
.
chan
.
send
(
b
)
...
@@ -107,6 +107,10 @@ class Server:
...
@@ -107,6 +107,10 @@ class Server:
def
recv
(
self
,
size
):
def
recv
(
self
,
size
):
return
self
.
chan
.
recv
(
size
)
return
self
.
chan
.
recv
(
size
)
def
close
(
self
):
self
.
chan
.
close
()
return
self
.
chan
.
transport
.
close
()
def
__getattr__
(
self
,
item
):
def
__getattr__
(
self
,
item
):
return
getattr
(
self
.
chan
,
item
)
return
getattr
(
self
.
chan
,
item
)
...
...
coco/session.py
View file @
9d650ca0
...
@@ -30,51 +30,63 @@ class Session:
...
@@ -30,51 +30,63 @@ class Session:
:return:
:return:
"""
"""
logger
.
info
(
"Session
%
add watcher
%
s"
%
(
self
,
watcher
))
logger
.
info
(
"Session
%
add watcher
%
s"
%
(
self
,
watcher
))
watcher
.
send
(
"Welcome to join session
%
s
\r\n
"
%
self
.
id
)
self
.
watchers
.
append
(
watcher
)
self
.
watchers
.
append
(
watcher
)
def
remove_watcher
(
self
,
watcher
):
logger
.
info
(
"Session
%
s remove watcher
%
s"
%
(
self
,
watcher
))
watcher
.
send
(
"Leave session
%
s at
%
s"
%
(
self
.
id
,
datetime
.
datetime
.
now
()))
self
.
watchers
.
remove
(
watcher
)
def
add_sharer
(
self
,
sharer
):
def
add_sharer
(
self
,
sharer
):
"""
"""
Add a sharer, it can read and write to server
Add a sharer, it can read and write to server
:param sharer: A client socket
:param sharer: A client socket
:return:
:return:
"""
"""
logger
.
info
(
"Session
%
add share
%
s"
%
(
self
,
sharer
))
logger
.
info
(
"Session
%
s add share
%
s"
%
(
self
.
id
,
sharer
))
sharer
.
send
(
"Welcome to join session
%
s
\r\n
"
%
self
.
id
)
self
.
sharers
.
append
(
sharer
)
self
.
sharers
.
append
(
sharer
)
def
remove_sharer
(
self
,
sharer
):
logger
.
info
(
"Session
%
s remove sharer
%
s"
%
(
self
.
id
,
sharer
))
sharer
.
send
(
"Leave session
%
s at
%
s"
%
(
self
.
id
,
datetime
.
datetime
.
now
()))
self
.
sharers
.
remove
(
sharer
)
def
bridge
(
self
):
def
bridge
(
self
):
"""
"""
Bridge clients with server
Bridge clients with server
:return:
:return:
"""
"""
logger
.
info
(
"Start bridge session
%
s"
%
self
.
id
)
while
self
.
running
:
while
self
.
running
:
try
:
r
,
w
,
x
=
select
.
select
([
self
.
client
,
self
.
server
]
+
r
,
w
,
x
=
select
.
select
([
self
.
client
+
self
.
server
]
self
.
watchers
+
self
.
sharers
,
[],
[])
+
self
.
sharers
,
[],
[])
for
sock
in
r
:
data
=
sock
.
recv
(
BUF_SIZE
)
for
sock
in
r
:
print
(
data
.
decode
(
'utf-8'
))
if
sock
==
self
.
server
:
if
sock
==
self
.
server
:
data
=
sock
.
recv
(
BUF_SIZE
)
if
len
(
data
)
==
0
:
if
len
(
data
)
==
0
:
self
.
close
()
self
.
close
()
break
for
watcher
in
[
self
.
client
]
+
self
.
watchers
+
self
.
sharers
:
for
watcher
in
[
self
.
client
]
+
self
.
watchers
+
self
.
sharers
:
watcher
.
send
(
data
)
watcher
.
send
(
data
)
elif
sock
==
self
.
client
:
elif
sock
==
self
.
client
:
data
=
sock
.
recv
(
BUF_SIZE
)
if
len
(
data
)
==
0
:
if
len
(
data
)
==
0
:
for
watcher
in
self
.
watchers
+
self
.
sharers
:
for
watcher
in
self
.
watchers
+
self
.
sharers
:
watcher
.
send
(
"Client
%
s close the session"
%
self
.
client
)
watcher
.
send
(
"
%
s close the session"
%
self
.
client
)
self
.
close
(
)
self
.
close
()
break
self
.
server
.
send
(
data
)
self
.
server
.
send
(
data
)
elif
sock
in
self
.
sharers
:
elif
sock
in
self
.
sharers
:
data
=
sock
.
recv
(
BUF_SIZE
)
if
len
(
data
)
==
0
:
if
len
(
data
)
==
0
:
logger
.
info
(
"Sharer
%
s leave session
%
s"
%
(
sock
,
self
.
id
))
sock
.
send
(
"Leave session
%
s"
%
self
.
id
)
self
.
remove_sharer
(
sock
)
self
.
server
.
send
(
data
)
self
.
server
.
send
(
data
)
elif
sock
in
self
.
watchers
:
except
Exception
as
e
:
if
len
(
data
)
==
0
:
pass
logger
.
info
(
"Watcher
%
s leave session
%
s"
%
(
sock
,
self
.
id
))
def
set_size
(
self
,
width
,
height
):
def
set_size
(
self
,
width
,
height
):
self
.
server
.
resize_pty
(
width
=
width
,
height
=
height
)
self
.
server
.
resize_pty
(
width
=
width
,
height
=
height
)
...
@@ -91,10 +103,13 @@ class Session:
...
@@ -91,10 +103,13 @@ class Session:
pass
pass
def
close
(
self
):
def
close
(
self
):
pass
self
.
running
=
False
self
.
server
.
close
()
return
def
__str__
(
self
):
def
__str__
(
self
):
return
self
.
id
return
self
.
id
__repr__
=
__str__
...
...
coco/sshd.py
View file @
9d650ca0
...
@@ -87,6 +87,8 @@ class SSHServer:
...
@@ -87,6 +87,8 @@ class SSHServer:
except
paramiko
.
SSHException
:
except
paramiko
.
SSHException
:
logger
.
warning
(
"SSH negotiation failed."
)
logger
.
warning
(
"SSH negotiation failed."
)
sys
.
exit
(
1
)
sys
.
exit
(
1
)
except
EOFError
:
logger
.
warning
(
"EOF Error"
)
chan
=
transport
.
accept
(
10
)
chan
=
transport
.
accept
(
10
)
if
chan
is
None
:
if
chan
is
None
:
...
...
manage.py
View file @
9d650ca0
...
@@ -2,9 +2,15 @@
...
@@ -2,9 +2,15 @@
#
#
import
os
import
os
import
sys
from
coco
import
Coco
from
coco
import
Coco
import
conf
try
:
import
conf
except
ImportError
:
print
(
"Please prepare config file `cp conf_example.py conf.py`"
)
sys
.
exit
(
1
)
try
:
try
:
os
.
mkdir
(
"logs"
)
os
.
mkdir
(
"logs"
)
...
...
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