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
b273218f
Commit
b273218f
authored
Oct 18, 2017
by
ibuler
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[Feture] ..
parent
daa71f39
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
125 additions
and
25 deletions
+125
-25
app.py
coco/app.py
+8
-8
interactive.py
coco/interactive.py
+1
-1
interface.py
coco/interface.py
+6
-10
sshd.py
coco/sshd.py
+3
-3
utils.py
coco/utils.py
+106
-3
manage.py
manage.py
+1
-0
No files found.
coco/app.py
View file @
b273218f
...
...
@@ -38,30 +38,30 @@ class Coco:
self
.
config
=
self
.
config_class
(
BASE_DIR
,
defaults
=
self
.
default_config
)
self
.
sessions
=
[]
self
.
connections
=
[]
self
.
sshd
=
SSHServer
(
self
)
self
.
ws
=
None
self
.
root_path
=
root_path
self
.
name
=
name
if
name
:
self
.
name
=
name
else
:
if
name
is
None
:
self
.
name
=
self
.
config
[
'NAME'
]
if
root_path
is
None
:
self
.
root_path
=
BASE_DIR
self
.
make_logger
()
self
.
sshd
=
None
def
make_logger
(
self
):
create_logger
(
self
)
@staticmethod
def
bootstrap
():
def
prepare
(
self
):
self
.
sshd
=
SSHServer
(
self
)
pass
def
heartbeat
(
self
):
pass
def
run_forever
(
self
):
self
.
prepare
()
print
(
time
.
ctime
())
print
(
'Coco version
%
s, more see https://www.jumpserver.org'
%
__version__
)
...
...
coco/interactive.py
View file @
b273218f
...
...
@@ -33,7 +33,7 @@ class InteractiveServer:
def
dispatch
(
self
):
pass
def
run
(
self
):
def
active
(
self
):
self
.
display_banner
()
while
True
:
try
:
...
...
coco/interface.py
View file @
b273218f
...
...
@@ -22,13 +22,6 @@ class SSHInterface(paramiko.ServerInterface):
self
.
event
=
threading
.
Event
()
def
check_auth_interactive
(
self
,
username
,
submethods
):
"""
:param username: the username of the authenticating client
:param submethods: a comma-separated list of methods preferred
by the client (usually empty)
:return: AUTH_FAILED if this auth method isn’t supported;
otherwise an object containing queries for the user
"""
logger
.
info
(
"Check auth interactive:
%
s
%
s"
%
(
username
,
submethods
))
return
paramiko
.
AUTH_FAILED
...
...
@@ -56,7 +49,7 @@ class SSHInterface(paramiko.ServerInterface):
def
validate_auth
(
self
,
username
,
password
=
""
,
key
=
""
):
# Todo: Implement it
self
.
request
.
user
=
"guang"
return
True
return
paramiko
.
AUTH_SUCCESSFUL
def
check_channel_direct_tcpip_request
(
self
,
chanid
,
origin
,
destination
):
logger
.
debug
(
"Check channel direct tcpip request:
%
d
%
s
%
s"
%
...
...
@@ -93,12 +86,12 @@ class SSHInterface(paramiko.ServerInterface):
self
,
channel
,
term
,
width
,
height
,
pixelwidth
,
pixelheight
,
modes
):
logger
.
debug
(
"Check channel pty request:
%
s
%
s
%
s
%
s
%
s
%
s"
%
(
channel
,
term
,
width
,
height
,
pixelwidth
,
pixelheight
))
(
channel
,
term
,
width
,
height
,
pixelwidth
,
pixelheight
))
self
.
request
.
type
=
'pty'
self
.
request
.
meta
=
{
'channel'
:
channel
,
'term'
:
term
,
'width'
:
width
,
'height'
:
height
,
'pixelwidth'
:
pixelwidth
,
'pixelheight'
:
pixelheight
,
'models'
:
modes
,
'pixelheight'
:
pixelheight
,
}
self
.
event
.
set
()
return
True
...
...
@@ -109,6 +102,9 @@ class SSHInterface(paramiko.ServerInterface):
def
check_channel_shell_request
(
self
,
channel
):
logger
.
info
(
"Check channel shell request:
%
s"
%
channel
)
self
.
request
.
type
=
'shell'
self
.
request
.
meta
=
{
'channel'
:
channel
}
self
.
event
.
set
()
return
True
def
check_channel_subsystem_request
(
self
,
channel
,
name
):
...
...
coco/sshd.py
View file @
b273218f
...
...
@@ -9,6 +9,7 @@ import sys
from
.utils
import
ssh_key_gen
from
.interface
import
SSHInterface
from
.interactive
import
InteractiveServer
logger
=
logging
.
getLogger
(
__file__
)
BACKLOG
=
5
...
...
@@ -22,7 +23,6 @@ class Request:
self
.
addr
=
addr
self
.
user
=
None
self
.
change_size_event
=
threading
.
Event
()
self
.
win_size
=
{}
class
SSHServer
:
...
...
@@ -54,7 +54,7 @@ class SSHServer:
def
run
(
self
):
self
.
listen
()
max_conn_num
=
self
.
app
[
'MAX_CONNECTIONS'
]
max_conn_num
=
self
.
app
.
config
[
'MAX_CONNECTIONS'
]
while
not
self
.
stop_event
.
is_set
():
try
:
client
,
addr
=
self
.
sock
.
accept
()
...
...
@@ -102,7 +102,7 @@ class SSHServer:
def
dispatch
(
self
,
request
,
channel
):
if
request
.
type
==
'pty'
:
pass
InteractiveServer
(
self
.
app
,
request
,
channel
)
.
active
()
elif
request
.
type
==
'exec'
:
pass
elif
request
.
type
==
'subsystem'
:
...
...
coco/utils.py
View file @
b273218f
#!coding: utf-8
import
base64
import
calendar
import
os
import
re
import
paramiko
from
io
import
StringIO
import
hashlib
import
threading
import
time
import
pyte
def
ssh_key_string_to_obj
(
text
):
...
...
@@ -61,4 +70,99 @@ def ssh_key_gen(length=2048, type='rsa', password=None,
public_key
=
ssh_pubkey_gen
(
private_key_obj
,
username
=
username
,
hostname
=
hostname
)
return
private_key
,
public_key
except
IOError
:
raise
IOError
(
'These is error when generate ssh key.'
)
\ No newline at end of file
raise
IOError
(
'These is error when generate ssh key.'
)
def
content_md5
(
data
):
"""计算data的MD5值,经过Base64编码并返回str类型。
返回值可以直接作为HTTP Content-Type头部的值
"""
if
isinstance
(
data
,
str
):
data
=
hashlib
.
md5
(
data
.
encode
(
'utf-8'
))
return
base64
.
b64encode
(
data
.
digest
())
_STRPTIME_LOCK
=
threading
.
Lock
()
_GMT_FORMAT
=
"
%
a,
%
d
%
b
%
Y
%
H:
%
M:
%
S GMT"
_ISO8601_FORMAT
=
"
%
Y-
%
m-
%
dT
%
H:
%
M:
%
S.000Z"
def
to_unixtime
(
time_string
,
format_string
):
with
_STRPTIME_LOCK
:
return
int
(
calendar
.
timegm
(
time
.
strptime
(
str
(
time_string
),
format_string
)))
def
http_date
(
timeval
=
None
):
"""返回符合HTTP标准的GMT时间字符串,用strftime的格式表示就是"
%
a,
%
d
%
b
%
Y
%
H:
%
M:
%
S GMT"。
但不能使用strftime,因为strftime的结果是和locale相关的。
"""
return
formatdate
(
timeval
,
usegmt
=
True
)
def
http_to_unixtime
(
time_string
):
"""把HTTP Date格式的字符串转换为UNIX时间(自1970年1月1日UTC零点的秒数)。
HTTP Date形如 `Sat, 05 Dec 2015 11:10:29 GMT` 。
"""
return
to_unixtime
(
time_string
,
_GMT_FORMAT
)
def
iso8601_to_unixtime
(
time_string
):
"""把ISO8601时间字符串(形如,2012-02-24T06:07:48.000Z)转换为UNIX时间,精确到秒。"""
return
to_unixtime
(
time_string
,
_ISO8601_FORMAT
)
def
make_signature
(
access_key_secret
,
date
=
None
):
if
isinstance
(
date
,
bytes
):
date
=
date
.
decode
(
"utf-8"
)
if
isinstance
(
date
,
int
):
date_gmt
=
http_date
(
date
)
elif
date
is
None
:
date_gmt
=
http_date
(
int
(
time
.
time
()))
else
:
date_gmt
=
date
data
=
str
(
access_key_secret
)
+
"
\n
"
+
date_gmt
return
content_md5
(
data
)
class
TtyIOParser
(
object
):
def
__init__
(
self
,
width
=
80
,
height
=
24
):
self
.
screen
=
pyte
.
Screen
(
width
,
height
)
self
.
stream
=
pyte
.
ByteStream
()
self
.
stream
.
attach
(
self
.
screen
)
self
.
ps1_pattern
=
re
.
compile
(
r'^\[?.*@.*\]?[\$#]\s|mysql>\s'
)
def
clean_ps1_etc
(
self
,
command
):
return
self
.
ps1_pattern
.
sub
(
''
,
command
)
def
parse_output
(
self
,
data
,
sep
=
'
\n
'
):
output
=
[]
if
not
isinstance
(
data
,
bytes
):
data
=
data
.
encode
(
'utf-8'
,
'ignore'
)
self
.
stream
.
feed
(
data
)
for
line
in
self
.
screen
.
display
:
if
line
.
strip
():
output
.
append
(
line
)
self
.
screen
.
reset
()
return
sep
.
join
(
output
[
0
:
-
1
])
def
parse_input
(
self
,
data
):
command
=
[]
if
not
isinstance
(
data
,
bytes
):
data
=
data
.
encode
(
'utf-8'
,
'ignore'
)
self
.
stream
.
feed
(
data
)
for
line
in
self
.
screen
.
display
:
line
=
line
.
strip
()
if
line
:
command
.
append
(
line
)
if
command
:
command
=
command
[
-
1
]
else
:
command
=
''
self
.
screen
.
reset
()
command
=
self
.
clean_ps1_etc
(
command
)
return
command
mange.py
→
man
a
ge.py
View file @
b273218f
...
...
@@ -16,6 +16,7 @@ except:
coco
=
Coco
()
coco
.
config
.
from_object
(
conf
)
print
(
coco
.
root_path
)
if
__name__
==
'__main__'
:
coco
.
run_forever
()
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