1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 """helper classes for creating a twisted server
23 """
24
25 import os
26
27 from twisted.internet import reactor
28 from zope.interface import Interface
29
30 from flumotion.common import log
31
32 __version__ = "$Rev: 6964 $"
33
34
35 -class _ServerContextFactory(log.Loggable):
36
37 logCategory = "SSLServer"
38
39 - def __init__(self, pemFile):
40 self._pemFile = pemFile
41
42 - def getContext(self):
43 """
44 Create an SSL context.
45 """
46 from OpenSSL import SSL
47 ctx = SSL.Context(SSL.SSLv23_METHOD)
48 try:
49 ctx.use_certificate_file(self._pemFile)
50 ctx.use_privatekey_file(self._pemFile)
51 except SSL.Error, e:
52 self.warning('SSL error: %r' % e.args)
53 self.error('Could not open certificate %s' % self._pemFile)
54 return ctx
55
56
58 """
59 I am an interface for objects that want to be servable through a
60 L{Server}.
61 """
63 """
64 @rtype: L{twisted.spread.pb.PBServerFactory}
65 """
66
68 """
69 @param host: the host to listen as
70 @type host: str
71 @param port: the port to listen on
72 @type port: int
73 @param useSSL: whether this connection uses SSL
74 @type useSSL: bool
75 """
76
78 logCategory = "server"
79
81 """
82 I expose a servable to the network using TCP or SSL.
83
84 @type servable: an implemtor of L{IServable}
85 """
86 self._servable = servable
87
88 - def startSSL(self, host, port, pemFile, configDir):
89 """
90 Listen as the given host and on the given port using SSL.
91 Use the given .pem file, or look for it in the config directory.
92
93 @param pemFile: File containing the SSL certificate.
94 If it's a full path, respects the full path.
95 If not, looks in configDir for this file.
96 @param configDir: directory where .pem file is stored
97 @returns: {twisted.internet.interfaces.IListeningPort} on which
98 we are listening; call .stopListening() to stop.
99 """
100 from flumotion.common import common
101 common.assertSSLAvailable()
102
103
104 if not os.path.split(pemFile)[0]:
105 pemFile = os.path.join(configDir, pemFile)
106 if not os.path.exists(pemFile):
107 self.error(".pem file %s does not exist.\n" \
108 "For more information, see \n" \
109 "http://www.flumotion.net/doc/flumotion/manual/html/" \
110 "chapter-security.html" % pemFile)
111 log.debug('manager', 'Using PEM certificate file %s' % pemFile)
112 ctxFactory = _ServerContextFactory(pemFile)
113
114 self.info('Starting on port %d using SSL' % port)
115 if not host == "":
116 self.info('Listening as host %s' % host)
117 self._servable.setConnectionInfo(host, port, True)
118 return reactor.listenSSL(port, self._servable.getFactory(),
119 ctxFactory, interface=host)
120
122 """
123 Listen as the given host and on the given port using normal TCP.
124
125 @returns: {twisted.internet.interfaces.IListeningPort} on which
126 we are listening; call .stopListening() to stop.
127 """
128 self.info('Starting on port %d using TCP' % port)
129 if not host == "":
130 self.info('Listening as host %s' % host)
131 self._servable.setConnectionInfo(host, port, False)
132 return reactor.listenTCP(port, self._servable.getFactory(),
133 interface=host)
134