Expose OpenSSL version info and handle missing SSLv2_METHOD support
diff --git a/OpenSSL/ssl/context.c b/OpenSSL/ssl/context.c
index ea7847f..16268d8 100644
--- a/OpenSSL/ssl/context.c
+++ b/OpenSSL/ssl/context.c
@@ -237,6 +237,15 @@
     return;
 }
 
+/*
+ * More recent builds of OpenSSL may have SSLv2 completely disabled.
+ */
+#ifdef OPENSSL_NO_SSL2
+#define SSLv2_METHOD_TEXT ""
+#else
+#define SSLv2_METHOD_TEXT "SSLv2_METHOD, "
+#endif
+
 
 static char ssl_Context_doc[] = "\n\
 Context(method) -> Context instance\n\
@@ -244,10 +253,12 @@
 OpenSSL.SSL.Context instances define the parameters for setting up new SSL\n\
 connections.\n\
 \n\
-@param method: One of SSLv2_METHOD, SSLv3_METHOD, SSLv23_METHOD, or\n\
+@param method: One of " SSLv2_METHOD_TEXT "SSLv3_METHOD, SSLv23_METHOD, or\n\
                TLSv1_METHOD.\n\
 ";
 
+#undef SSLv2_METHOD_TEXT
+
 static char ssl_Context_load_verify_locations_doc[] = "\n\
 Let SSL know where we can find trusted certificates for the certificate\n\
 chain\n\
@@ -1107,11 +1118,16 @@
  */
 static ssl_ContextObj*
 ssl_Context_init(ssl_ContextObj *self, int i_method) {
-    SSL_METHOD *method;
+    const SSL_METHOD *method;
 
     switch (i_method) {
         case ssl_SSLv2_METHOD:
+#ifdef OPENSSL_NO_SSL2
+            PyErr_SetString(PyExc_ValueError, "SSLv2_METHOD not supported by this version of OpenSSL");
+            return NULL;
+#else      
             method = SSLv2_method();
+#endif
             break;
         case ssl_SSLv23_METHOD:
             method = SSLv23_method();
diff --git a/OpenSSL/ssl/ssl.c b/OpenSSL/ssl/ssl.c
index 50651a9..7a827a0 100644
--- a/OpenSSL/ssl/ssl.c
+++ b/OpenSSL/ssl/ssl.c
@@ -50,9 +50,30 @@
          *ssl_WantX509LookupError,     /* ...                     */
          *ssl_SysCallError;            /* Uses (errno,errstr)     */
 
+static char ssl_SSLeay_version_doc[] = "\n\
+Return a string describing the version of OpenSSL in use.\n\
+\n\
+@param type: One of the SSLEAY_ constants defined in this module.\n\
+";
+
+static PyObject *
+ssl_SSLeay_version(PyObject *spam, PyObject *args) {
+    int t;
+    const char *version;
+
+    if (!PyArg_ParseTuple(args, "i:SSLeay_version", &t)) {
+        return NULL;
+    }
+
+    version = SSLeay_version(t);
+    return PyBytes_FromStringAndSize(version, strlen(version));
+}
+
+
 
 /* Methods in the OpenSSL.SSL module */
 static PyMethodDef ssl_methods[] = {
+    { "SSLeay_version", ssl_SSLeay_version, METH_VARARGS, ssl_SSLeay_version_doc },
     { NULL, NULL }
 };
 
@@ -232,6 +253,16 @@
     PyModule_AddIntConstant(module, "SSL_CB_HANDSHAKE_START", SSL_CB_HANDSHAKE_START);
     PyModule_AddIntConstant(module, "SSL_CB_HANDSHAKE_DONE", SSL_CB_HANDSHAKE_DONE);
 
+    /* Version information indicators, used with SSLeay_version */
+    PyModule_AddIntConstant(module, "SSLEAY_VERSION", SSLEAY_VERSION);
+    PyModule_AddIntConstant(module, "SSLEAY_CFLAGS", SSLEAY_CFLAGS);
+    PyModule_AddIntConstant(module, "SSLEAY_BUILT_ON", SSLEAY_BUILT_ON);
+    PyModule_AddIntConstant(module, "SSLEAY_PLATFORM", SSLEAY_PLATFORM);
+    PyModule_AddIntConstant(module, "SSLEAY_DIR", SSLEAY_DIR);
+
+    /* Straight up version number */
+    PyModule_AddIntConstant(module, "OPENSSL_VERSION_NUMBER", OPENSSL_VERSION_NUMBER);
+
     if (!init_ssl_context(module))
         goto error;
     if (!init_ssl_connection(module))
diff --git a/OpenSSL/test/test_ssl.py b/OpenSSL/test/test_ssl.py
index 487266d..99aa6fb 100644
--- a/OpenSSL/test/test_ssl.py
+++ b/OpenSSL/test/test_ssl.py
@@ -17,18 +17,19 @@
 from OpenSSL.crypto import dump_privatekey, load_privatekey
 from OpenSSL.crypto import dump_certificate, load_certificate
 
+from OpenSSL.SSL import OPENSSL_VERSION_NUMBER, SSLEAY_VERSION, SSLEAY_CFLAGS
+from OpenSSL.SSL import SSLEAY_PLATFORM, SSLEAY_DIR, SSLEAY_BUILT_ON
 from OpenSSL.SSL import SENT_SHUTDOWN, RECEIVED_SHUTDOWN
 from OpenSSL.SSL import SSLv2_METHOD, SSLv3_METHOD, SSLv23_METHOD, TLSv1_METHOD
 from OpenSSL.SSL import OP_NO_SSLv2, OP_NO_SSLv3, OP_SINGLE_DH_USE
 from OpenSSL.SSL import VERIFY_PEER, VERIFY_FAIL_IF_NO_PEER_CERT, VERIFY_CLIENT_ONCE
-from OpenSSL.SSL import Error, SysCallError, WantReadError, ZeroReturnError
+from OpenSSL.SSL import Error, SysCallError, WantReadError, ZeroReturnError, SSLeay_version
 from OpenSSL.SSL import Context, ContextType, Connection, ConnectionType
 
 from OpenSSL.test.util import TestCase, bytes, b
 from OpenSSL.test.test_crypto import cleartextCertificatePEM, cleartextPrivateKeyPEM
 from OpenSSL.test.test_crypto import client_cert_pem, client_key_pem
 from OpenSSL.test.test_crypto import server_cert_pem, server_key_pem, root_cert_pem
-
 try:
     from OpenSSL.SSL import OP_NO_QUERY_MTU
 except ImportError:
@@ -174,6 +175,35 @@
                         write.bio_write(dirty)
 
 
+class VersionTests(TestCase):
+    """
+    Tests for version information exposed by
+    L{OpenSSL.SSL.SSLeay_version} and
+    L{OpenSSL.SSL.OPENSSL_VERSION_NUMBER}.
+    """
+    def test_OPENSSL_VERSION_NUMBER(self):
+        """
+        L{OPENSSL_VERSION_NUMBER} is an integer with status in the low
+        byte and the patch, fix, minor, and major versions in the
+        nibbles above that.
+        """
+        self.assertTrue(isinstance(OPENSSL_VERSION_NUMBER, int))
+
+
+    def test_SSLeay_version(self):
+        """
+        L{SSLeay_version} takes a version type indicator and returns
+        one of a number of version strings based on that indicator.
+        """
+        versions = {}
+        for t in [SSLEAY_VERSION, SSLEAY_CFLAGS, SSLEAY_BUILT_ON,
+                  SSLEAY_PLATFORM, SSLEAY_DIR]:
+            version = SSLeay_version(t)
+            versions[version] = t
+            self.assertTrue(isinstance(version, bytes))
+        self.assertEqual(len(versions), 5)
+
+
 
 class ContextTests(TestCase, _LoopbackMixin):
     """
@@ -184,8 +214,16 @@
         L{Context} can be instantiated with one of L{SSLv2_METHOD},
         L{SSLv3_METHOD}, L{SSLv23_METHOD}, or L{TLSv1_METHOD}.
         """
-        for meth in [SSLv2_METHOD, SSLv3_METHOD, SSLv23_METHOD, TLSv1_METHOD]:
+        for meth in [SSLv3_METHOD, SSLv23_METHOD, TLSv1_METHOD]:
             Context(meth)
+
+        try:
+            Context(SSLv2_METHOD)
+        except ValueError:
+            # Some versions of OpenSSL have SSLv2, some don't.
+            # Difficult to say in advance.
+            pass
+
         self.assertRaises(TypeError, Context, "")
         self.assertRaises(ValueError, Context, 10)