root/trunk/twisted/conch/ssh/factory.py

Revision 30752, 4.8 KB (checked in by exarkun, 15 months ago)

Rewrite the copyright headers to exclude date information.

Author: exarkun
Reviewer: glyph
Fixes: #4857

To avoid the need to perpetually update copyright dates in each file in Twisted,
remove the dates from most files and just leave them in the LICENSE file.

As a side effect, some files also have had a trailing newline added where it was
missing before.

Line 
1# Copyright (c) Twisted Matrix Laboratories.
2# See LICENSE for details.
3
4"""
5A Factory for SSH servers, along with an OpenSSHFactory to use the same
6data sources as OpenSSH.
7
8Maintainer: Paul Swartz
9"""
10
11from twisted.internet import protocol
12from twisted.python import log
13from twisted.python.reflect import qual
14
15from twisted.conch import error
16from twisted.conch.ssh import keys
17import transport, userauth, connection
18
19import random
20import warnings
21
22class SSHFactory(protocol.Factory):
23    """
24    A Factory for SSH servers.
25    """
26    protocol = transport.SSHServerTransport
27
28    services = {
29        'ssh-userauth':userauth.SSHUserAuthServer,
30        'ssh-connection':connection.SSHConnection
31    }
32    def startFactory(self):
33        """
34        Check for public and private keys.
35        """
36        if not hasattr(self,'publicKeys'):
37            self.publicKeys = self.getPublicKeys()
38        for keyType, value in self.publicKeys.items():
39            if isinstance(value, str):
40                warnings.warn("Returning a mapping from strings to "
41                        "strings from getPublicKeys()/publicKeys (in %s) "
42                        "is deprecated.  Return a mapping from "
43                        "strings to Key objects instead." %
44                        (qual(self.__class__)),
45                        DeprecationWarning, stacklevel=1)
46                self.publicKeys[keyType] = keys.Key.fromString(value)
47        if not hasattr(self,'privateKeys'):
48            self.privateKeys = self.getPrivateKeys()
49        for keyType, value in self.privateKeys.items():
50            if not isinstance(value, keys.Key):
51                warnings.warn("Returning a mapping from strings to "
52                        "PyCrypto key objects from "
53                        "getPrivateKeys()/privateKeys (in %s) "
54                        "is deprecated.  Return a mapping from "
55                        "strings to Key objects instead." %
56                        (qual(self.__class__),),
57                        DeprecationWarning, stacklevel=1)
58                self.privateKeys[keyType] = keys.Key(value)
59        if not self.publicKeys or not self.privateKeys:
60            raise error.ConchError('no host keys, failing')
61        if not hasattr(self,'primes'):
62            self.primes = self.getPrimes()
63
64
65    def buildProtocol(self, addr):
66        """
67        Create an instance of the server side of the SSH protocol.
68
69        @type addr: L{twisted.internet.interfaces.IAddress} provider
70        @param addr: The address at which the server will listen.
71
72        @rtype: L{twisted.conch.ssh.SSHServerTransport}
73        @return: The built transport.
74        """
75        t = protocol.Factory.buildProtocol(self, addr)
76        t.supportedPublicKeys = self.privateKeys.keys()
77        if not self.primes:
78            log.msg('disabling diffie-hellman-group-exchange because we '
79                    'cannot find moduli file')
80            ske = t.supportedKeyExchanges[:]
81            ske.remove('diffie-hellman-group-exchange-sha1')
82            t.supportedKeyExchanges = ske
83        return t
84
85
86    def getPublicKeys(self):
87        """
88        Called when the factory is started to get the public portions of the
89        servers host keys.  Returns a dictionary mapping SSH key types to
90        public key strings.
91
92        @rtype: C{dict}
93        """
94        raise NotImplementedError('getPublicKeys unimplemented')
95
96
97    def getPrivateKeys(self):
98        """
99        Called when the factory is started to get the  private portions of the
100        servers host keys.  Returns a dictionary mapping SSH key types to
101        C{Crypto.PublicKey.pubkey.pubkey} objects.
102
103        @rtype: C{dict}
104        """
105        raise NotImplementedError('getPrivateKeys unimplemented')
106
107
108    def getPrimes(self):
109        """
110        Called when the factory is started to get Diffie-Hellman generators and
111        primes to use.  Returns a dictionary mapping number of bits to lists
112        of tuple of (generator, prime).
113
114        @rtype: C{dict}
115        """
116
117
118    def getDHPrime(self, bits):
119        """
120        Return a tuple of (g, p) for a Diffe-Hellman process, with p being as
121        close to bits bits as possible.
122
123        @type bits: C{int}
124        @rtype:     C{tuple}
125        """
126        primesKeys = self.primes.keys()
127        primesKeys.sort(lambda x, y: cmp(abs(x - bits), abs(y - bits)))
128        realBits = primesKeys[0]
129        return random.choice(self.primes[realBits])
130
131
132    def getService(self, transport, service):
133        """
134        Return a class to use as a service for the given transport.
135
136        @type transport:    L{transport.SSHServerTransport}
137        @type service:      C{str}
138        @rtype:             subclass of L{service.SSHService}
139        """
140        if service == 'ssh-userauth' or hasattr(transport, 'avatar'):
141            return self.services[service]
Note: See TracBrowser for help on using the browser.