setup.py 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. import os, sys
  2. from distutils.core import setup, Extension
  3. from distutils.sysconfig import get_python_lib
  4. from distutils.cmd import Command
  5. from distutils.command.build import build
  6. if (sys.version_info >= (2, 6, 0)):
  7. sys.stderr.write("Skipping building ssl-1.15 because" +
  8. "it is a built-in module in Python" +
  9. "2.6 and later.\n")
  10. sys.exit(0)
  11. elif (sys.version_info < (2, 3, 5)):
  12. sys.stderr.write("Warning: This code has not been tested "
  13. + "with versions of Python less than 2.3.5.\n")
  14. class Test (Command):
  15. user_options = []
  16. def initialize_options(self):
  17. pass
  18. def finalize_options(self):
  19. pass
  20. def run (self):
  21. """Run the regrtest module appropriately"""
  22. # figure out where the _ssl2 extension will be put
  23. b = build(self.distribution)
  24. b.initialize_options()
  25. b.finalize_options()
  26. extdir = os.path.abspath(b.build_platlib)
  27. # now set up the load path
  28. topdir = os.path.dirname(os.path.abspath(__file__))
  29. localtestdir = os.path.join(topdir, "test")
  30. sys.path.insert(0, topdir) # for ssl package
  31. sys.path.insert(0, localtestdir) # for test module
  32. sys.path.insert(0, extdir) # for _ssl2 extension
  33. # make sure the network is enabled
  34. import test.test_support
  35. test.test_support.use_resources = ["network"]
  36. # and load the test and run it
  37. os.chdir(localtestdir)
  38. the_module = __import__("test_ssl", globals(), locals(), [])
  39. # Most tests run to completion simply as a side-effect of
  40. # being imported. For the benefit of tests that can't run
  41. # that way (like test_threaded_import), explicitly invoke
  42. # their test_main() function (if it exists).
  43. indirect_test = getattr(the_module, "test_main", None)
  44. if indirect_test is not None:
  45. indirect_test()
  46. def find_file(filename, std_dirs, paths):
  47. """Searches for the directory where a given file is located,
  48. and returns a possibly-empty list of additional directories, or None
  49. if the file couldn't be found at all.
  50. 'filename' is the name of a file, such as readline.h or libcrypto.a.
  51. 'std_dirs' is the list of standard system directories; if the
  52. file is found in one of them, no additional directives are needed.
  53. 'paths' is a list of additional locations to check; if the file is
  54. found in one of them, the resulting list will contain the directory.
  55. """
  56. # Check the standard locations
  57. for dir in std_dirs:
  58. f = os.path.join(dir, filename)
  59. print 'looking for', f
  60. if os.path.exists(f): return []
  61. # Check the additional directories
  62. for dir in paths:
  63. f = os.path.join(dir, filename)
  64. print 'looking for', f
  65. if os.path.exists(f):
  66. return [dir]
  67. # Not found anywhere
  68. return None
  69. def find_library_file(compiler, libname, std_dirs, paths):
  70. result = compiler.find_library_file(std_dirs + paths, libname)
  71. if result is None:
  72. return None
  73. # Check whether the found file is in one of the standard directories
  74. dirname = os.path.dirname(result)
  75. for p in std_dirs:
  76. # Ensure path doesn't end with path separator
  77. p = p.rstrip(os.sep)
  78. if p == dirname:
  79. return [ ]
  80. # Otherwise, it must have been in one of the additional directories,
  81. # so we have to figure out which one.
  82. for p in paths:
  83. # Ensure path doesn't end with path separator
  84. p = p.rstrip(os.sep)
  85. if p == dirname:
  86. return [p]
  87. else:
  88. assert False, "Internal error: Path not found in std_dirs or paths"
  89. def find_ssl():
  90. # Detect SSL support for the socket module (via _ssl)
  91. from distutils.ccompiler import new_compiler
  92. compiler = new_compiler()
  93. inc_dirs = compiler.include_dirs + ['/usr/include']
  94. search_for_ssl_incs_in = [
  95. '/usr/local/ssl/include',
  96. '/usr/contrib/ssl/include/'
  97. ]
  98. ssl_incs = find_file('openssl/ssl.h', inc_dirs,
  99. search_for_ssl_incs_in
  100. )
  101. if ssl_incs is not None:
  102. krb5_h = find_file('krb5.h', inc_dirs,
  103. ['/usr/kerberos/include'])
  104. if krb5_h:
  105. ssl_incs += krb5_h
  106. ssl_libs = find_library_file(compiler, 'ssl',
  107. ['/usr/lib'],
  108. ['/usr/local/lib',
  109. '/usr/local/ssl/lib',
  110. '/usr/contrib/ssl/lib/'
  111. ] )
  112. if (ssl_incs is not None and ssl_libs is not None):
  113. return ssl_incs, ssl_libs, ['ssl', 'crypto']
  114. raise Exception("No SSL support found")
  115. if (sys.version_info >= (2, 5, 1)):
  116. socket_inc = "./ssl/2.5.1"
  117. else:
  118. socket_inc = "./ssl/2.3.6"
  119. link_args = []
  120. if sys.platform == 'win32':
  121. # Assume the openssl libraries from GnuWin32 are installed in the
  122. # following location:
  123. gnuwin32_dir = os.environ.get("GNUWIN32_DIR", r"C:\Utils\GnuWin32")
  124. # Set this to 1 for a dynamic build (depends on openssl DLLs)
  125. # Dynamic build is about 26k, static is 670k
  126. dynamic = int(os.environ.get("SSL_DYNAMIC", 0))
  127. ssl_incs = [os.environ.get("C_INCLUDE_DIR") or os.path.join(gnuwin32_dir, "include")]
  128. ssl_libs = [os.environ.get("C_LIB_DIR") or os.path.join(gnuwin32_dir, "lib")]
  129. libs = ['ssl', 'crypto', 'wsock32']
  130. if not dynamic:
  131. libs = libs + ['gdi32', 'gw32c', 'ole32', 'uuid']
  132. link_args = ['-static']
  133. else:
  134. ssl_incs, ssl_libs, libs = find_ssl()
  135. testdir = os.path.join(get_python_lib(False), "test")
  136. setup(name='ssl',
  137. version='1.15',
  138. description='SSL wrapper for socket objects (2.3, 2.4, 2.5 compatible)',
  139. long_description=
  140. """
  141. The old socket.ssl() support for TLS over sockets is being
  142. superseded in Python 2.6 by a new 'ssl' module. This package
  143. brings that module to older Python releases, 2.3.5 and up (it may
  144. also work on older versions of 2.3, but we haven't tried it).
  145. It's quite similar to the 2.6 ssl module. There's no stand-alone
  146. documentation for this package; instead, just use the development
  147. branch documentation for the SSL module at
  148. http://docs.python.org/dev/library/ssl.html.
  149. Version 1.0 had a problem with Python 2.5.1 -- the structure of
  150. the socket object changed from earlier versions.
  151. Version 1.1 was missing various package metadata information.
  152. Version 1.2 added more package metadata, and support for
  153. ssl.get_server_certificate(), and the PEM-to-DER encode/decode
  154. routines. Plus integrated Paul Moore's patch to setup.py for
  155. Windows. Plus added support for asyncore, and asyncore HTTPS
  156. server test.
  157. Version 1.3 fixed a bug in the test suite.
  158. Version 1.4 incorporated use of -static switch.
  159. Version 1.5 fixed bug in Python version check affecting build on
  160. Python 2.5.0.
  161. Version 1.7 (and 1.6) fixed some bugs with asyncore support (recv and
  162. send not being called on the SSLSocket class, wrong semantics for
  163. sendall).
  164. Version 1.8 incorporated some code from Chris Stawarz to handle
  165. sockets which are set to non-blocking before negotiating the SSL
  166. session.
  167. Version 1.9 makes ssl.SSLError a subtype of socket.error.
  168. Version 1.10 fixes a bug in sendall().
  169. Version 1.11 includes the MANIFEST file, and by default will turne
  170. unexpected EOFs occurring during a read into a regular EOF. It also
  171. removes the code for SSLFileStream, to use the regular socket module's
  172. _fileobject instead.
  173. Version 1.12 fixes the bug in SSLSocket.accept() reported by Georg
  174. Brandl, and adds a test case for that fix.
  175. Version 1.13 fixes a bug in calling do_handshake() automatically
  176. on non-blocking sockets. Thanks to Giampaolo Rodola. Now includes
  177. real asyncore test case.
  178. Version 1.14 incorporates some fixes to naming (rename "recv_from" to
  179. "recvfrom" and "send_to" to "sendto"), and a fix to the asyncore test
  180. case to unregister the connection handler when the connection is
  181. closed. It also exposes the SSL shutdown via the "unwrap" method
  182. on an SSLSocket. It exposes "subjectPublicKey" in the data received
  183. from a peer cert.
  184. Version 1.15 fixes a bug in write retries, where the output buffer has
  185. changed location because of garbage collection during the interim.
  186. It also provides the new flag, PROTOCOL_NOSSLv2, which selects SSL23,
  187. but disallows actual use of SSL2.
  188. Authorship: A cast of dozens over the years have written the Python
  189. SSL support, including Marc-Alan Lemburg, Robin Dunn, GvR, Kalle
  190. Svensson, Skip Montanaro, Mark Hammond, Martin von Loewis, Jeremy
  191. Hylton, Andrew Kuchling, Georg Brandl, Bill Janssen, Chris Stawarz,
  192. Neal Norwitz, and many others. Thanks to Paul Moore, David Bolen and
  193. Mark Hammond for help with the Windows side of the house. And it's
  194. all based on OpenSSL, which has its own cast of dozens!
  195. """,
  196. license='Python (MIT-like)',
  197. author='See long_description for details',
  198. author_email='python.ssl.maintainer@gmail.com',
  199. url='http://docs.python.org/dev/library/ssl.html',
  200. cmdclass={'test': Test},
  201. packages=['ssl'],
  202. ext_modules=[Extension('ssl._ssl2', ['ssl/_ssl2.c'],
  203. include_dirs = ssl_incs + [socket_inc],
  204. library_dirs = ssl_libs,
  205. libraries = libs,
  206. extra_link_args = link_args)],
  207. data_files=[(testdir, ['test/test_ssl.py',
  208. 'test/keycert.pem',
  209. 'test/badcert.pem',
  210. 'test/badkey.pem',
  211. 'test/nullcert.pem'])],
  212. )