Clean-up and improvements on twisted.manhole
git-svn-id: svn://svn.cy55.de/Zope3/src/cybertools/trunk@1086 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
parent
98ce9acb56
commit
72a3d7cf2c
1 changed files with 71 additions and 22 deletions
|
@ -1,14 +1,37 @@
|
||||||
"""
|
"""
|
||||||
|
A simple twisted manhole that allows you to access a running Zope 3
|
||||||
|
instance via a python command line without having to run ZEO.
|
||||||
|
|
||||||
|
You may run it for testing purposes via `python manhole.py` (note that
|
||||||
|
the twisted library must be reachable via your PYTHONPATH) and log in
|
||||||
|
from another console window using `ssh -p 5001 admin@localhost`. The
|
||||||
|
password is defined below in the "reactor.listenTCP()" statement. The
|
||||||
|
manhole script may be stopped with Ctrl-C.
|
||||||
|
|
||||||
|
Note that this will open up a serious security hole on your computer
|
||||||
|
as now anybody knowing this password may login to the Python console
|
||||||
|
and get full access to the system with the permissions of the user
|
||||||
|
running the manhole script.
|
||||||
|
|
||||||
|
In order to use it with Zope copy the cybertools.twisted-configure.zcml
|
||||||
|
to the etc/package-includes directory of your Zope instance and restart
|
||||||
|
Zope. You can then log in with ssh like shown above, using the username
|
||||||
|
and password of the zope.manager principal defined in your principals.zcml.
|
||||||
|
|
||||||
|
After logging in use the `help` command to get more information.
|
||||||
|
|
||||||
$Id$
|
$Id$
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from twisted.internet import reactor, protocol
|
from twisted.internet import reactor, protocol, defer
|
||||||
from twisted.protocols import basic
|
from twisted.protocols import basic
|
||||||
from twisted.cred import portal, checkers
|
from twisted.cred import portal, checkers, credentials, error as credError
|
||||||
from twisted.conch import manhole, manhole_ssh
|
from twisted.conch import manhole, manhole_ssh
|
||||||
|
from zope.interface import implements
|
||||||
try:
|
try:
|
||||||
from zope.app.publication.zopepublication import ZopePublication
|
from zope.app.publication.zopepublication import ZopePublication
|
||||||
from zope.app.component.hooks import setSite
|
from zope.app.component.hooks import setSite
|
||||||
|
from zope.app.security.principalregistry import principalRegistry
|
||||||
from zope.app import zapi
|
from zope.app import zapi
|
||||||
hasZope = True
|
hasZope = True
|
||||||
except:
|
except:
|
||||||
|
@ -17,34 +40,60 @@ import time
|
||||||
import sys
|
import sys
|
||||||
from cStringIO import StringIO
|
from cStringIO import StringIO
|
||||||
|
|
||||||
|
|
||||||
def getManholeFactory(namespace, **passwords):
|
def getManholeFactory(namespace, **passwords):
|
||||||
realm = manhole_ssh.TerminalRealm()
|
realm = manhole_ssh.TerminalRealm()
|
||||||
def getManhole(_):
|
def getManhole(_):
|
||||||
return manhole.Manhole(namespace)
|
return manhole.Manhole(namespace)
|
||||||
realm.chainedProtocolFactory.protocolFactory = getManhole
|
realm.chainedProtocolFactory.protocolFactory = getManhole
|
||||||
p = portal.Portal(realm)
|
p = portal.Portal(realm)
|
||||||
p.registerChecker(
|
checker = (hasZope and ZopeManagerChecker() or
|
||||||
checkers.InMemoryUsernamePasswordDatabaseDontUse(**passwords))
|
checkers.InMemoryUsernamePasswordDatabaseDontUse(**passwords))
|
||||||
|
p.registerChecker(checker)
|
||||||
return manhole_ssh.ConchFactory(p)
|
return manhole_ssh.ConchFactory(p)
|
||||||
|
|
||||||
|
|
||||||
|
class ZopeManagerChecker(object):
|
||||||
|
|
||||||
|
implements(checkers.ICredentialsChecker)
|
||||||
|
credentialInterfaces = (credentials.IUsernamePassword,)
|
||||||
|
|
||||||
|
def requestAvatarId(self, credentials):
|
||||||
|
manager = principalRegistry.getPrincipal('zope.manager')
|
||||||
|
login = credentials.username
|
||||||
|
password = credentials.password
|
||||||
|
if login == manager.getLogin() and manager.validate(password):
|
||||||
|
return defer.succeed(login)
|
||||||
|
return defer.fail(credError.UnauthorizedLogin(
|
||||||
|
'User/password not correct'))
|
||||||
|
|
||||||
|
|
||||||
def printTime():
|
def printTime():
|
||||||
print 'twisted.manhole running:', time.strftime('%H:%M:%S')
|
print 'twisted.manhole running:', time.strftime('%H:%M:%S')
|
||||||
reactor.callLater(60, printTime)
|
reactor.callLater(60, printTime)
|
||||||
|
|
||||||
def help():
|
|
||||||
info = """
|
class Help(object):
|
||||||
Use dir() to see what variables and functions are available."""
|
|
||||||
zopeInfo = """
|
def __repr__(self):
|
||||||
In order to get access to local utilities and adapters you should
|
info = """
|
||||||
issue a setSite(root). Don't forget to call setSite() before
|
Use dir() to see what variables and functions are available.
|
||||||
finishing your session.
|
"""
|
||||||
You may use x = zapi.traverse(root, 'path/to/object') to get an
|
zopeInfo = """
|
||||||
object in your folder hierarchy. Then you may call any method or
|
You may use x = zapi.traverse(root, 'path/to/object') to get an
|
||||||
access any attribute of this object."""
|
object in your folder hierarchy. Then you may call any method or
|
||||||
print info
|
access any attribute of this object.
|
||||||
if hasZope:
|
|
||||||
print zopeInfo
|
In order to get access to local utilities and adapters you may
|
||||||
print
|
issue a setSite(root). Don't forget to call setSite() before
|
||||||
|
finishing your session in order to reset this setting.
|
||||||
|
"""
|
||||||
|
return info + (hasZope and zopeInfo or '')
|
||||||
|
|
||||||
|
def __call__(self):
|
||||||
|
print self
|
||||||
|
|
||||||
|
help = Help()
|
||||||
|
|
||||||
|
|
||||||
def startup(event=None, port=5001):
|
def startup(event=None, port=5001):
|
||||||
|
@ -52,14 +101,14 @@ def startup(event=None, port=5001):
|
||||||
printTime()
|
printTime()
|
||||||
d = globals()
|
d = globals()
|
||||||
if hasZope and event is not None:
|
if hasZope and event is not None:
|
||||||
conn =event.database.open()
|
connection = event.database.open()
|
||||||
root = conn.root()[ZopePublication.root_name]
|
root = connection.root()[ZopePublication.root_name]
|
||||||
else:
|
else:
|
||||||
hasZope = False
|
hasZope = False
|
||||||
d.update(locals())
|
d.update(locals())
|
||||||
namespace = {}
|
namespace = {}
|
||||||
for key in ('__builtins__', 'conn', 'event', 'setSite', 'hasZope', 'zapi',
|
for key in ('__builtins__', 'connection', 'event', 'setSite', 'hasZope',
|
||||||
'root', '__doc__', 'help'):
|
'zapi', 'root', '__doc__', 'help'):
|
||||||
if key in d:
|
if key in d:
|
||||||
namespace[key] = d[key]
|
namespace[key] = d[key]
|
||||||
# TODO: get admin password from somewhere else or use a real checker.
|
# TODO: get admin password from somewhere else or use a real checker.
|
||||||
|
|
Loading…
Add table
Reference in a new issue