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:
...
@@ -38,30 +38,30 @@ class Coco:
self
.
config
=
self
.
config_class
(
BASE_DIR
,
defaults
=
self
.
default_config
)
self
.
config
=
self
.
config_class
(
BASE_DIR
,
defaults
=
self
.
default_config
)
self
.
sessions
=
[]
self
.
sessions
=
[]
self
.
connections
=
[]
self
.
connections
=
[]
self
.
sshd
=
SSHServer
(
self
)
self
.
ws
=
None
self
.
ws
=
None
self
.
root_path
=
root_path
self
.
name
=
name
if
name
:
if
name
is
None
:
self
.
name
=
name
else
:
self
.
name
=
self
.
config
[
'NAME'
]
self
.
name
=
self
.
config
[
'NAME'
]
if
root_path
is
None
:
if
root_path
is
None
:
self
.
root_path
=
BASE_DIR
self
.
make_logger
()
self
.
make_logger
()
self
.
sshd
=
None
def
make_logger
(
self
):
def
make_logger
(
self
):
create_logger
(
self
)
create_logger
(
self
)
@staticmethod
def
prepare
(
self
):
def
bootstrap
():
self
.
sshd
=
SSHServer
(
self
)
pass
pass
def
heartbeat
(
self
):
def
heartbeat
(
self
):
pass
pass
def
run_forever
(
self
):
def
run_forever
(
self
):
self
.
prepare
()
print
(
time
.
ctime
())
print
(
time
.
ctime
())
print
(
'Coco version
%
s, more see https://www.jumpserver.org'
%
__version__
)
print
(
'Coco version
%
s, more see https://www.jumpserver.org'
%
__version__
)
...
...
coco/interactive.py
View file @
b273218f
...
@@ -33,7 +33,7 @@ class InteractiveServer:
...
@@ -33,7 +33,7 @@ class InteractiveServer:
def
dispatch
(
self
):
def
dispatch
(
self
):
pass
pass
def
run
(
self
):
def
active
(
self
):
self
.
display_banner
()
self
.
display_banner
()
while
True
:
while
True
:
try
:
try
:
...
...
coco/interface.py
View file @
b273218f
...
@@ -22,13 +22,6 @@ class SSHInterface(paramiko.ServerInterface):
...
@@ -22,13 +22,6 @@ class SSHInterface(paramiko.ServerInterface):
self
.
event
=
threading
.
Event
()
self
.
event
=
threading
.
Event
()
def
check_auth_interactive
(
self
,
username
,
submethods
):
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
))
logger
.
info
(
"Check auth interactive:
%
s
%
s"
%
(
username
,
submethods
))
return
paramiko
.
AUTH_FAILED
return
paramiko
.
AUTH_FAILED
...
@@ -56,7 +49,7 @@ class SSHInterface(paramiko.ServerInterface):
...
@@ -56,7 +49,7 @@ class SSHInterface(paramiko.ServerInterface):
def
validate_auth
(
self
,
username
,
password
=
""
,
key
=
""
):
def
validate_auth
(
self
,
username
,
password
=
""
,
key
=
""
):
# Todo: Implement it
# Todo: Implement it
self
.
request
.
user
=
"guang"
self
.
request
.
user
=
"guang"
return
True
return
paramiko
.
AUTH_SUCCESSFUL
def
check_channel_direct_tcpip_request
(
self
,
chanid
,
origin
,
destination
):
def
check_channel_direct_tcpip_request
(
self
,
chanid
,
origin
,
destination
):
logger
.
debug
(
"Check channel direct tcpip request:
%
d
%
s
%
s"
%
logger
.
debug
(
"Check channel direct tcpip request:
%
d
%
s
%
s"
%
...
@@ -93,12 +86,12 @@ class SSHInterface(paramiko.ServerInterface):
...
@@ -93,12 +86,12 @@ class SSHInterface(paramiko.ServerInterface):
self
,
channel
,
term
,
width
,
height
,
self
,
channel
,
term
,
width
,
height
,
pixelwidth
,
pixelheight
,
modes
):
pixelwidth
,
pixelheight
,
modes
):
logger
.
debug
(
"Check channel pty request:
%
s
%
s
%
s
%
s
%
s
%
s"
%
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
.
type
=
'pty'
self
.
request
.
meta
=
{
self
.
request
.
meta
=
{
'channel'
:
channel
,
'term'
:
term
,
'width'
:
width
,
'channel'
:
channel
,
'term'
:
term
,
'width'
:
width
,
'height'
:
height
,
'pixelwidth'
:
pixelwidth
,
'height'
:
height
,
'pixelwidth'
:
pixelwidth
,
'pixelheight'
:
pixelheight
,
'models'
:
modes
,
'pixelheight'
:
pixelheight
,
}
}
self
.
event
.
set
()
self
.
event
.
set
()
return
True
return
True
...
@@ -109,6 +102,9 @@ class SSHInterface(paramiko.ServerInterface):
...
@@ -109,6 +102,9 @@ class SSHInterface(paramiko.ServerInterface):
def
check_channel_shell_request
(
self
,
channel
):
def
check_channel_shell_request
(
self
,
channel
):
logger
.
info
(
"Check channel shell request:
%
s"
%
channel
)
logger
.
info
(
"Check channel shell request:
%
s"
%
channel
)
self
.
request
.
type
=
'shell'
self
.
request
.
meta
=
{
'channel'
:
channel
}
self
.
event
.
set
()
return
True
return
True
def
check_channel_subsystem_request
(
self
,
channel
,
name
):
def
check_channel_subsystem_request
(
self
,
channel
,
name
):
...
...
coco/sshd.py
View file @
b273218f
...
@@ -9,6 +9,7 @@ import sys
...
@@ -9,6 +9,7 @@ import sys
from
.utils
import
ssh_key_gen
from
.utils
import
ssh_key_gen
from
.interface
import
SSHInterface
from
.interface
import
SSHInterface
from
.interactive
import
InteractiveServer
logger
=
logging
.
getLogger
(
__file__
)
logger
=
logging
.
getLogger
(
__file__
)
BACKLOG
=
5
BACKLOG
=
5
...
@@ -22,7 +23,6 @@ class Request:
...
@@ -22,7 +23,6 @@ class Request:
self
.
addr
=
addr
self
.
addr
=
addr
self
.
user
=
None
self
.
user
=
None
self
.
change_size_event
=
threading
.
Event
()
self
.
change_size_event
=
threading
.
Event
()
self
.
win_size
=
{}
class
SSHServer
:
class
SSHServer
:
...
@@ -54,7 +54,7 @@ class SSHServer:
...
@@ -54,7 +54,7 @@ class SSHServer:
def
run
(
self
):
def
run
(
self
):
self
.
listen
()
self
.
listen
()
max_conn_num
=
self
.
app
[
'MAX_CONNECTIONS'
]
max_conn_num
=
self
.
app
.
config
[
'MAX_CONNECTIONS'
]
while
not
self
.
stop_event
.
is_set
():
while
not
self
.
stop_event
.
is_set
():
try
:
try
:
client
,
addr
=
self
.
sock
.
accept
()
client
,
addr
=
self
.
sock
.
accept
()
...
@@ -102,7 +102,7 @@ class SSHServer:
...
@@ -102,7 +102,7 @@ class SSHServer:
def
dispatch
(
self
,
request
,
channel
):
def
dispatch
(
self
,
request
,
channel
):
if
request
.
type
==
'pty'
:
if
request
.
type
==
'pty'
:
pass
InteractiveServer
(
self
.
app
,
request
,
channel
)
.
active
()
elif
request
.
type
==
'exec'
:
elif
request
.
type
==
'exec'
:
pass
pass
elif
request
.
type
==
'subsystem'
:
elif
request
.
type
==
'subsystem'
:
...
...
coco/utils.py
View file @
b273218f
#!coding: utf-8
#!coding: utf-8
import
base64
import
calendar
import
os
import
os
import
re
import
paramiko
import
paramiko
from
io
import
StringIO
from
io
import
StringIO
import
hashlib
import
threading
import
time
import
pyte
def
ssh_key_string_to_obj
(
text
):
def
ssh_key_string_to_obj
(
text
):
...
@@ -61,4 +70,99 @@ def ssh_key_gen(length=2048, type='rsa', password=None,
...
@@ -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
)
public_key
=
ssh_pubkey_gen
(
private_key_obj
,
username
=
username
,
hostname
=
hostname
)
return
private_key
,
public_key
return
private_key
,
public_key
except
IOError
:
except
IOError
:
raise
IOError
(
'These is error when generate ssh key.'
)
raise
IOError
(
'These is error when generate ssh key.'
)
\ No newline at end of file
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:
...
@@ -16,6 +16,7 @@ except:
coco
=
Coco
()
coco
=
Coco
()
coco
.
config
.
from_object
(
conf
)
coco
.
config
.
from_object
(
conf
)
print
(
coco
.
root_path
)
if
__name__
==
'__main__'
:
if
__name__
==
'__main__'
:
coco
.
run_forever
()
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