Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Z
Zope
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
Zope
Commits
416c8faf
Commit
416c8faf
authored
Jul 21, 1999
by
Ken Manheimer
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added back a print so the client user sees the result of their commands.
Changed all tabs to spaces.
parent
0516b906
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
614 additions
and
612 deletions
+614
-612
ZServer/medusa/monitor.py
ZServer/medusa/monitor.py
+307
-306
lib/python/ZServer/medusa/monitor.py
lib/python/ZServer/medusa/monitor.py
+307
-306
No files found.
ZServer/medusa/monitor.py
View file @
416c8faf
# -*- Mode: Python; tab-width: 4 -*-
#
Author: Sam Rushing <rushing@nightmare.com>
#
Author: Sam Rushing <rushing@nightmare.com>
#
# python REPL channel.
#
RCS_ID
=
'$Id: monitor.py,v 1.
3 1999/07/20 16:53:50 amos
Exp $'
RCS_ID
=
'$Id: monitor.py,v 1.
4 1999/07/21 16:50:57 klm
Exp $'
import
md5
import
socket
...
...
@@ -22,326 +22,327 @@ from counter import counter
import
producers
class
monitor_channel
(
asynchat
.
async_chat
):
try_linemode
=
1
def
__init__
(
self
,
server
,
sock
,
addr
):
asynchat
.
async_chat
.
__init__
(
self
,
sock
)
self
.
server
=
server
self
.
addr
=
addr
self
.
set_terminator
(
'
\
r
\
n
'
)
self
.
data
=
''
# local bindings specific to this channel
self
.
local_env
=
{}
self
.
push
(
'Python '
+
sys
.
version
+
'
\
r
\
n
'
)
self
.
push
(
sys
.
copyright
+
'
\
r
\
n
'
)
self
.
push
(
'Welcome to %s
\
r
\
n
'
%
self
)
self
.
push
(
"[Hint: try 'from __main__ import *']
\
r
\
n
"
)
self
.
prompt
()
self
.
number
=
server
.
total_sessions
.
as_long
()
self
.
line_counter
=
counter
()
self
.
multi_line
=
[]
def
handle_connect
(
self
):
# send IAC DO LINEMODE
self
.
push
(
'
\
377
\
375
\
"
'
)
def
close
(
self
):
self
.
server
.
closed_sessions
.
increment
()
asynchat
.
async_chat
.
close
(
self
)
def
prompt
(
self
):
self
.
push
(
'>>> '
)
def
collect_incoming_data
(
self
,
data
):
self
.
data
=
self
.
data
+
data
if
len
(
self
.
data
)
>
1024
:
# denial of service.
self
.
push
(
'BCNU
\
r
\
n
'
)
self
.
close_when_done
()
def
found_terminator
(
self
):
line
=
self
.
clean_line
(
self
.
data
)
self
.
data
=
''
self
.
line_counter
.
increment
()
# check for special case inputs...
if
not
line
and
not
self
.
multi_line
:
self
.
prompt
()
return
if
line
in
[
'
\
004
'
,
'exit'
]:
self
.
push
(
'BCNU
\
r
\
n
'
)
self
.
close_when_done
()
return
oldout
=
sys
.
stdout
olderr
=
sys
.
stderr
try
:
p
=
output_producer
(
self
,
olderr
)
sys
.
stdout
=
p
sys
.
stderr
=
p
try
:
# this is, of course, a blocking operation.
# if you wanted to thread this, you would have
# to synchronize, etc... and treat the output
# like a pipe. Not Fun.
#
# try eval first. If that fails, try exec. If that fails,
# hurl.
try
:
if
self
.
multi_line
:
# oh, this is horrible...
raise
SyntaxError
co
=
compile
(
line
,
repr
(
self
),
'eval'
)
result
=
eval
(
co
,
self
.
local_env
)
method
=
'eval'
if
result
is
not
None
:
self
.
log_info
(
repr
(
result
))
self
.
local_env
[
'_'
]
=
result
except
SyntaxError
:
try
:
if
self
.
multi_line
:
if
line
and
line
[
0
]
in
[
' '
,
'
\
t
'
]:
self
.
multi_line
.
append
(
line
)
self
.
push
(
'... '
)
return
else
:
self
.
multi_line
.
append
(
line
)
line
=
string
.
join
(
self
.
multi_line
,
'
\
n
'
)
co
=
compile
(
line
,
repr
(
self
),
'exec'
)
self
.
multi_line
=
[]
else
:
co
=
compile
(
line
,
repr
(
self
),
'exec'
)
except
SyntaxError
,
why
:
if
why
[
0
]
==
'unexpected EOF while parsing'
:
self
.
push
(
'... '
)
self
.
multi_line
.
append
(
line
)
return
exec
co
in
self
.
local_env
method
=
'exec'
except
:
method
=
'exception'
self
.
multi_line
=
[]
(
file
,
fun
,
line
),
t
,
v
,
tbinfo
=
asyncore
.
compact_traceback
()
self
.
log_info
(
'%s %s %s'
%
(
t
,
v
,
tbinfo
),
'warning'
)
finally
:
sys
.
stdout
=
oldout
sys
.
stderr
=
olderr
self
.
log_info
(
'%s:%s (%s)> %s'
%
(
self
.
number
,
self
.
line_counter
,
method
,
repr
(
line
))
)
self
.
push_with_producer
(
p
)
self
.
prompt
()
# for now, we ignore any telnet option stuff sent to
# us, and we process the backspace key ourselves.
# gee, it would be fun to write a full-blown line-editing
# environment, etc...
def
clean_line
(
self
,
line
):
chars
=
[]
for
ch
in
line
:
oc
=
ord
(
ch
)
if
oc
<
127
:
if
oc
in
[
8
,
177
]:
# backspace
chars
=
chars
[:
-
1
]
else
:
chars
.
append
(
ch
)
return
string
.
join
(
chars
,
''
)
try_linemode
=
1
def
__init__
(
self
,
server
,
sock
,
addr
):
asynchat
.
async_chat
.
__init__
(
self
,
sock
)
self
.
server
=
server
self
.
addr
=
addr
self
.
set_terminator
(
'
\
r
\
n
'
)
self
.
data
=
''
# local bindings specific to this channel
self
.
local_env
=
{}
self
.
push
(
'Python '
+
sys
.
version
+
'
\
r
\
n
'
)
self
.
push
(
sys
.
copyright
+
'
\
r
\
n
'
)
self
.
push
(
'Welcome to %s
\
r
\
n
'
%
self
)
self
.
push
(
"[Hint: try 'from __main__ import *']
\
r
\
n
"
)
self
.
prompt
()
self
.
number
=
server
.
total_sessions
.
as_long
()
self
.
line_counter
=
counter
()
self
.
multi_line
=
[]
def
handle_connect
(
self
):
# send IAC DO LINEMODE
self
.
push
(
'
\
377
\
375
\
"
'
)
def
close
(
self
):
self
.
server
.
closed_sessions
.
increment
()
asynchat
.
async_chat
.
close
(
self
)
def
prompt
(
self
):
self
.
push
(
'>>> '
)
def
collect_incoming_data
(
self
,
data
):
self
.
data
=
self
.
data
+
data
if
len
(
self
.
data
)
>
1024
:
# denial of service.
self
.
push
(
'BCNU
\
r
\
n
'
)
self
.
close_when_done
()
def
found_terminator
(
self
):
line
=
self
.
clean_line
(
self
.
data
)
self
.
data
=
''
self
.
line_counter
.
increment
()
# check for special case inputs...
if
not
line
and
not
self
.
multi_line
:
self
.
prompt
()
return
if
line
in
[
'
\
004
'
,
'exit'
]:
self
.
push
(
'BCNU
\
r
\
n
'
)
self
.
close_when_done
()
return
oldout
=
sys
.
stdout
olderr
=
sys
.
stderr
try
:
p
=
output_producer
(
self
,
olderr
)
sys
.
stdout
=
p
sys
.
stderr
=
p
try
:
# this is, of course, a blocking operation.
# if you wanted to thread this, you would have
# to synchronize, etc... and treat the output
# like a pipe. Not Fun.
#
# try eval first. If that fails, try exec. If that fails,
# hurl.
try
:
if
self
.
multi_line
:
# oh, this is horrible...
raise
SyntaxError
co
=
compile
(
line
,
repr
(
self
),
'eval'
)
result
=
eval
(
co
,
self
.
local_env
)
method
=
'eval'
if
result
is
not
None
:
self
.
log_info
(
repr
(
result
))
print
repr
(
result
)
self
.
local_env
[
'_'
]
=
result
except
SyntaxError
:
try
:
if
self
.
multi_line
:
if
line
and
line
[
0
]
in
[
' '
,
'
\
t
'
]:
self
.
multi_line
.
append
(
line
)
self
.
push
(
'... '
)
return
else
:
self
.
multi_line
.
append
(
line
)
line
=
string
.
join
(
self
.
multi_line
,
'
\
n
'
)
co
=
compile
(
line
,
repr
(
self
),
'exec'
)
self
.
multi_line
=
[]
else
:
co
=
compile
(
line
,
repr
(
self
),
'exec'
)
except
SyntaxError
,
why
:
if
why
[
0
]
==
'unexpected EOF while parsing'
:
self
.
push
(
'... '
)
self
.
multi_line
.
append
(
line
)
return
exec
co
in
self
.
local_env
method
=
'exec'
except
:
method
=
'exception'
self
.
multi_line
=
[]
(
file
,
fun
,
line
),
t
,
v
,
tbinfo
=
asyncore
.
compact_traceback
()
self
.
log_info
(
'%s %s %s'
%
(
t
,
v
,
tbinfo
),
'warning'
)
finally
:
sys
.
stdout
=
oldout
sys
.
stderr
=
olderr
self
.
log_info
(
'%s:%s (%s)> %s'
%
(
self
.
number
,
self
.
line_counter
,
method
,
repr
(
line
))
)
self
.
push_with_producer
(
p
)
self
.
prompt
()
# for now, we ignore any telnet option stuff sent to
# us, and we process the backspace key ourselves.
# gee, it would be fun to write a full-blown line-editing
# environment, etc...
def
clean_line
(
self
,
line
):
chars
=
[]
for
ch
in
line
:
oc
=
ord
(
ch
)
if
oc
<
127
:
if
oc
in
[
8
,
177
]:
# backspace
chars
=
chars
[:
-
1
]
else
:
chars
.
append
(
ch
)
return
string
.
join
(
chars
,
''
)
class
monitor_server
(
asyncore
.
dispatcher
):
SERVER_IDENT
=
'Monitor Server (V%s)'
%
VERSION
channel_class
=
monitor_channel
def
__init__
(
self
,
hostname
=
'127.0.0.1'
,
port
=
8023
):
self
.
hostname
=
hostname
self
.
port
=
port
self
.
create_socket
(
socket
.
AF_INET
,
socket
.
SOCK_STREAM
)
self
.
set_reuse_addr
()
self
.
bind
((
hostname
,
port
))
self
.
log_info
(
'%s started on port %d'
%
(
self
.
SERVER_IDENT
,
port
))
self
.
listen
(
5
)
self
.
closed
=
0
self
.
failed_auths
=
0
self
.
total_sessions
=
counter
()
self
.
closed_sessions
=
counter
()
def
writable
(
self
):
return
0
def
handle_accept
(
self
):
conn
,
addr
=
self
.
accept
()
self
.
log_info
(
'Incoming monitor connection from %s:%d'
%
addr
)
self
.
channel_class
(
self
,
conn
,
addr
)
self
.
total_sessions
.
increment
()
def
status
(
self
):
return
producers
.
simple_producer
(
'<h2>%s</h2>'
%
self
.
SERVER_IDENT
+
'<br><b>Total Sessions:</b> %s'
%
self
.
total_sessions
+
'<br><b>Current Sessions:</b> %d'
%
(
self
.
total_sessions
.
as_long
()
-
self
.
closed_sessions
.
as_long
()
)
)
SERVER_IDENT
=
'Monitor Server (V%s)'
%
VERSION
channel_class
=
monitor_channel
def
__init__
(
self
,
hostname
=
'127.0.0.1'
,
port
=
8023
):
self
.
hostname
=
hostname
self
.
port
=
port
self
.
create_socket
(
socket
.
AF_INET
,
socket
.
SOCK_STREAM
)
self
.
set_reuse_addr
()
self
.
bind
((
hostname
,
port
))
self
.
log_info
(
'%s started on port %d'
%
(
self
.
SERVER_IDENT
,
port
))
self
.
listen
(
5
)
self
.
closed
=
0
self
.
failed_auths
=
0
self
.
total_sessions
=
counter
()
self
.
closed_sessions
=
counter
()
def
writable
(
self
):
return
0
def
handle_accept
(
self
):
conn
,
addr
=
self
.
accept
()
self
.
log_info
(
'Incoming monitor connection from %s:%d'
%
addr
)
self
.
channel_class
(
self
,
conn
,
addr
)
self
.
total_sessions
.
increment
()
def
status
(
self
):
return
producers
.
simple_producer
(
'<h2>%s</h2>'
%
self
.
SERVER_IDENT
+
'<br><b>Total Sessions:</b> %s'
%
self
.
total_sessions
+
'<br><b>Current Sessions:</b> %d'
%
(
self
.
total_sessions
.
as_long
()
-
self
.
closed_sessions
.
as_long
()
)
)
def
hex_digest
(
s
):
m
=
md5
.
md5
()
m
.
update
(
s
)
return
string
.
joinfields
(
map
(
lambda
x
:
hex
(
ord
(
x
))[
2
:],
map
(
None
,
m
.
digest
())),
''
,
)
m
=
md5
.
md5
()
m
.
update
(
s
)
return
string
.
joinfields
(
map
(
lambda
x
:
hex
(
ord
(
x
))[
2
:],
map
(
None
,
m
.
digest
())),
''
,
)
class
secure_monitor_channel
(
monitor_channel
):
authorized
=
0
def
__init__
(
self
,
server
,
sock
,
addr
):
asynchat
.
async_chat
.
__init__
(
self
,
sock
)
self
.
server
=
server
self
.
addr
=
addr
self
.
set_terminator
(
'
\
r
\
n
'
)
self
.
data
=
''
# local bindings specific to this channel
self
.
local_env
=
{}
# send timestamp string
self
.
timestamp
=
str
(
time
.
time
())
self
.
count
=
0
self
.
line_counter
=
counter
()
self
.
number
=
int
(
server
.
total_sessions
.
as_long
())
self
.
multi_line
=
[]
self
.
push
(
self
.
timestamp
+
'
\
r
\
n
'
)
def
found_terminator
(
self
):
if
not
self
.
authorized
:
if
hex_digest
(
'%s%s'
%
(
self
.
timestamp
,
self
.
server
.
password
))
!=
self
.
data
:
self
.
log_info
(
'%s: failed authorization'
%
self
,
'warning'
)
self
.
server
.
failed_auths
=
self
.
server
.
failed_auths
+
1
self
.
close
()
else
:
self
.
authorized
=
1
self
.
push
(
'Python '
+
sys
.
version
+
'
\
r
\
n
'
)
self
.
push
(
sys
.
copyright
+
'
\
r
\
n
'
)
self
.
push
(
'Welcome to %s
\
r
\
n
'
%
self
)
self
.
push
(
"[Hint: try 'from __main__ import *']
\
r
\
n
"
)
self
.
prompt
()
self
.
data
=
''
else
:
monitor_channel
.
found_terminator
(
self
)
authorized
=
0
def
__init__
(
self
,
server
,
sock
,
addr
):
asynchat
.
async_chat
.
__init__
(
self
,
sock
)
self
.
server
=
server
self
.
addr
=
addr
self
.
set_terminator
(
'
\
r
\
n
'
)
self
.
data
=
''
# local bindings specific to this channel
self
.
local_env
=
{}
# send timestamp string
self
.
timestamp
=
str
(
time
.
time
())
self
.
count
=
0
self
.
line_counter
=
counter
()
self
.
number
=
int
(
server
.
total_sessions
.
as_long
())
self
.
multi_line
=
[]
self
.
push
(
self
.
timestamp
+
'
\
r
\
n
'
)
def
found_terminator
(
self
):
if
not
self
.
authorized
:
if
hex_digest
(
'%s%s'
%
(
self
.
timestamp
,
self
.
server
.
password
))
!=
self
.
data
:
self
.
log_info
(
'%s: failed authorization'
%
self
,
'warning'
)
self
.
server
.
failed_auths
=
self
.
server
.
failed_auths
+
1
self
.
close
()
else
:
self
.
authorized
=
1
self
.
push
(
'Python '
+
sys
.
version
+
'
\
r
\
n
'
)
self
.
push
(
sys
.
copyright
+
'
\
r
\
n
'
)
self
.
push
(
'Welcome to %s
\
r
\
n
'
%
self
)
self
.
push
(
"[Hint: try 'from __main__ import *']
\
r
\
n
"
)
self
.
prompt
()
self
.
data
=
''
else
:
monitor_channel
.
found_terminator
(
self
)
class
secure_encrypted_monitor_channel
(
secure_monitor_channel
):
"Wrap send() and recv() with a stream cipher"
def
__init__
(
self
,
server
,
conn
,
addr
):
key
=
server
.
password
self
.
outgoing
=
server
.
cipher
.
new
(
key
)
self
.
incoming
=
server
.
cipher
.
new
(
key
)
secure_monitor_channel
.
__init__
(
self
,
server
,
conn
,
addr
)
def
send
(
self
,
data
):
# send the encrypted data instead
ed
=
self
.
outgoing
.
encrypt
(
data
)
return
secure_monitor_channel
.
send
(
self
,
ed
)
def
recv
(
self
,
block_size
):
data
=
secure_monitor_channel
.
recv
(
self
,
block_size
)
if
data
:
dd
=
self
.
incoming
.
decrypt
(
data
)
return
dd
else
:
return
data
"Wrap send() and recv() with a stream cipher"
def
__init__
(
self
,
server
,
conn
,
addr
):
key
=
server
.
password
self
.
outgoing
=
server
.
cipher
.
new
(
key
)
self
.
incoming
=
server
.
cipher
.
new
(
key
)
secure_monitor_channel
.
__init__
(
self
,
server
,
conn
,
addr
)
def
send
(
self
,
data
):
# send the encrypted data instead
ed
=
self
.
outgoing
.
encrypt
(
data
)
return
secure_monitor_channel
.
send
(
self
,
ed
)
def
recv
(
self
,
block_size
):
data
=
secure_monitor_channel
.
recv
(
self
,
block_size
)
if
data
:
dd
=
self
.
incoming
.
decrypt
(
data
)
return
dd
else
:
return
data
class
secure_monitor_server
(
monitor_server
):
channel_class
=
secure_monitor_channel
channel_class
=
secure_monitor_channel
def
__init__
(
self
,
password
,
hostname
=
''
,
port
=
8023
):
monitor_server
.
__init__
(
self
,
hostname
,
port
)
self
.
password
=
password
def
__init__
(
self
,
password
,
hostname
=
''
,
port
=
8023
):
monitor_server
.
__init__
(
self
,
hostname
,
port
)
self
.
password
=
password
def
status
(
self
):
p
=
monitor_server
.
status
(
self
)
# kludge
p
.
data
=
p
.
data
+
(
'<br><b>Failed Authorizations:</b> %d'
%
self
.
failed_auths
)
return
p
def
status
(
self
):
p
=
monitor_server
.
status
(
self
)
# kludge
p
.
data
=
p
.
data
+
(
'<br><b>Failed Authorizations:</b> %d'
%
self
.
failed_auths
)
return
p
# don't try to print from within any of the methods
# of this object. 8^)
class
output_producer
:
def
__init__
(
self
,
channel
,
real_stderr
):
self
.
channel
=
channel
self
.
data
=
''
# use _this_ for debug output
self
.
stderr
=
real_stderr
def
check_data
(
self
):
if
len
(
self
.
data
)
>
1
<<
16
:
# runaway output, close it.
self
.
channel
.
close
()
def
write
(
self
,
data
):
lines
=
string
.
splitfields
(
data
,
'
\
n
'
)
data
=
string
.
join
(
lines
,
'
\
r
\
n
'
)
self
.
data
=
self
.
data
+
data
self
.
check_data
()
def
writeline
(
self
,
line
):
self
.
data
=
self
.
data
+
line
+
'
\
r
\
n
'
self
.
check_data
()
def
writelines
(
self
,
lines
):
self
.
data
=
self
.
data
+
string
.
joinfields
(
lines
,
'
\
r
\
n
'
)
+
'
\
r
\
n
'
self
.
check_data
()
def
ready
(
self
):
return
(
len
(
self
.
data
)
>
0
)
def
flush
(
self
):
pass
def
softspace
(
self
,
*
args
):
pass
def
more
(
self
):
if
self
.
data
:
result
=
self
.
data
[:
512
]
self
.
data
=
self
.
data
[
512
:]
return
result
else
:
return
''
def
__init__
(
self
,
channel
,
real_stderr
):
self
.
channel
=
channel
self
.
data
=
''
# use _this_ for debug output
self
.
stderr
=
real_stderr
def
check_data
(
self
):
if
len
(
self
.
data
)
>
1
<<
16
:
# runaway output, close it.
self
.
channel
.
close
()
def
write
(
self
,
data
):
lines
=
string
.
splitfields
(
data
,
'
\
n
'
)
data
=
string
.
join
(
lines
,
'
\
r
\
n
'
)
self
.
data
=
self
.
data
+
data
self
.
check_data
()
def
writeline
(
self
,
line
):
self
.
data
=
self
.
data
+
line
+
'
\
r
\
n
'
self
.
check_data
()
def
writelines
(
self
,
lines
):
self
.
data
=
self
.
data
+
string
.
joinfields
(
lines
,
'
\
r
\
n
'
)
+
'
\
r
\
n
'
self
.
check_data
()
def
ready
(
self
):
return
(
len
(
self
.
data
)
>
0
)
def
flush
(
self
):
pass
def
softspace
(
self
,
*
args
):
pass
def
more
(
self
):
if
self
.
data
:
result
=
self
.
data
[:
512
]
self
.
data
=
self
.
data
[
512
:]
return
result
else
:
return
''
if
__name__
==
'__main__'
:
import
string
import
sys
if
'-s'
in
sys
.
argv
:
sys
.
argv
.
remove
(
'-s'
)
print
'Enter password: '
,
password
=
raw_input
()
else
:
password
=
None
if
'-e'
in
sys
.
argv
:
sys
.
argv
.
remove
(
'-e'
)
encrypt
=
1
else
:
encrypt
=
0
print
sys
.
argv
if
len
(
sys
.
argv
)
>
1
:
port
=
string
.
atoi
(
sys
.
argv
[
1
])
else
:
port
=
8023
if
password
is
not
None
:
s
=
secure_monitor_server
(
password
,
''
,
port
)
if
encrypt
:
s
.
channel_class
=
secure_encrypted_monitor_channel
import
sapphire
s
.
cipher
=
sapphire
else
:
s
=
monitor_server
(
''
,
port
)
asyncore
.
loop
()
import
string
import
sys
if
'-s'
in
sys
.
argv
:
sys
.
argv
.
remove
(
'-s'
)
print
'Enter password: '
,
password
=
raw_input
()
else
:
password
=
None
if
'-e'
in
sys
.
argv
:
sys
.
argv
.
remove
(
'-e'
)
encrypt
=
1
else
:
encrypt
=
0
print
sys
.
argv
if
len
(
sys
.
argv
)
>
1
:
port
=
string
.
atoi
(
sys
.
argv
[
1
])
else
:
port
=
8023
if
password
is
not
None
:
s
=
secure_monitor_server
(
password
,
''
,
port
)
if
encrypt
:
s
.
channel_class
=
secure_encrypted_monitor_channel
import
sapphire
s
.
cipher
=
sapphire
else
:
s
=
monitor_server
(
''
,
port
)
asyncore
.
loop
()
lib/python/ZServer/medusa/monitor.py
View file @
416c8faf
# -*- Mode: Python; tab-width: 4 -*-
#
Author: Sam Rushing <rushing@nightmare.com>
#
Author: Sam Rushing <rushing@nightmare.com>
#
# python REPL channel.
#
RCS_ID
=
'$Id: monitor.py,v 1.
3 1999/07/20 16:53:50 amos
Exp $'
RCS_ID
=
'$Id: monitor.py,v 1.
4 1999/07/21 16:50:57 klm
Exp $'
import
md5
import
socket
...
...
@@ -22,326 +22,327 @@ from counter import counter
import
producers
class
monitor_channel
(
asynchat
.
async_chat
):
try_linemode
=
1
def
__init__
(
self
,
server
,
sock
,
addr
):
asynchat
.
async_chat
.
__init__
(
self
,
sock
)
self
.
server
=
server
self
.
addr
=
addr
self
.
set_terminator
(
'
\
r
\
n
'
)
self
.
data
=
''
# local bindings specific to this channel
self
.
local_env
=
{}
self
.
push
(
'Python '
+
sys
.
version
+
'
\
r
\
n
'
)
self
.
push
(
sys
.
copyright
+
'
\
r
\
n
'
)
self
.
push
(
'Welcome to %s
\
r
\
n
'
%
self
)
self
.
push
(
"[Hint: try 'from __main__ import *']
\
r
\
n
"
)
self
.
prompt
()
self
.
number
=
server
.
total_sessions
.
as_long
()
self
.
line_counter
=
counter
()
self
.
multi_line
=
[]
def
handle_connect
(
self
):
# send IAC DO LINEMODE
self
.
push
(
'
\
377
\
375
\
"
'
)
def
close
(
self
):
self
.
server
.
closed_sessions
.
increment
()
asynchat
.
async_chat
.
close
(
self
)
def
prompt
(
self
):
self
.
push
(
'>>> '
)
def
collect_incoming_data
(
self
,
data
):
self
.
data
=
self
.
data
+
data
if
len
(
self
.
data
)
>
1024
:
# denial of service.
self
.
push
(
'BCNU
\
r
\
n
'
)
self
.
close_when_done
()
def
found_terminator
(
self
):
line
=
self
.
clean_line
(
self
.
data
)
self
.
data
=
''
self
.
line_counter
.
increment
()
# check for special case inputs...
if
not
line
and
not
self
.
multi_line
:
self
.
prompt
()
return
if
line
in
[
'
\
004
'
,
'exit'
]:
self
.
push
(
'BCNU
\
r
\
n
'
)
self
.
close_when_done
()
return
oldout
=
sys
.
stdout
olderr
=
sys
.
stderr
try
:
p
=
output_producer
(
self
,
olderr
)
sys
.
stdout
=
p
sys
.
stderr
=
p
try
:
# this is, of course, a blocking operation.
# if you wanted to thread this, you would have
# to synchronize, etc... and treat the output
# like a pipe. Not Fun.
#
# try eval first. If that fails, try exec. If that fails,
# hurl.
try
:
if
self
.
multi_line
:
# oh, this is horrible...
raise
SyntaxError
co
=
compile
(
line
,
repr
(
self
),
'eval'
)
result
=
eval
(
co
,
self
.
local_env
)
method
=
'eval'
if
result
is
not
None
:
self
.
log_info
(
repr
(
result
))
self
.
local_env
[
'_'
]
=
result
except
SyntaxError
:
try
:
if
self
.
multi_line
:
if
line
and
line
[
0
]
in
[
' '
,
'
\
t
'
]:
self
.
multi_line
.
append
(
line
)
self
.
push
(
'... '
)
return
else
:
self
.
multi_line
.
append
(
line
)
line
=
string
.
join
(
self
.
multi_line
,
'
\
n
'
)
co
=
compile
(
line
,
repr
(
self
),
'exec'
)
self
.
multi_line
=
[]
else
:
co
=
compile
(
line
,
repr
(
self
),
'exec'
)
except
SyntaxError
,
why
:
if
why
[
0
]
==
'unexpected EOF while parsing'
:
self
.
push
(
'... '
)
self
.
multi_line
.
append
(
line
)
return
exec
co
in
self
.
local_env
method
=
'exec'
except
:
method
=
'exception'
self
.
multi_line
=
[]
(
file
,
fun
,
line
),
t
,
v
,
tbinfo
=
asyncore
.
compact_traceback
()
self
.
log_info
(
'%s %s %s'
%
(
t
,
v
,
tbinfo
),
'warning'
)
finally
:
sys
.
stdout
=
oldout
sys
.
stderr
=
olderr
self
.
log_info
(
'%s:%s (%s)> %s'
%
(
self
.
number
,
self
.
line_counter
,
method
,
repr
(
line
))
)
self
.
push_with_producer
(
p
)
self
.
prompt
()
# for now, we ignore any telnet option stuff sent to
# us, and we process the backspace key ourselves.
# gee, it would be fun to write a full-blown line-editing
# environment, etc...
def
clean_line
(
self
,
line
):
chars
=
[]
for
ch
in
line
:
oc
=
ord
(
ch
)
if
oc
<
127
:
if
oc
in
[
8
,
177
]:
# backspace
chars
=
chars
[:
-
1
]
else
:
chars
.
append
(
ch
)
return
string
.
join
(
chars
,
''
)
try_linemode
=
1
def
__init__
(
self
,
server
,
sock
,
addr
):
asynchat
.
async_chat
.
__init__
(
self
,
sock
)
self
.
server
=
server
self
.
addr
=
addr
self
.
set_terminator
(
'
\
r
\
n
'
)
self
.
data
=
''
# local bindings specific to this channel
self
.
local_env
=
{}
self
.
push
(
'Python '
+
sys
.
version
+
'
\
r
\
n
'
)
self
.
push
(
sys
.
copyright
+
'
\
r
\
n
'
)
self
.
push
(
'Welcome to %s
\
r
\
n
'
%
self
)
self
.
push
(
"[Hint: try 'from __main__ import *']
\
r
\
n
"
)
self
.
prompt
()
self
.
number
=
server
.
total_sessions
.
as_long
()
self
.
line_counter
=
counter
()
self
.
multi_line
=
[]
def
handle_connect
(
self
):
# send IAC DO LINEMODE
self
.
push
(
'
\
377
\
375
\
"
'
)
def
close
(
self
):
self
.
server
.
closed_sessions
.
increment
()
asynchat
.
async_chat
.
close
(
self
)
def
prompt
(
self
):
self
.
push
(
'>>> '
)
def
collect_incoming_data
(
self
,
data
):
self
.
data
=
self
.
data
+
data
if
len
(
self
.
data
)
>
1024
:
# denial of service.
self
.
push
(
'BCNU
\
r
\
n
'
)
self
.
close_when_done
()
def
found_terminator
(
self
):
line
=
self
.
clean_line
(
self
.
data
)
self
.
data
=
''
self
.
line_counter
.
increment
()
# check for special case inputs...
if
not
line
and
not
self
.
multi_line
:
self
.
prompt
()
return
if
line
in
[
'
\
004
'
,
'exit'
]:
self
.
push
(
'BCNU
\
r
\
n
'
)
self
.
close_when_done
()
return
oldout
=
sys
.
stdout
olderr
=
sys
.
stderr
try
:
p
=
output_producer
(
self
,
olderr
)
sys
.
stdout
=
p
sys
.
stderr
=
p
try
:
# this is, of course, a blocking operation.
# if you wanted to thread this, you would have
# to synchronize, etc... and treat the output
# like a pipe. Not Fun.
#
# try eval first. If that fails, try exec. If that fails,
# hurl.
try
:
if
self
.
multi_line
:
# oh, this is horrible...
raise
SyntaxError
co
=
compile
(
line
,
repr
(
self
),
'eval'
)
result
=
eval
(
co
,
self
.
local_env
)
method
=
'eval'
if
result
is
not
None
:
self
.
log_info
(
repr
(
result
))
print
repr
(
result
)
self
.
local_env
[
'_'
]
=
result
except
SyntaxError
:
try
:
if
self
.
multi_line
:
if
line
and
line
[
0
]
in
[
' '
,
'
\
t
'
]:
self
.
multi_line
.
append
(
line
)
self
.
push
(
'... '
)
return
else
:
self
.
multi_line
.
append
(
line
)
line
=
string
.
join
(
self
.
multi_line
,
'
\
n
'
)
co
=
compile
(
line
,
repr
(
self
),
'exec'
)
self
.
multi_line
=
[]
else
:
co
=
compile
(
line
,
repr
(
self
),
'exec'
)
except
SyntaxError
,
why
:
if
why
[
0
]
==
'unexpected EOF while parsing'
:
self
.
push
(
'... '
)
self
.
multi_line
.
append
(
line
)
return
exec
co
in
self
.
local_env
method
=
'exec'
except
:
method
=
'exception'
self
.
multi_line
=
[]
(
file
,
fun
,
line
),
t
,
v
,
tbinfo
=
asyncore
.
compact_traceback
()
self
.
log_info
(
'%s %s %s'
%
(
t
,
v
,
tbinfo
),
'warning'
)
finally
:
sys
.
stdout
=
oldout
sys
.
stderr
=
olderr
self
.
log_info
(
'%s:%s (%s)> %s'
%
(
self
.
number
,
self
.
line_counter
,
method
,
repr
(
line
))
)
self
.
push_with_producer
(
p
)
self
.
prompt
()
# for now, we ignore any telnet option stuff sent to
# us, and we process the backspace key ourselves.
# gee, it would be fun to write a full-blown line-editing
# environment, etc...
def
clean_line
(
self
,
line
):
chars
=
[]
for
ch
in
line
:
oc
=
ord
(
ch
)
if
oc
<
127
:
if
oc
in
[
8
,
177
]:
# backspace
chars
=
chars
[:
-
1
]
else
:
chars
.
append
(
ch
)
return
string
.
join
(
chars
,
''
)
class
monitor_server
(
asyncore
.
dispatcher
):
SERVER_IDENT
=
'Monitor Server (V%s)'
%
VERSION
channel_class
=
monitor_channel
def
__init__
(
self
,
hostname
=
'127.0.0.1'
,
port
=
8023
):
self
.
hostname
=
hostname
self
.
port
=
port
self
.
create_socket
(
socket
.
AF_INET
,
socket
.
SOCK_STREAM
)
self
.
set_reuse_addr
()
self
.
bind
((
hostname
,
port
))
self
.
log_info
(
'%s started on port %d'
%
(
self
.
SERVER_IDENT
,
port
))
self
.
listen
(
5
)
self
.
closed
=
0
self
.
failed_auths
=
0
self
.
total_sessions
=
counter
()
self
.
closed_sessions
=
counter
()
def
writable
(
self
):
return
0
def
handle_accept
(
self
):
conn
,
addr
=
self
.
accept
()
self
.
log_info
(
'Incoming monitor connection from %s:%d'
%
addr
)
self
.
channel_class
(
self
,
conn
,
addr
)
self
.
total_sessions
.
increment
()
def
status
(
self
):
return
producers
.
simple_producer
(
'<h2>%s</h2>'
%
self
.
SERVER_IDENT
+
'<br><b>Total Sessions:</b> %s'
%
self
.
total_sessions
+
'<br><b>Current Sessions:</b> %d'
%
(
self
.
total_sessions
.
as_long
()
-
self
.
closed_sessions
.
as_long
()
)
)
SERVER_IDENT
=
'Monitor Server (V%s)'
%
VERSION
channel_class
=
monitor_channel
def
__init__
(
self
,
hostname
=
'127.0.0.1'
,
port
=
8023
):
self
.
hostname
=
hostname
self
.
port
=
port
self
.
create_socket
(
socket
.
AF_INET
,
socket
.
SOCK_STREAM
)
self
.
set_reuse_addr
()
self
.
bind
((
hostname
,
port
))
self
.
log_info
(
'%s started on port %d'
%
(
self
.
SERVER_IDENT
,
port
))
self
.
listen
(
5
)
self
.
closed
=
0
self
.
failed_auths
=
0
self
.
total_sessions
=
counter
()
self
.
closed_sessions
=
counter
()
def
writable
(
self
):
return
0
def
handle_accept
(
self
):
conn
,
addr
=
self
.
accept
()
self
.
log_info
(
'Incoming monitor connection from %s:%d'
%
addr
)
self
.
channel_class
(
self
,
conn
,
addr
)
self
.
total_sessions
.
increment
()
def
status
(
self
):
return
producers
.
simple_producer
(
'<h2>%s</h2>'
%
self
.
SERVER_IDENT
+
'<br><b>Total Sessions:</b> %s'
%
self
.
total_sessions
+
'<br><b>Current Sessions:</b> %d'
%
(
self
.
total_sessions
.
as_long
()
-
self
.
closed_sessions
.
as_long
()
)
)
def
hex_digest
(
s
):
m
=
md5
.
md5
()
m
.
update
(
s
)
return
string
.
joinfields
(
map
(
lambda
x
:
hex
(
ord
(
x
))[
2
:],
map
(
None
,
m
.
digest
())),
''
,
)
m
=
md5
.
md5
()
m
.
update
(
s
)
return
string
.
joinfields
(
map
(
lambda
x
:
hex
(
ord
(
x
))[
2
:],
map
(
None
,
m
.
digest
())),
''
,
)
class
secure_monitor_channel
(
monitor_channel
):
authorized
=
0
def
__init__
(
self
,
server
,
sock
,
addr
):
asynchat
.
async_chat
.
__init__
(
self
,
sock
)
self
.
server
=
server
self
.
addr
=
addr
self
.
set_terminator
(
'
\
r
\
n
'
)
self
.
data
=
''
# local bindings specific to this channel
self
.
local_env
=
{}
# send timestamp string
self
.
timestamp
=
str
(
time
.
time
())
self
.
count
=
0
self
.
line_counter
=
counter
()
self
.
number
=
int
(
server
.
total_sessions
.
as_long
())
self
.
multi_line
=
[]
self
.
push
(
self
.
timestamp
+
'
\
r
\
n
'
)
def
found_terminator
(
self
):
if
not
self
.
authorized
:
if
hex_digest
(
'%s%s'
%
(
self
.
timestamp
,
self
.
server
.
password
))
!=
self
.
data
:
self
.
log_info
(
'%s: failed authorization'
%
self
,
'warning'
)
self
.
server
.
failed_auths
=
self
.
server
.
failed_auths
+
1
self
.
close
()
else
:
self
.
authorized
=
1
self
.
push
(
'Python '
+
sys
.
version
+
'
\
r
\
n
'
)
self
.
push
(
sys
.
copyright
+
'
\
r
\
n
'
)
self
.
push
(
'Welcome to %s
\
r
\
n
'
%
self
)
self
.
push
(
"[Hint: try 'from __main__ import *']
\
r
\
n
"
)
self
.
prompt
()
self
.
data
=
''
else
:
monitor_channel
.
found_terminator
(
self
)
authorized
=
0
def
__init__
(
self
,
server
,
sock
,
addr
):
asynchat
.
async_chat
.
__init__
(
self
,
sock
)
self
.
server
=
server
self
.
addr
=
addr
self
.
set_terminator
(
'
\
r
\
n
'
)
self
.
data
=
''
# local bindings specific to this channel
self
.
local_env
=
{}
# send timestamp string
self
.
timestamp
=
str
(
time
.
time
())
self
.
count
=
0
self
.
line_counter
=
counter
()
self
.
number
=
int
(
server
.
total_sessions
.
as_long
())
self
.
multi_line
=
[]
self
.
push
(
self
.
timestamp
+
'
\
r
\
n
'
)
def
found_terminator
(
self
):
if
not
self
.
authorized
:
if
hex_digest
(
'%s%s'
%
(
self
.
timestamp
,
self
.
server
.
password
))
!=
self
.
data
:
self
.
log_info
(
'%s: failed authorization'
%
self
,
'warning'
)
self
.
server
.
failed_auths
=
self
.
server
.
failed_auths
+
1
self
.
close
()
else
:
self
.
authorized
=
1
self
.
push
(
'Python '
+
sys
.
version
+
'
\
r
\
n
'
)
self
.
push
(
sys
.
copyright
+
'
\
r
\
n
'
)
self
.
push
(
'Welcome to %s
\
r
\
n
'
%
self
)
self
.
push
(
"[Hint: try 'from __main__ import *']
\
r
\
n
"
)
self
.
prompt
()
self
.
data
=
''
else
:
monitor_channel
.
found_terminator
(
self
)
class
secure_encrypted_monitor_channel
(
secure_monitor_channel
):
"Wrap send() and recv() with a stream cipher"
def
__init__
(
self
,
server
,
conn
,
addr
):
key
=
server
.
password
self
.
outgoing
=
server
.
cipher
.
new
(
key
)
self
.
incoming
=
server
.
cipher
.
new
(
key
)
secure_monitor_channel
.
__init__
(
self
,
server
,
conn
,
addr
)
def
send
(
self
,
data
):
# send the encrypted data instead
ed
=
self
.
outgoing
.
encrypt
(
data
)
return
secure_monitor_channel
.
send
(
self
,
ed
)
def
recv
(
self
,
block_size
):
data
=
secure_monitor_channel
.
recv
(
self
,
block_size
)
if
data
:
dd
=
self
.
incoming
.
decrypt
(
data
)
return
dd
else
:
return
data
"Wrap send() and recv() with a stream cipher"
def
__init__
(
self
,
server
,
conn
,
addr
):
key
=
server
.
password
self
.
outgoing
=
server
.
cipher
.
new
(
key
)
self
.
incoming
=
server
.
cipher
.
new
(
key
)
secure_monitor_channel
.
__init__
(
self
,
server
,
conn
,
addr
)
def
send
(
self
,
data
):
# send the encrypted data instead
ed
=
self
.
outgoing
.
encrypt
(
data
)
return
secure_monitor_channel
.
send
(
self
,
ed
)
def
recv
(
self
,
block_size
):
data
=
secure_monitor_channel
.
recv
(
self
,
block_size
)
if
data
:
dd
=
self
.
incoming
.
decrypt
(
data
)
return
dd
else
:
return
data
class
secure_monitor_server
(
monitor_server
):
channel_class
=
secure_monitor_channel
channel_class
=
secure_monitor_channel
def
__init__
(
self
,
password
,
hostname
=
''
,
port
=
8023
):
monitor_server
.
__init__
(
self
,
hostname
,
port
)
self
.
password
=
password
def
__init__
(
self
,
password
,
hostname
=
''
,
port
=
8023
):
monitor_server
.
__init__
(
self
,
hostname
,
port
)
self
.
password
=
password
def
status
(
self
):
p
=
monitor_server
.
status
(
self
)
# kludge
p
.
data
=
p
.
data
+
(
'<br><b>Failed Authorizations:</b> %d'
%
self
.
failed_auths
)
return
p
def
status
(
self
):
p
=
monitor_server
.
status
(
self
)
# kludge
p
.
data
=
p
.
data
+
(
'<br><b>Failed Authorizations:</b> %d'
%
self
.
failed_auths
)
return
p
# don't try to print from within any of the methods
# of this object. 8^)
class
output_producer
:
def
__init__
(
self
,
channel
,
real_stderr
):
self
.
channel
=
channel
self
.
data
=
''
# use _this_ for debug output
self
.
stderr
=
real_stderr
def
check_data
(
self
):
if
len
(
self
.
data
)
>
1
<<
16
:
# runaway output, close it.
self
.
channel
.
close
()
def
write
(
self
,
data
):
lines
=
string
.
splitfields
(
data
,
'
\
n
'
)
data
=
string
.
join
(
lines
,
'
\
r
\
n
'
)
self
.
data
=
self
.
data
+
data
self
.
check_data
()
def
writeline
(
self
,
line
):
self
.
data
=
self
.
data
+
line
+
'
\
r
\
n
'
self
.
check_data
()
def
writelines
(
self
,
lines
):
self
.
data
=
self
.
data
+
string
.
joinfields
(
lines
,
'
\
r
\
n
'
)
+
'
\
r
\
n
'
self
.
check_data
()
def
ready
(
self
):
return
(
len
(
self
.
data
)
>
0
)
def
flush
(
self
):
pass
def
softspace
(
self
,
*
args
):
pass
def
more
(
self
):
if
self
.
data
:
result
=
self
.
data
[:
512
]
self
.
data
=
self
.
data
[
512
:]
return
result
else
:
return
''
def
__init__
(
self
,
channel
,
real_stderr
):
self
.
channel
=
channel
self
.
data
=
''
# use _this_ for debug output
self
.
stderr
=
real_stderr
def
check_data
(
self
):
if
len
(
self
.
data
)
>
1
<<
16
:
# runaway output, close it.
self
.
channel
.
close
()
def
write
(
self
,
data
):
lines
=
string
.
splitfields
(
data
,
'
\
n
'
)
data
=
string
.
join
(
lines
,
'
\
r
\
n
'
)
self
.
data
=
self
.
data
+
data
self
.
check_data
()
def
writeline
(
self
,
line
):
self
.
data
=
self
.
data
+
line
+
'
\
r
\
n
'
self
.
check_data
()
def
writelines
(
self
,
lines
):
self
.
data
=
self
.
data
+
string
.
joinfields
(
lines
,
'
\
r
\
n
'
)
+
'
\
r
\
n
'
self
.
check_data
()
def
ready
(
self
):
return
(
len
(
self
.
data
)
>
0
)
def
flush
(
self
):
pass
def
softspace
(
self
,
*
args
):
pass
def
more
(
self
):
if
self
.
data
:
result
=
self
.
data
[:
512
]
self
.
data
=
self
.
data
[
512
:]
return
result
else
:
return
''
if
__name__
==
'__main__'
:
import
string
import
sys
if
'-s'
in
sys
.
argv
:
sys
.
argv
.
remove
(
'-s'
)
print
'Enter password: '
,
password
=
raw_input
()
else
:
password
=
None
if
'-e'
in
sys
.
argv
:
sys
.
argv
.
remove
(
'-e'
)
encrypt
=
1
else
:
encrypt
=
0
print
sys
.
argv
if
len
(
sys
.
argv
)
>
1
:
port
=
string
.
atoi
(
sys
.
argv
[
1
])
else
:
port
=
8023
if
password
is
not
None
:
s
=
secure_monitor_server
(
password
,
''
,
port
)
if
encrypt
:
s
.
channel_class
=
secure_encrypted_monitor_channel
import
sapphire
s
.
cipher
=
sapphire
else
:
s
=
monitor_server
(
''
,
port
)
asyncore
.
loop
()
import
string
import
sys
if
'-s'
in
sys
.
argv
:
sys
.
argv
.
remove
(
'-s'
)
print
'Enter password: '
,
password
=
raw_input
()
else
:
password
=
None
if
'-e'
in
sys
.
argv
:
sys
.
argv
.
remove
(
'-e'
)
encrypt
=
1
else
:
encrypt
=
0
print
sys
.
argv
if
len
(
sys
.
argv
)
>
1
:
port
=
string
.
atoi
(
sys
.
argv
[
1
])
else
:
port
=
8023
if
password
is
not
None
:
s
=
secure_monitor_server
(
password
,
''
,
port
)
if
encrypt
:
s
.
channel_class
=
secure_encrypted_monitor_channel
import
sapphire
s
.
cipher
=
sapphire
else
:
s
=
monitor_server
(
''
,
port
)
asyncore
.
loop
()
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