Initial import to Tizen
[profile/ivi/python-twisted.git] / twisted / conch / ssh / factory.py
1 # Copyright (c) Twisted Matrix Laboratories.
2 # See LICENSE for details.
3
4 """
5 A Factory for SSH servers, along with an OpenSSHFactory to use the same
6 data sources as OpenSSH.
7
8 Maintainer: Paul Swartz
9 """
10
11 from twisted.internet import protocol
12 from twisted.python import log
13 from twisted.python.reflect import qual
14
15 from twisted.conch import error
16 from twisted.conch.ssh import keys
17 import transport, userauth, connection
18
19 import random
20 import warnings
21
22 class 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]