1
# Copyright (c) 2001-2008 Twisted Matrix Laboratories.
2
# See LICENSE for details.
5
A Factory for SSH servers, along with an OpenSSHFactory to use the same
6
data sources as OpenSSH.
8
Maintainer: Paul Swartz
16
from twisted.internet import protocol
17
from twisted.python import log
18
from twisted.python.reflect import qual
20
from twisted.conch import error
21
from twisted.conch.ssh import keys
22
import transport, userauth, connection
27
class SSHFactory(protocol.Factory):
29
protocol = transport.SSHServerTransport
32
'ssh-userauth':userauth.SSHUserAuthServer,
33
'ssh-connection':connection.SSHConnection
35
def startFactory(self):
38
resource.setrlimit(resource.RLIMIT_CORE, (0,0))
40
log.msg('INSECURE: unable to disable core dumps.')
41
if not hasattr(self,'publicKeys'):
42
self.publicKeys = self.getPublicKeys()
43
for keyType, value in self.publicKeys.items():
44
if isinstance(value, str):
45
warnings.warn("Returning a mapping from strings to "
46
"strings from getPublicKeys()/publicKeys (in %s) "
47
"is deprecated. Return a mapping from "
48
"strings to Key objects instead." %
49
(qual(self.__class__)),
50
DeprecationWarning, stacklevel=1)
51
self.publicKeys[keyType] = keys.Key.fromString(value)
52
if not hasattr(self,'privateKeys'):
53
self.privateKeys = self.getPrivateKeys()
54
for keyType, value in self.privateKeys.items():
55
if not isinstance(value, keys.Key):
56
warnings.warn("Returning a mapping from strings to "
57
"PyCrypto key objects from "
58
"getPrivateKeys()/privateKeys (in %s) "
59
"is deprecated. Return a mapping from "
60
"strings to Key objects instead." %
61
(qual(self.__class__),),
62
DeprecationWarning, stacklevel=1)
63
self.privateKeys[keyType] = keys.Key(value)
64
if not self.publicKeys or not self.privateKeys:
65
raise error.ConchError('no host keys, failing')
66
if not hasattr(self,'primes'):
67
self.primes = self.getPrimes()
69
def buildProtocol(self, addr):
70
t = protocol.Factory.buildProtocol(self, addr)
71
t.supportedPublicKeys = self.privateKeys.keys()
73
log.msg('disabling diffie-hellman-group-exchange because we '
74
'cannot find moduli file')
75
ske = t.supportedKeyExchanges[:]
76
ske.remove('diffie-hellman-group-exchange-sha1')
77
t.supportedKeyExchanges = ske
80
def getPublicKeys(self):
82
Called when the factory is started to get the public portions of the
83
servers host keys. Returns a dictionary mapping SSH key types to
88
raise NotImplementedError('getPublicKeys unimplemented')
90
def getPrivateKeys(self):
92
Called when the factory is started to get the private portions of the
93
servers host keys. Returns a dictionary mapping SSH key types to
94
C{Crypto.PublicKey.pubkey.pubkey} objects.
98
raise NotImplementedError('getPrivateKeys unimplemented')
102
Called when the factory is started to get Diffie-Hellman generators and
103
primes to use. Returns a dictionary mapping number of bits to lists
104
of tuple of (generator, prime).
109
def getDHPrime(self, bits):
111
Return a tuple of (g, p) for a Diffe-Hellman process, with p being as
112
close to bits bits as possible.
117
primesKeys = self.primes.keys()
118
primesKeys.sort(lambda x, y: cmp(abs(x - bits), abs(y - bits)))
119
realBits = primesKeys[0]
120
return random.choice(self.primes[realBits])
122
def getService(self, transport, service):
124
Return a class to use as a service for the given transport.
126
@type transport: L{transport.SSHServerTransport}
127
@type service: C{str}
128
@rtype: subclass of L{service.SSHService}
130
if service == 'ssh-userauth' or hasattr(transport, 'avatar'):
131
return self.services[service]