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
7 years ago
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
import
time
import
threading
from
queue
import
Queue
import
logging
from
.config
import
Config
from
.sshd
import
SSHServer
...
...
@@ -11,6 +12,7 @@ from .logging import create_logger
__version__
=
'0.4.0'
BASE_DIR
=
os
.
path
.
dirname
(
os
.
path
.
dirname
(
__file__
))
logger
=
logging
.
getLogger
(
__file__
)
class
Coco
:
...
...
@@ -95,24 +97,27 @@ class Coco:
pass
def
shutdown
(
self
):
print
(
"Grace shutdown the server"
)
for
client
in
self
.
clients
:
self
.
remove_client
(
client
)
time
.
sleep
(
1
)
self
.
sshd
.
shutdown
()
logger
.
info
(
"Grace shutdown the server"
)
def
add_client
(
self
,
client
):
with
self
.
lock
:
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
):
with
self
.
lock
:
self
.
clients
.
remove
(
client
)
print
(
"
%
s remove client, now
%
d s"
%
(
self
.
name
,
len
(
self
.
clients
))
)
try
:
client
.
send
(
"Closed by server"
)
client
.
close
()
except
:
pass
try
:
self
.
clients
.
remove
(
client
)
logger
.
info
(
"Client
%
s leave, total
%
d now"
%
(
client
,
len
(
self
.
clients
)))
client
.
send
(
"Closed by server"
)
client
.
close
()
except
:
pass
def
monitor_session
(
self
):
pass
...
...
This diff is collapsed.
Click to expand it.
coco/exception.py
0 → 100644
View file @
9d650ca0
# coding: utf-8
class
PermissionFailed
(
Exception
):
pass
This diff is collapsed.
Click to expand it.
coco/forward.py
View file @
9d650ca0
...
...
@@ -3,21 +3,37 @@
import
socket
import
paramiko
import
time
from
.session
import
Session
from
.models
import
Server
from
.exception
import
PermissionFailed
class
ProxyServer
:
def
__init__
(
self
,
app
,
request
,
clien
t
):
def
__init__
(
self
,
app
,
client
,
reques
t
):
self
.
app
=
app
self
.
request
=
request
self
.
client
=
client
self
.
server
=
None
def
proxy
(
self
,
asset
,
system_user
):
self
.
server
=
self
.
get_server_conn
(
asset
,
system_user
)
session
=
Session
(
self
.
client
,
self
.
server
)
session
.
bridge
()
try
:
self
.
server
=
self
.
get_server_conn
(
asset
,
system_user
)
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
):
"""
...
...
@@ -25,26 +41,37 @@ class ProxyServer:
system user
: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
:return: system user have full info
"""
pass
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
())
try
:
ssh
.
connect
(
asset
.
ip
,
port
=
asset
.
port
,
username
=
system_user
.
username
,
password
=
system_user
.
password
,
pkey
=
system_user
.
private_key
)
except
(
paramiko
.
AuthenticationException
,
paramiko
.
ssh_exception
.
NoValidConnectionsError
)
as
e
:
pass
ssh
.
connect
(
asset
.
ip
,
port
=
asset
.
port
,
username
=
system_user
.
username
,
password
=
system_user
.
password
,
pkey
=
system_user
.
private_key
)
except
paramiko
.
AuthenticationException
as
e
:
self
.
client
.
send
(
"Authentication failed:
%
s"
%
e
)
return
except
socket
.
error
:
pass
except
socket
.
error
as
e
:
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
)
This diff is collapsed.
Click to expand it.
coco/interactive.py
View file @
9d650ca0
...
...
@@ -79,20 +79,25 @@ class InteractiveServer:
input_data
.
append
(
data
)
def
dispatch
(
self
,
opt
):
if
opt
in
[
'q'
,
'Q'
]:
if
opt
in
[
'q'
,
'Q'
,
'0'
]:
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
:
self
.
client
.
send
(
"hello"
)
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
)
self
.
search_and_proxy
(
opt
)
def
search_assets
(
self
,
opt
,
from_result
=
False
):
pass
def
display_assets
(
self
):
"""
Display user all assets
:return:
"""
pass
def
display_asset_groups
(
self
):
...
...
@@ -118,7 +123,9 @@ class InteractiveServer:
pass
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
):
forwarder
=
ProxyServer
(
self
.
app
,
self
.
client
,
self
.
request
)
...
...
This diff is collapsed.
Click to expand it.
coco/logging.py
View file @
9d650ca0
...
...
@@ -26,8 +26,11 @@ def create_logger(app):
log_path
=
os
.
path
.
join
(
log_dir
,
'coco.log'
)
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
(
fmt
=
'
%(asctime)
s [
%(
module)
s
%(
levelname)
s]
%(message)
s'
,
fmt
=
'
%(asctime)
s [
%(levelname)
s]
%(message)
s'
,
datefmt
=
'
%
Y-
%
m-
%
d
%
H:
%
M:
%
S'
)
console_handler
=
StreamHandler
()
file_handler
=
TimedRotatingFileHandler
(
...
...
This diff is collapsed.
Click to expand it.
coco/models.py
View file @
9d650ca0
...
...
@@ -99,7 +99,7 @@ class Server:
self
.
system_user
=
system_user
def
fileno
(
self
):
return
self
.
chan
.
fileno
return
self
.
chan
.
fileno
()
def
send
(
self
,
b
):
return
self
.
chan
.
send
(
b
)
...
...
@@ -107,6 +107,10 @@ class Server:
def
recv
(
self
,
size
):
return
self
.
chan
.
recv
(
size
)
def
close
(
self
):
self
.
chan
.
close
()
return
self
.
chan
.
transport
.
close
()
def
__getattr__
(
self
,
item
):
return
getattr
(
self
.
chan
,
item
)
...
...
This diff is collapsed.
Click to expand it.
coco/session.py
View file @
9d650ca0
...
...
@@ -30,51 +30,63 @@ class Session:
:return:
"""
logger
.
info
(
"Session
%
add watcher
%
s"
%
(
self
,
watcher
))
watcher
.
send
(
"Welcome to join session
%
s
\r\n
"
%
self
.
id
)
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
):
"""
Add a sharer, it can read and write to server
:param sharer: A client socket
: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
)
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
):
"""
Bridge clients with server
:return:
"""
logger
.
info
(
"Start bridge session
%
s"
%
self
.
id
)
while
self
.
running
:
try
:
r
,
w
,
x
=
select
.
select
([
self
.
client
+
self
.
server
]
+
self
.
sharers
,
[],
[])
for
sock
in
r
:
if
sock
==
self
.
server
:
data
=
sock
.
recv
(
BUF_SIZE
)
if
len
(
data
)
==
0
:
self
.
close
()
for
watcher
in
[
self
.
client
]
+
self
.
watchers
+
self
.
sharers
:
watcher
.
send
(
data
)
elif
sock
==
self
.
client
:
data
=
sock
.
recv
(
BUF_SIZE
)
if
len
(
data
)
==
0
:
for
watcher
in
self
.
watchers
+
self
.
sharers
:
watcher
.
send
(
"
%
s close the session"
%
self
.
client
)
self
.
close
()
self
.
server
.
send
(
data
)
elif
sock
in
self
.
sharers
:
data
=
sock
.
recv
(
BUF_SIZE
)
if
len
(
data
)
==
0
:
sock
.
send
(
"Leave session
%
s"
%
self
.
id
)
self
.
server
.
send
(
data
)
except
Exception
as
e
:
pass
r
,
w
,
x
=
select
.
select
([
self
.
client
,
self
.
server
]
+
self
.
watchers
+
self
.
sharers
,
[],
[])
for
sock
in
r
:
data
=
sock
.
recv
(
BUF_SIZE
)
print
(
data
.
decode
(
'utf-8'
))
if
sock
==
self
.
server
:
if
len
(
data
)
==
0
:
self
.
close
()
break
for
watcher
in
[
self
.
client
]
+
self
.
watchers
+
self
.
sharers
:
watcher
.
send
(
data
)
elif
sock
==
self
.
client
:
if
len
(
data
)
==
0
:
for
watcher
in
self
.
watchers
+
self
.
sharers
:
watcher
.
send
(
"Client
%
s close the session"
%
self
.
client
)
self
.
close
(
)
break
self
.
server
.
send
(
data
)
elif
sock
in
self
.
sharers
:
if
len
(
data
)
==
0
:
logger
.
info
(
"Sharer
%
s leave session
%
s"
%
(
sock
,
self
.
id
))
self
.
remove_sharer
(
sock
)
self
.
server
.
send
(
data
)
elif
sock
in
self
.
watchers
:
if
len
(
data
)
==
0
:
logger
.
info
(
"Watcher
%
s leave session
%
s"
%
(
sock
,
self
.
id
))
def
set_size
(
self
,
width
,
height
):
self
.
server
.
resize_pty
(
width
=
width
,
height
=
height
)
...
...
@@ -91,10 +103,13 @@ class Session:
pass
def
close
(
self
):
pass
self
.
running
=
False
self
.
server
.
close
()
return
def
__str__
(
self
):
return
self
.
id
__repr__
=
__str__
...
...
This diff is collapsed.
Click to expand it.
coco/sshd.py
View file @
9d650ca0
...
...
@@ -87,6 +87,8 @@ class SSHServer:
except
paramiko
.
SSHException
:
logger
.
warning
(
"SSH negotiation failed."
)
sys
.
exit
(
1
)
except
EOFError
:
logger
.
warning
(
"EOF Error"
)
chan
=
transport
.
accept
(
10
)
if
chan
is
None
:
...
...
This diff is collapsed.
Click to expand it.
manage.py
View file @
9d650ca0
...
...
@@ -2,9 +2,15 @@
#
import
os
import
sys
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
:
os
.
mkdir
(
"logs"
)
...
...
This diff is collapsed.
Click to expand it.
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