RAHHH
This commit is contained in:
@@ -0,0 +1,22 @@
|
||||
# -*- test-case-name: twisted.test.test_plugin -*-
|
||||
# Copyright (c) 2005 Divmod, Inc.
|
||||
# Copyright (c) Twisted Matrix Laboratories.
|
||||
# See LICENSE for details.
|
||||
|
||||
"""
|
||||
Plugins for services implemented in Twisted.
|
||||
|
||||
Plugins go in directories on your PYTHONPATH named twisted/plugins:
|
||||
this is the only place where an __init__.py is necessary, thanks to
|
||||
the __path__ variable.
|
||||
|
||||
@author: Jp Calderone
|
||||
@author: Glyph Lefkowitz
|
||||
"""
|
||||
|
||||
from typing import List
|
||||
|
||||
from twisted.plugin import pluginPackagePaths
|
||||
|
||||
__path__.extend(pluginPackagePaths(__name__))
|
||||
__all__: List[str] = [] # nothing to see here, move along, move along
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,176 @@
|
||||
###############################################################################
|
||||
#
|
||||
# The MIT License (MIT)
|
||||
#
|
||||
# Copyright (c) typedef int GmbH
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
from zope.interface import implementer
|
||||
|
||||
from twisted.plugin import IPlugin
|
||||
from twisted.internet.interfaces import IStreamServerEndpointStringParser, \
|
||||
IStreamServerEndpoint, \
|
||||
IStreamClientEndpoint
|
||||
|
||||
try:
|
||||
from twisted.internet.interfaces import IStreamClientEndpointStringParserWithReactor
|
||||
_HAS_REACTOR_ARG = True
|
||||
except ImportError:
|
||||
_HAS_REACTOR_ARG = False
|
||||
from twisted.internet.interfaces import IStreamClientEndpointStringParser as \
|
||||
IStreamClientEndpointStringParserWithReactor
|
||||
|
||||
from twisted.internet.endpoints import serverFromString, clientFromString
|
||||
|
||||
from autobahn.twisted.websocket import WrappingWebSocketServerFactory, \
|
||||
WrappingWebSocketClientFactory
|
||||
|
||||
|
||||
def _parseOptions(options):
|
||||
opts = {}
|
||||
|
||||
if 'url' not in options:
|
||||
raise Exception("URL needed")
|
||||
else:
|
||||
opts['url'] = options['url']
|
||||
|
||||
if 'compression' in options:
|
||||
value = options['compression'].lower().strip()
|
||||
if value == 'true':
|
||||
opts['enableCompression'] = True
|
||||
elif value == 'false':
|
||||
opts['enableCompression'] = False
|
||||
else:
|
||||
raise Exception("invalid value '{0}' for compression".format(value))
|
||||
|
||||
if 'autofrag' in options:
|
||||
try:
|
||||
value = int(options['autofrag'])
|
||||
except:
|
||||
raise Exception("invalid value '{0}' for autofrag".format(options['autofrag']))
|
||||
|
||||
if value < 0:
|
||||
raise Exception("negative value '{0}' for autofrag".format(value))
|
||||
|
||||
opts['autoFragmentSize'] = value
|
||||
|
||||
if 'subprotocol' in options:
|
||||
value = options['subprotocol'].lower().strip()
|
||||
opts['subprotocol'] = value
|
||||
|
||||
if 'debug' in options:
|
||||
value = options['debug'].lower().strip()
|
||||
if value == 'true':
|
||||
opts['debug'] = True
|
||||
elif value == 'false':
|
||||
opts['debug'] = False
|
||||
else:
|
||||
raise Exception("invalid value '{0}' for debug".format(value))
|
||||
|
||||
return opts
|
||||
|
||||
|
||||
@implementer(IPlugin)
|
||||
@implementer(IStreamServerEndpointStringParser)
|
||||
class AutobahnServerParser(object):
|
||||
|
||||
prefix = "autobahn"
|
||||
|
||||
def parseStreamServer(self, reactor, description, **options):
|
||||
|
||||
# The present endpoint plugin is intended to be used as in the
|
||||
# following for running a streaming protocol over WebSocket over
|
||||
# an underlying stream transport.
|
||||
#
|
||||
# endpoint = serverFromString(reactor,
|
||||
# "autobahn:tcp\:9000\:interface\=0.0.0.0:url=ws\://localhost\:9000:compress=false"
|
||||
#
|
||||
# This will result in `parseStreamServer` to be called will
|
||||
#
|
||||
# description == tcp:9000:interface=0.0.0.0
|
||||
#
|
||||
# and
|
||||
#
|
||||
# options == {'url': 'ws://localhost:9000', 'compress': 'false'}
|
||||
#
|
||||
# Essentially, we are using the `\:` escape to coerce the endpoint descriptor
|
||||
# of the underlying stream transport into one (first) positional argument.
|
||||
#
|
||||
# Note that the `\:` within "url" is another form of escaping!
|
||||
#
|
||||
opts = _parseOptions(options)
|
||||
endpoint = serverFromString(reactor, description)
|
||||
return AutobahnServerEndpoint(reactor, endpoint, opts)
|
||||
|
||||
|
||||
@implementer(IPlugin)
|
||||
@implementer(IStreamServerEndpoint)
|
||||
class AutobahnServerEndpoint(object):
|
||||
|
||||
def __init__(self, reactor, endpoint, options):
|
||||
self._reactor = reactor
|
||||
self._endpoint = endpoint
|
||||
self._options = options
|
||||
|
||||
def listen(self, protocolFactory):
|
||||
return self._endpoint.listen(WrappingWebSocketServerFactory(protocolFactory, reactor=self._reactor, **self._options))
|
||||
|
||||
|
||||
# note that for older Twisted before the WithReactor variant, we
|
||||
# import it under that name so we can share (most of) this
|
||||
# implementation...
|
||||
@implementer(IPlugin)
|
||||
@implementer(IStreamClientEndpointStringParserWithReactor)
|
||||
class AutobahnClientParser(object):
|
||||
prefix = "autobahn"
|
||||
|
||||
def parseStreamClient(self, *args, **options):
|
||||
if _HAS_REACTOR_ARG:
|
||||
reactor = args[0]
|
||||
if len(args) != 2:
|
||||
raise RuntimeError("autobahn: client plugin takes exactly one positional argument")
|
||||
description = args[1]
|
||||
else:
|
||||
from twisted.internet import reactor
|
||||
if len(args) != 1:
|
||||
raise RuntimeError("autobahn: client plugin takes exactly one positional argument")
|
||||
description = args[0]
|
||||
opts = _parseOptions(options)
|
||||
endpoint = clientFromString(reactor, description)
|
||||
return AutobahnClientEndpoint(reactor, endpoint, opts)
|
||||
|
||||
|
||||
@implementer(IPlugin)
|
||||
@implementer(IStreamClientEndpoint)
|
||||
class AutobahnClientEndpoint(object):
|
||||
|
||||
def __init__(self, reactor, endpoint, options):
|
||||
self._reactor = reactor
|
||||
self._endpoint = endpoint
|
||||
self._options = options
|
||||
|
||||
def connect(self, protocolFactory):
|
||||
return self._endpoint.connect(WrappingWebSocketClientFactory(protocolFactory, reactor=self._reactor, **self._options))
|
||||
|
||||
|
||||
autobahnServerParser = AutobahnServerParser()
|
||||
autobahnClientParser = AutobahnClientParser()
|
||||
@@ -0,0 +1,32 @@
|
||||
###############################################################################
|
||||
#
|
||||
# The MIT License (MIT)
|
||||
#
|
||||
# Copyright (c) typedef int GmbH
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
from twisted.application.service import ServiceMaker
|
||||
|
||||
serviceMaker = ServiceMaker('endpointforward',
|
||||
'autobahn.twisted.forwarder',
|
||||
'A simple stream endpoint forwarder',
|
||||
'endpointforward')
|
||||
@@ -0,0 +1,38 @@
|
||||
# -*- test-case-name: twisted.test.test_strcred -*-
|
||||
#
|
||||
# Copyright (c) Twisted Matrix Laboratories.
|
||||
# See LICENSE for details.
|
||||
|
||||
"""
|
||||
Cred plugin for anonymous logins.
|
||||
"""
|
||||
|
||||
|
||||
from zope.interface import implementer
|
||||
|
||||
from twisted import plugin
|
||||
from twisted.cred.checkers import AllowAnonymousAccess
|
||||
from twisted.cred.credentials import IAnonymous
|
||||
from twisted.cred.strcred import ICheckerFactory
|
||||
|
||||
anonymousCheckerFactoryHelp = """
|
||||
This allows anonymous authentication for servers that support it.
|
||||
"""
|
||||
|
||||
|
||||
@implementer(ICheckerFactory, plugin.IPlugin)
|
||||
class AnonymousCheckerFactory:
|
||||
"""
|
||||
Generates checkers that will authenticate an anonymous request.
|
||||
"""
|
||||
|
||||
authType = "anonymous"
|
||||
authHelp = anonymousCheckerFactoryHelp
|
||||
argStringFormat = "No argstring required."
|
||||
credentialInterfaces = (IAnonymous,)
|
||||
|
||||
def generateChecker(self, argstring=""):
|
||||
return AllowAnonymousAccess()
|
||||
|
||||
|
||||
theAnonymousCheckerFactory = AnonymousCheckerFactory()
|
||||
@@ -0,0 +1,59 @@
|
||||
# -*- test-case-name: twisted.test.test_strcred -*-
|
||||
#
|
||||
# Copyright (c) Twisted Matrix Laboratories.
|
||||
# See LICENSE for details.
|
||||
|
||||
"""
|
||||
Cred plugin for a file of the format 'username:password'.
|
||||
"""
|
||||
|
||||
|
||||
import sys
|
||||
|
||||
from zope.interface import implementer
|
||||
|
||||
from twisted import plugin
|
||||
from twisted.cred.checkers import FilePasswordDB
|
||||
from twisted.cred.credentials import IUsernameHashedPassword, IUsernamePassword
|
||||
from twisted.cred.strcred import ICheckerFactory
|
||||
|
||||
fileCheckerFactoryHelp = """
|
||||
This checker expects to receive the location of a file that
|
||||
conforms to the FilePasswordDB format. Each line in the file
|
||||
should be of the format 'username:password', in plain text.
|
||||
"""
|
||||
|
||||
invalidFileWarning = "Warning: not a valid file"
|
||||
|
||||
|
||||
@implementer(ICheckerFactory, plugin.IPlugin)
|
||||
class FileCheckerFactory:
|
||||
"""
|
||||
A factory for instances of L{FilePasswordDB}.
|
||||
"""
|
||||
|
||||
authType = "file"
|
||||
authHelp = fileCheckerFactoryHelp
|
||||
argStringFormat = "Location of a FilePasswordDB-formatted file."
|
||||
# Explicitly defined here because FilePasswordDB doesn't do it for us
|
||||
credentialInterfaces = (IUsernamePassword, IUsernameHashedPassword)
|
||||
|
||||
errorOutput = sys.stderr
|
||||
|
||||
def generateChecker(self, argstring):
|
||||
"""
|
||||
This checker factory expects to get the location of a file.
|
||||
The file should conform to the format required by
|
||||
L{FilePasswordDB} (using defaults for all
|
||||
initialization parameters).
|
||||
"""
|
||||
from twisted.python.filepath import FilePath
|
||||
|
||||
if not argstring.strip():
|
||||
raise ValueError("%r requires a filename" % self.authType)
|
||||
elif not FilePath(argstring).isfile():
|
||||
self.errorOutput.write(f"{invalidFileWarning}: {argstring}\n")
|
||||
return FilePasswordDB(argstring)
|
||||
|
||||
|
||||
theFileCheckerFactory = FileCheckerFactory()
|
||||
@@ -0,0 +1,65 @@
|
||||
# -*- test-case-name: twisted.test.test_strcred -*-
|
||||
#
|
||||
# Copyright (c) Twisted Matrix Laboratories.
|
||||
# See LICENSE for details.
|
||||
|
||||
"""
|
||||
Cred plugin for an in-memory user database.
|
||||
"""
|
||||
|
||||
|
||||
from zope.interface import implementer
|
||||
|
||||
from twisted import plugin
|
||||
from twisted.cred.checkers import InMemoryUsernamePasswordDatabaseDontUse
|
||||
from twisted.cred.credentials import IUsernameHashedPassword, IUsernamePassword
|
||||
from twisted.cred.strcred import ICheckerFactory
|
||||
|
||||
inMemoryCheckerFactoryHelp = """
|
||||
A checker that uses an in-memory user database.
|
||||
|
||||
This is only of use in one-off test programs or examples which
|
||||
don't want to focus too much on how credentials are verified. You
|
||||
really don't want to use this for anything else. It is a toy.
|
||||
"""
|
||||
|
||||
|
||||
@implementer(ICheckerFactory, plugin.IPlugin)
|
||||
class InMemoryCheckerFactory:
|
||||
"""
|
||||
A factory for in-memory credentials checkers.
|
||||
|
||||
This is only of use in one-off test programs or examples which don't
|
||||
want to focus too much on how credentials are verified.
|
||||
|
||||
You really don't want to use this for anything else. It is, at best, a
|
||||
toy. If you need a simple credentials checker for a real application,
|
||||
see L{cred_file.FileCheckerFactory}.
|
||||
"""
|
||||
|
||||
authType = "memory"
|
||||
authHelp = inMemoryCheckerFactoryHelp
|
||||
argStringFormat = "A colon-separated list (name:password:...)"
|
||||
credentialInterfaces = (IUsernamePassword, IUsernameHashedPassword)
|
||||
|
||||
def generateChecker(self, argstring):
|
||||
"""
|
||||
This checker factory expects to get a list of
|
||||
username:password pairs, with each pair also separated by a
|
||||
colon. For example, the string 'alice:f:bob:g' would generate
|
||||
two users, one named 'alice' and one named 'bob'.
|
||||
"""
|
||||
checker = InMemoryUsernamePasswordDatabaseDontUse()
|
||||
if argstring:
|
||||
pieces = argstring.split(":")
|
||||
if len(pieces) % 2:
|
||||
from twisted.cred.strcred import InvalidAuthArgumentString
|
||||
|
||||
raise InvalidAuthArgumentString("argstring must be in format U:P:...")
|
||||
for i in range(0, len(pieces), 2):
|
||||
username, password = pieces[i], pieces[i + 1]
|
||||
checker.addUser(username, password)
|
||||
return checker
|
||||
|
||||
|
||||
theInMemoryCheckerFactory = InMemoryCheckerFactory()
|
||||
@@ -0,0 +1,48 @@
|
||||
# -*- test-case-name: twisted.test.test_strcred -*-
|
||||
#
|
||||
# Copyright (c) Twisted Matrix Laboratories.
|
||||
# See LICENSE for details.
|
||||
|
||||
"""
|
||||
Cred plugin for ssh key login.
|
||||
"""
|
||||
|
||||
|
||||
from zope.interface import implementer
|
||||
|
||||
from twisted import plugin
|
||||
from twisted.cred.strcred import ICheckerFactory
|
||||
|
||||
sshKeyCheckerFactoryHelp = """
|
||||
This allows SSH public key authentication, based on public keys listed in
|
||||
authorized_keys and authorized_keys2 files in user .ssh/ directories.
|
||||
"""
|
||||
|
||||
|
||||
try:
|
||||
from twisted.conch.checkers import SSHPublicKeyChecker, UNIXAuthorizedKeysFiles
|
||||
|
||||
@implementer(ICheckerFactory, plugin.IPlugin)
|
||||
class SSHKeyCheckerFactory:
|
||||
"""
|
||||
Generates checkers that will authenticate a SSH public key
|
||||
"""
|
||||
|
||||
authType = "sshkey"
|
||||
authHelp = sshKeyCheckerFactoryHelp
|
||||
argStringFormat = "No argstring required."
|
||||
credentialInterfaces = SSHPublicKeyChecker.credentialInterfaces
|
||||
|
||||
def generateChecker(self, argstring=""):
|
||||
"""
|
||||
This checker factory ignores the argument string. Everything
|
||||
needed to authenticate users is pulled out of the public keys
|
||||
listed in user .ssh/ directories.
|
||||
"""
|
||||
return SSHPublicKeyChecker(UNIXAuthorizedKeysFiles())
|
||||
|
||||
theSSHKeyCheckerFactory = SSHKeyCheckerFactory()
|
||||
|
||||
except ImportError:
|
||||
# if checkers can't be imported, then there should be no SSH cred plugin
|
||||
pass
|
||||
@@ -0,0 +1,184 @@
|
||||
# -*- test-case-name: twisted.test.test_strcred -*-
|
||||
#
|
||||
# Copyright (c) Twisted Matrix Laboratories.
|
||||
# See LICENSE for details.
|
||||
|
||||
"""
|
||||
Cred plugin for UNIX user accounts.
|
||||
"""
|
||||
|
||||
|
||||
from zope.interface import implementer
|
||||
|
||||
from twisted import plugin
|
||||
from twisted.cred.checkers import ICredentialsChecker
|
||||
from twisted.cred.credentials import IUsernamePassword
|
||||
from twisted.cred.error import UnauthorizedLogin
|
||||
from twisted.cred.strcred import ICheckerFactory
|
||||
from twisted.internet import defer
|
||||
|
||||
|
||||
def verifyCryptedPassword(crypted, pw):
|
||||
"""
|
||||
Use L{crypt.crypt} to Verify that an unencrypted
|
||||
password matches the encrypted password.
|
||||
|
||||
@param crypted: The encrypted password, obtained from
|
||||
the Unix password database or Unix shadow
|
||||
password database.
|
||||
@param pw: The unencrypted password.
|
||||
@return: L{True} if there is successful match, else L{False}.
|
||||
@rtype: L{bool}
|
||||
"""
|
||||
try:
|
||||
import crypt
|
||||
except ImportError:
|
||||
crypt = None
|
||||
|
||||
if crypt is None:
|
||||
raise NotImplementedError("cred_unix not supported on this platform")
|
||||
if isinstance(pw, bytes):
|
||||
pw = pw.decode("utf-8")
|
||||
if isinstance(crypted, bytes):
|
||||
crypted = crypted.decode("utf-8")
|
||||
try:
|
||||
crypted_check = crypt.crypt(pw, crypted)
|
||||
if isinstance(crypted_check, bytes):
|
||||
crypted_check = crypted_check.decode("utf-8")
|
||||
return crypted_check == crypted
|
||||
except OSError:
|
||||
return False
|
||||
|
||||
|
||||
@implementer(ICredentialsChecker)
|
||||
class UNIXChecker:
|
||||
"""
|
||||
A credentials checker for a UNIX server. This will check that
|
||||
an authenticating username/password is a valid user on the system.
|
||||
|
||||
Does not work on Windows.
|
||||
|
||||
Right now this supports Python's pwd and spwd modules, if they are
|
||||
installed. It does not support PAM.
|
||||
"""
|
||||
|
||||
credentialInterfaces = (IUsernamePassword,)
|
||||
|
||||
def checkPwd(self, pwd, username, password):
|
||||
"""
|
||||
Obtain the encrypted password for C{username} from the Unix password
|
||||
database using L{pwd.getpwnam}, and see if it it matches it matches
|
||||
C{password}.
|
||||
|
||||
@param pwd: Module which provides functions which
|
||||
access to the Unix password database.
|
||||
@type pwd: C{module}
|
||||
@param username: The user to look up in the Unix password database.
|
||||
@type username: L{unicode}/L{str} or L{bytes}
|
||||
@param password: The password to compare.
|
||||
@type username: L{unicode}/L{str} or L{bytes}
|
||||
"""
|
||||
try:
|
||||
if isinstance(username, bytes):
|
||||
username = username.decode("utf-8")
|
||||
cryptedPass = pwd.getpwnam(username).pw_passwd
|
||||
except KeyError:
|
||||
return defer.fail(UnauthorizedLogin())
|
||||
else:
|
||||
if cryptedPass in ("*", "x"):
|
||||
# Allow checkSpwd to take over
|
||||
return None
|
||||
elif verifyCryptedPassword(cryptedPass, password):
|
||||
return defer.succeed(username)
|
||||
|
||||
def checkSpwd(self, spwd, username, password):
|
||||
"""
|
||||
Obtain the encrypted password for C{username} from the
|
||||
Unix shadow password database using L{spwd.getspnam},
|
||||
and see if it it matches it matches C{password}.
|
||||
|
||||
@param spwd: Module which provides functions which
|
||||
access to the Unix shadow password database.
|
||||
@type spwd: C{module}
|
||||
@param username: The user to look up in the Unix password database.
|
||||
@type username: L{unicode}/L{str} or L{bytes}
|
||||
@param password: The password to compare.
|
||||
@type username: L{unicode}/L{str} or L{bytes}
|
||||
"""
|
||||
try:
|
||||
if isinstance(username, bytes):
|
||||
username = username.decode("utf-8")
|
||||
if getattr(spwd.struct_spwd, "sp_pwdp", None):
|
||||
# Python 3
|
||||
cryptedPass = spwd.getspnam(username).sp_pwdp
|
||||
else:
|
||||
# Python 2
|
||||
cryptedPass = spwd.getspnam(username).sp_pwd
|
||||
except KeyError:
|
||||
return defer.fail(UnauthorizedLogin())
|
||||
else:
|
||||
if verifyCryptedPassword(cryptedPass, password):
|
||||
return defer.succeed(username)
|
||||
|
||||
def requestAvatarId(self, credentials):
|
||||
username, password = credentials.username, credentials.password
|
||||
|
||||
try:
|
||||
import pwd
|
||||
except ImportError:
|
||||
pwd = None
|
||||
|
||||
if pwd is not None:
|
||||
checked = self.checkPwd(pwd, username, password)
|
||||
if checked is not None:
|
||||
return checked
|
||||
|
||||
try:
|
||||
import spwd
|
||||
except ImportError:
|
||||
spwd = None
|
||||
|
||||
if spwd is not None:
|
||||
checked = self.checkSpwd(spwd, username, password)
|
||||
if checked is not None:
|
||||
return checked
|
||||
# TODO: check_pam?
|
||||
# TODO: check_shadow?
|
||||
return defer.fail(UnauthorizedLogin())
|
||||
|
||||
|
||||
unixCheckerFactoryHelp = """
|
||||
This checker will attempt to use every resource available to
|
||||
authenticate against the list of users on the local UNIX system.
|
||||
(This does not support Windows servers for very obvious reasons.)
|
||||
|
||||
Right now, this includes support for:
|
||||
|
||||
* Python's pwd module (which checks /etc/passwd)
|
||||
* Python's spwd module (which checks /etc/shadow)
|
||||
|
||||
Future versions may include support for PAM authentication.
|
||||
"""
|
||||
|
||||
|
||||
@implementer(ICheckerFactory, plugin.IPlugin)
|
||||
class UNIXCheckerFactory:
|
||||
"""
|
||||
A factory for L{UNIXChecker}.
|
||||
"""
|
||||
|
||||
authType = "unix"
|
||||
authHelp = unixCheckerFactoryHelp
|
||||
argStringFormat = "No argstring required."
|
||||
credentialInterfaces = UNIXChecker.credentialInterfaces
|
||||
|
||||
def generateChecker(self, argstring):
|
||||
"""
|
||||
This checker factory ignores the argument string. Everything
|
||||
needed to generate a user database is pulled out of the local
|
||||
UNIX environment.
|
||||
"""
|
||||
return UNIXChecker()
|
||||
|
||||
|
||||
theUnixCheckerFactory = UNIXCheckerFactory()
|
||||
@@ -0,0 +1,24 @@
|
||||
import socket
|
||||
|
||||
from twisted.internet import endpoints
|
||||
from twisted.internet.interfaces import IStreamServerEndpointStringParser
|
||||
from twisted.plugin import IPlugin
|
||||
from zope.interface import implementer
|
||||
|
||||
|
||||
@implementer(IPlugin, IStreamServerEndpointStringParser)
|
||||
class _FDParser:
|
||||
prefix = "fd"
|
||||
|
||||
def _parseServer(self, reactor, fileno, domain=socket.AF_INET):
|
||||
fileno = int(fileno)
|
||||
return endpoints.AdoptedStreamServerEndpoint(reactor, fileno, domain)
|
||||
|
||||
def parseStreamServer(self, reactor, *args, **kwargs):
|
||||
# Delegate to another function with a sane signature. This function has
|
||||
# an insane signature to trick zope.interface into believing the
|
||||
# interface is correctly implemented.
|
||||
return self._parseServer(reactor, *args, **kwargs)
|
||||
|
||||
|
||||
parser = _FDParser()
|
||||
@@ -0,0 +1,19 @@
|
||||
# Copyright (c) Twisted Matrix Laboratories.
|
||||
# See LICENSE for details.
|
||||
|
||||
from twisted.application.service import ServiceMaker
|
||||
|
||||
TwistedSSH = ServiceMaker(
|
||||
"Twisted Conch Server", "twisted.conch.tap", "A Conch SSH service.", "conch"
|
||||
)
|
||||
|
||||
TwistedManhole = ServiceMaker(
|
||||
"Twisted Manhole (new)",
|
||||
"twisted.conch.manhole_tap",
|
||||
(
|
||||
"An interactive remote debugger service accessible via telnet "
|
||||
"and ssh and providing syntax coloring and basic line editing "
|
||||
"functionality."
|
||||
),
|
||||
"manhole",
|
||||
)
|
||||
@@ -0,0 +1,19 @@
|
||||
# Copyright (c) Twisted Matrix Laboratories.
|
||||
# See LICENSE for details.
|
||||
|
||||
|
||||
from twisted.internet.endpoints import (
|
||||
_StandardIOParser,
|
||||
_SystemdParser,
|
||||
_TCP6ServerParser,
|
||||
_TLSClientEndpointParser,
|
||||
)
|
||||
from twisted.protocols.haproxy._parser import (
|
||||
HAProxyServerParser as _HAProxyServerParser,
|
||||
)
|
||||
|
||||
systemdEndpointParser = _SystemdParser()
|
||||
tcp6ServerEndpointParser = _TCP6ServerParser()
|
||||
stdioEndpointParser = _StandardIOParser()
|
||||
tlsClientEndpointParser = _TLSClientEndpointParser()
|
||||
_haProxyServerEndpointParser = _HAProxyServerParser()
|
||||
@@ -0,0 +1,6 @@
|
||||
# Copyright (c) Twisted Matrix Laboratories.
|
||||
# See LICENSE for details.
|
||||
|
||||
from twisted.application.service import ServiceMaker
|
||||
|
||||
TwistedFTP = ServiceMaker("Twisted FTP", "twisted.tap.ftp", "An FTP server.", "ftp")
|
||||
@@ -0,0 +1,11 @@
|
||||
# Copyright (c) Twisted Matrix Laboratories.
|
||||
# See LICENSE for details.
|
||||
|
||||
from twisted.application.service import ServiceMaker
|
||||
|
||||
TwistedINETD = ServiceMaker(
|
||||
"Twisted INETD Server",
|
||||
"twisted.runner.inetdtap",
|
||||
"An inetd(8) replacement.",
|
||||
"inetd",
|
||||
)
|
||||
@@ -0,0 +1,8 @@
|
||||
# Copyright (c) Twisted Matrix Laboratories.
|
||||
# See LICENSE for details.
|
||||
|
||||
from twisted.application.service import ServiceMaker
|
||||
|
||||
TwistedMail = ServiceMaker(
|
||||
"Twisted Mail", "twisted.mail.tap", "An email service", "mail"
|
||||
)
|
||||
@@ -0,0 +1,8 @@
|
||||
# Copyright (c) Twisted Matrix Laboratories.
|
||||
# See LICENSE for details.
|
||||
|
||||
from twisted.application.service import ServiceMaker
|
||||
|
||||
TwistedNames = ServiceMaker(
|
||||
"Twisted DNS Server", "twisted.names.tap", "A domain name server.", "dns"
|
||||
)
|
||||
@@ -0,0 +1,11 @@
|
||||
# Copyright (c) Twisted Matrix Laboratories.
|
||||
# See LICENSE for details.
|
||||
|
||||
from twisted.application.service import ServiceMaker
|
||||
|
||||
TwistedPortForward = ServiceMaker(
|
||||
"Twisted Port-Forwarding",
|
||||
"twisted.tap.portforward",
|
||||
"A simple port-forwarder.",
|
||||
"portforward",
|
||||
)
|
||||
@@ -0,0 +1,59 @@
|
||||
# Copyright (c) Twisted Matrix Laboratories.
|
||||
# See LICENSE for details.
|
||||
|
||||
|
||||
from twisted.application.reactors import Reactor
|
||||
|
||||
__all__ = []
|
||||
|
||||
default = Reactor(
|
||||
"default",
|
||||
"twisted.internet.default",
|
||||
"A reasonable default: poll(2) if available, otherwise select(2).",
|
||||
)
|
||||
__all__.append("default")
|
||||
|
||||
select = Reactor("select", "twisted.internet.selectreactor", "select(2) based reactor.")
|
||||
__all__.append("select")
|
||||
|
||||
poll = Reactor("poll", "twisted.internet.pollreactor", "poll(2) based reactor.")
|
||||
__all__.append("poll")
|
||||
|
||||
epoll = Reactor("epoll", "twisted.internet.epollreactor", "epoll(4) based reactor.")
|
||||
__all__.append("epoll")
|
||||
|
||||
kqueue = Reactor("kqueue", "twisted.internet.kqreactor", "kqueue(2) based reactor.")
|
||||
__all__.append("kqueue")
|
||||
|
||||
cf = Reactor("cf", "twisted.internet.cfreactor", "CoreFoundation based reactor.")
|
||||
__all__.append("cf")
|
||||
|
||||
asyncio = Reactor("asyncio", "twisted.internet.asyncioreactor", "asyncio based reactor")
|
||||
__all__.append("asyncio")
|
||||
|
||||
wx = Reactor("wx", "twisted.internet.wxreactor", "wxPython based reactor.")
|
||||
__all__.append("wx")
|
||||
|
||||
gi = Reactor("gi", "twisted.internet.gireactor", "GObject Introspection based reactor.")
|
||||
__all__.append("gi")
|
||||
|
||||
gtk3 = Reactor("gtk3", "twisted.internet.gtk3reactor", "Gtk3 based reactor.")
|
||||
__all__.append("gtk3")
|
||||
|
||||
gtk2 = Reactor("gtk2", "twisted.internet.gtk2reactor", "Gtk2 based reactor.")
|
||||
__all__.append("gtk2")
|
||||
|
||||
glib2 = Reactor("glib2", "twisted.internet.glib2reactor", "GLib2 based reactor.")
|
||||
__all__.append("glib2")
|
||||
|
||||
win32er = Reactor(
|
||||
"win32",
|
||||
"twisted.internet.win32eventreactor",
|
||||
"Win32 WaitForMultipleObjects based reactor.",
|
||||
)
|
||||
__all__.append("win32er")
|
||||
|
||||
iocp = Reactor(
|
||||
"iocp", "twisted.internet.iocpreactor", "Win32 IO Completion Ports based reactor."
|
||||
)
|
||||
__all__.append("iocp")
|
||||
@@ -0,0 +1,11 @@
|
||||
# Copyright (c) Twisted Matrix Laboratories.
|
||||
# See LICENSE for details.
|
||||
|
||||
from twisted.application.service import ServiceMaker
|
||||
|
||||
TwistedProcmon = ServiceMaker(
|
||||
"Twisted Process Monitor",
|
||||
"twisted.runner.procmontap",
|
||||
("A process watchdog / supervisor"),
|
||||
"procmon",
|
||||
)
|
||||
@@ -0,0 +1,8 @@
|
||||
# Copyright (c) Twisted Matrix Laboratories.
|
||||
# See LICENSE for details.
|
||||
|
||||
from twisted.application.service import ServiceMaker
|
||||
|
||||
TwistedSOCKS = ServiceMaker(
|
||||
"Twisted SOCKS", "twisted.tap.socks", "A SOCKSv4 proxy service.", "socks"
|
||||
)
|
||||
@@ -0,0 +1,172 @@
|
||||
from zope.interface import implementer
|
||||
|
||||
from twisted.plugin import IPlugin
|
||||
from twisted.trial.itrial import IReporter
|
||||
|
||||
|
||||
@implementer(IPlugin, IReporter)
|
||||
class _Reporter:
|
||||
def __init__(self, name, module, description, longOpt, shortOpt, klass):
|
||||
self.name = name
|
||||
self.module = module
|
||||
self.description = description
|
||||
self.longOpt = longOpt
|
||||
self.shortOpt = shortOpt
|
||||
self.klass = klass
|
||||
|
||||
@property
|
||||
def stream(self):
|
||||
# IReporter.stream
|
||||
pass
|
||||
|
||||
@property
|
||||
def tbformat(self):
|
||||
# IReporter.tbformat
|
||||
pass
|
||||
|
||||
@property
|
||||
def args(self):
|
||||
# IReporter.args
|
||||
pass
|
||||
|
||||
@property
|
||||
def shouldStop(self):
|
||||
# IReporter.shouldStop
|
||||
pass
|
||||
|
||||
@property
|
||||
def separator(self):
|
||||
# IReporter.separator
|
||||
pass
|
||||
|
||||
@property
|
||||
def testsRun(self):
|
||||
# IReporter.testsRun
|
||||
pass
|
||||
|
||||
def addError(self, test, error):
|
||||
# IReporter.addError
|
||||
pass
|
||||
|
||||
def addExpectedFailure(self, test, failure, todo=None):
|
||||
# IReporter.addExpectedFailure
|
||||
pass
|
||||
|
||||
def addFailure(self, test, failure):
|
||||
# IReporter.addFailure
|
||||
pass
|
||||
|
||||
def addSkip(self, test, reason):
|
||||
# IReporter.addSkip
|
||||
pass
|
||||
|
||||
def addSuccess(self, test):
|
||||
# IReporter.addSuccess
|
||||
pass
|
||||
|
||||
def addUnexpectedSuccess(self, test, todo=None):
|
||||
# IReporter.addUnexpectedSuccess
|
||||
pass
|
||||
|
||||
def cleanupErrors(self, errs):
|
||||
# IReporter.cleanupErrors
|
||||
pass
|
||||
|
||||
def done(self):
|
||||
# IReporter.done
|
||||
pass
|
||||
|
||||
def endSuite(self, name):
|
||||
# IReporter.endSuite
|
||||
pass
|
||||
|
||||
def printErrors(self):
|
||||
# IReporter.printErrors
|
||||
pass
|
||||
|
||||
def printSummary(self):
|
||||
# IReporter.printSummary
|
||||
pass
|
||||
|
||||
def startSuite(self, name):
|
||||
# IReporter.startSuite
|
||||
pass
|
||||
|
||||
def startTest(self, method):
|
||||
# IReporter.startTest
|
||||
pass
|
||||
|
||||
def stopTest(self, method):
|
||||
# IReporter.stopTest
|
||||
pass
|
||||
|
||||
def upDownError(self, userMeth, warn=True, printStatus=True):
|
||||
# IReporter.upDownError
|
||||
pass
|
||||
|
||||
def wasSuccessful(self):
|
||||
# IReporter.wasSuccessful
|
||||
pass
|
||||
|
||||
def write(self, string):
|
||||
# IReporter.write
|
||||
pass
|
||||
|
||||
def writeln(self, string):
|
||||
# IReporter.writeln
|
||||
pass
|
||||
|
||||
|
||||
Tree = _Reporter(
|
||||
"Tree Reporter",
|
||||
"twisted.trial.reporter",
|
||||
description="verbose color output (default reporter)",
|
||||
longOpt="verbose",
|
||||
shortOpt="v",
|
||||
klass="TreeReporter",
|
||||
)
|
||||
|
||||
BlackAndWhite = _Reporter(
|
||||
"Black-And-White Reporter",
|
||||
"twisted.trial.reporter",
|
||||
description="Colorless verbose output",
|
||||
longOpt="bwverbose",
|
||||
shortOpt="o",
|
||||
klass="VerboseTextReporter",
|
||||
)
|
||||
|
||||
Minimal = _Reporter(
|
||||
"Minimal Reporter",
|
||||
"twisted.trial.reporter",
|
||||
description="minimal summary output",
|
||||
longOpt="summary",
|
||||
shortOpt="s",
|
||||
klass="MinimalReporter",
|
||||
)
|
||||
|
||||
Classic = _Reporter(
|
||||
"Classic Reporter",
|
||||
"twisted.trial.reporter",
|
||||
description="terse text output",
|
||||
longOpt="text",
|
||||
shortOpt="t",
|
||||
klass="TextReporter",
|
||||
)
|
||||
|
||||
Timing = _Reporter(
|
||||
"Timing Reporter",
|
||||
"twisted.trial.reporter",
|
||||
description="Timing output",
|
||||
longOpt="timing",
|
||||
shortOpt=None,
|
||||
klass="TimingTextReporter",
|
||||
)
|
||||
|
||||
Subunit = _Reporter(
|
||||
"Subunit Reporter",
|
||||
"twisted.trial.reporter",
|
||||
description="subunit output",
|
||||
longOpt="subunit",
|
||||
shortOpt=None,
|
||||
klass="SubunitReporter",
|
||||
)
|
||||
@@ -0,0 +1,14 @@
|
||||
# Copyright (c) Twisted Matrix Laboratories.
|
||||
# See LICENSE for details.
|
||||
|
||||
from twisted.application.service import ServiceMaker
|
||||
|
||||
TwistedWeb = ServiceMaker(
|
||||
"Twisted Web",
|
||||
"twisted.web.tap",
|
||||
(
|
||||
"A general-purpose web server which can serve from a "
|
||||
"filesystem or application resource."
|
||||
),
|
||||
"web",
|
||||
)
|
||||
@@ -0,0 +1,38 @@
|
||||
# Copyright (c) Twisted Matrix Laboratories.
|
||||
# See LICENSE for details.
|
||||
|
||||
from zope.interface import provider
|
||||
|
||||
from twisted.application.service import ServiceMaker
|
||||
from twisted.plugin import IPlugin
|
||||
from twisted.words import iwords
|
||||
|
||||
NewTwistedWords = ServiceMaker(
|
||||
"New Twisted Words", "twisted.words.tap", "A modern words server", "words"
|
||||
)
|
||||
|
||||
TwistedXMPPRouter = ServiceMaker(
|
||||
"XMPP Router", "twisted.words.xmpproutertap", "An XMPP Router server", "xmpp-router"
|
||||
)
|
||||
|
||||
|
||||
@provider(IPlugin, iwords.IProtocolPlugin)
|
||||
class RelayChatInterface:
|
||||
name = "irc"
|
||||
|
||||
@classmethod
|
||||
def getFactory(cls, realm, portal):
|
||||
from twisted.words import service
|
||||
|
||||
return service.IRCFactory(realm, portal)
|
||||
|
||||
|
||||
@provider(IPlugin, iwords.IProtocolPlugin)
|
||||
class PBChatInterface:
|
||||
name = "pb"
|
||||
|
||||
@classmethod
|
||||
def getFactory(cls, realm, portal):
|
||||
from twisted.spread import pb
|
||||
|
||||
return pb.PBServerFactory(portal, True)
|
||||
Reference in New Issue
Block a user