Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100755 166 lines (127 sloc) 5.21 kb
cd5e58b @moxie0 Initial commit.
authored
1 #!/usr/bin/env python
2 """notary implements the Convergence Notary System."""
3
4 __author__ = "Moxie Marlinspike"
5 __email__ = "moxie@thoughtcrime.org"
6 __license__= """
7 Copyright (c) 2010 Moxie Marlinspike <moxie@thoughtcrime.org>
8
9 This program is free software; you can redistribute it and/or
10 modify it under the terms of the GNU General Public License as
11 published by the Free Software Foundation; either version 3 of the
12 License, or (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
22 USA
23
24 """
25
26 from twisted.internet import epollreactor
27 epollreactor.install()
28
29 from convergence.TargetPage import TargetPage
30 from convergence.ConnectChannel import ConnectChannel
31 from convergence.ConnectRequest import ConnectRequest
32
33
34 from OpenSSL import SSL
35 from twisted.enterprise import adbapi
36 from twisted.web import http
37 from twisted.web.server import Site
38 from twisted.web.resource import Resource
39 from twisted.internet import reactor
40
41 import sys, string, os, getopt, logging, pwd, grp, convergence.daemonize
42
43 gVersion = "0.01"
44
45 class ServerContextFactory:
46
47 def __init__(self, cert, key):
48 self.cert = cert
49 self.key = key
50
51 def getContext(self):
52 ctx = SSL.Context(SSL.SSLv3_METHOD)
53 ctx.use_certificate_chain_file(self.cert)
54 ctx.use_privatekey_file(self.key)
55
56 return ctx
57
58 def parseOptions(argv):
59 logLevel = logging.INFO
60 httpPort = 80
61 sslPort = 443
62 certFile = "/etc/ssl/certs/convergence.pem"
63 keyFile = "/etc/ssl/private/convergence.key"
64 background = True
65
66 try:
67 opts, args = getopt.getopt(argv, "s:p:c:k:fdh")
68
69 for opt, arg in opts:
70 if opt in("-p"):
71 httpPort = int(arg)
72 elif opt in ("-s"):
73 sslPort = int(arg)
74 elif opt in ("-c"):
75 certFile = arg
76 elif opt in ("-k"):
77 keyFile = arg
78 elif opt in ("-d"):
79 logLevel = logging.DEBUG
80 elif opt in ("-f"):
81 background = False
82 elif opt in ("-h"):
83 usage()
84 sys.exit()
85
86 return (logLevel, sslPort, httpPort,
87 certFile, keyFile, background)
88
89 except getopt.GetoptError:
90 usage()
91 sys.exit(2)
92
93 def usage():
94 print "\nnotary " + str(gVersion) + " by Moxie Marlinspike"
95 print "usage: notary <options>\n"
96 print "Options:"
97 print "-p <http_port> HTTP port to listen on."
98 print "-s <ssl_port> SSL port to listen on."
99 print "-c <cert> SSL certificate location."
100 print "-k <key> SSL private key location."
101 print "-f Run in foreground."
102 print "-d Debug mode."
103 print "-h Print this help message."
104 print ""
105
106 def writePidFile():
107 pidFile = open("/var/run/convergence.pid", "wb")
108 pidFile.write(str(os.getpid()))
109 pidFile.close()
110
111 def dropPrivileges():
112 nobody = pwd.getpwnam('nobody')
113 adm = grp.getgrnam('nogroup')
114
115 os.setgroups([adm.gr_gid])
116 os.setgid(adm.gr_gid)
117 os.setuid(nobody.pw_uid)
118
119 def initializeLogging(logLevel):
120 logging.basicConfig(filename="/var/log/convergence.log",level=logLevel,
121 format='%(asctime)s %(message)s',filemode='a')
122
123 logging.info("Convergence Notary started...")
124
125 def initializeFactory(database, privateKey):
126 root = Resource()
127 root.putChild("target", TargetPage(database, privateKey))
128
129 return Site(root)
130
131 def initializeDatabase():
132 return adbapi.ConnectionPool("sqlite3", '/var/lib/convergence/convergence.db', cp_max=1, cp_min=1)
133
134 def initializeKey(keyFile):
135 return open(keyFile,'r').read()
136
137 def main(argv):
138 (logLevel, sslPort, httpPort,
139 certFile, keyFile, background) = parseOptions(argv)
140 privateKey = initializeKey(keyFile)
141 database = initializeDatabase()
142 sslFactory = initializeFactory(database, privateKey)
143 connectFactory = http.HTTPFactory(timeout=10)
144 connectFactory.protocol = ConnectChannel
145
146 reactor.listenSSL(sslPort, sslFactory, ServerContextFactory(certFile, keyFile))
147 reactor.listenSSL(4242, sslFactory, ServerContextFactory(certFile, keyFile))
148 reactor.listenTCP(port=httpPort, factory=connectFactory)
149
150
151 initializeLogging(logLevel)
152
153 if background:
154 print "\nconvergence " + str(gVersion) + " by Moxie Marlinspike backgrounding..."
155 convergence.daemonize.createDaemon()
156 else:
157 print "\nconvergence " + str(gVersion) + " by Moxie Marlinspike running..."
158
159 writePidFile()
160 # dropPrivileges()
161
162 reactor.run()
163
164 if __name__ == '__main__':
165 main(sys.argv[1:])
Something went wrong with that request. Please try again.