Jean-Paul Calderone | 897bc25 | 2008-02-18 20:50:23 -0500 | [diff] [blame] | 1 | /* |
| 2 | * ssl.c |
| 3 | * |
| 4 | * Copyright (C) AB Strakt 2001, All rights reserved |
| 5 | * |
| 6 | * Main file of the SSL sub module. |
| 7 | * See the file RATIONALE for a short explanation of why this module was written. |
| 8 | * |
| 9 | * Reviewed 2001-07-23 |
| 10 | */ |
| 11 | #include <Python.h> |
| 12 | #define SSL_MODULE |
| 13 | #include "ssl.h" |
| 14 | |
| 15 | static char ssl_doc[] = "\n\ |
| 16 | Main file of the SSL sub module.\n\ |
| 17 | See the file RATIONALE for a short explanation of hy this module was written.\n\ |
| 18 | "; |
| 19 | |
| 20 | static char *CVSid = "@(#) $Id: ssl.c,v 1.12 2004/08/10 21:42:51 martin Exp $"; |
| 21 | |
| 22 | void **crypto_API; |
| 23 | |
| 24 | /* Exceptions defined by the SSL submodule */ |
| 25 | PyObject *ssl_Error, /* Base class */ |
| 26 | *ssl_ZeroReturnError, /* Used with SSL_get_error */ |
| 27 | *ssl_WantReadError, /* ... */ |
| 28 | *ssl_WantWriteError, /* ... */ |
| 29 | *ssl_WantX509LookupError, /* ... */ |
| 30 | *ssl_SysCallError; /* Uses (errno,errstr) */ |
| 31 | |
| 32 | static char ssl_Context_doc[] = "\n\ |
| 33 | The factory function inserted in the module dictionary to create Context\n\ |
| 34 | objects\n\ |
| 35 | \n\ |
| 36 | Arguments: spam - Always NULL\n\ |
| 37 | args - The Python argument tuple, should be:\n\ |
| 38 | method - The SSL method to use\n\ |
| 39 | Returns: The Context object\n\ |
| 40 | "; |
| 41 | |
| 42 | static PyObject * |
| 43 | ssl_Context(PyObject *spam, PyObject *args) |
| 44 | { |
| 45 | int method; |
| 46 | |
| 47 | if (!PyArg_ParseTuple(args, "i:Context", &method)) |
| 48 | return NULL; |
| 49 | |
| 50 | return (PyObject *)ssl_Context_New(method); |
| 51 | } |
| 52 | |
| 53 | static char ssl_Connection_doc[] = "\n\ |
| 54 | The factory function inserted in the module dictionary to create Connection\n\ |
| 55 | objects\n\ |
| 56 | \n\ |
| 57 | Arguments: spam - Always NULL\n\ |
| 58 | args - The Python argument tuple, should be:\n\ |
| 59 | ctx - An SSL Context to use for this connection\n\ |
| 60 | sock - The socket to use for transport layer\n\ |
| 61 | Returns: The Connection object\n\ |
| 62 | "; |
| 63 | |
| 64 | static PyObject * |
| 65 | ssl_Connection(PyObject *spam, PyObject *args) |
| 66 | { |
| 67 | ssl_ContextObj *ctx; |
| 68 | PyObject *sock; |
| 69 | |
| 70 | if (!PyArg_ParseTuple(args, "O!O:Connection", &ssl_Context_Type, &ctx, &sock)) |
| 71 | return NULL; |
| 72 | |
| 73 | return (PyObject *)ssl_Connection_New(ctx, sock); |
| 74 | } |
| 75 | |
| 76 | |
| 77 | /* Methods in the OpenSSL.SSL module */ |
| 78 | static PyMethodDef ssl_methods[] = { |
| 79 | { "Context", ssl_Context, METH_VARARGS, ssl_Context_doc }, |
| 80 | { "Connection", ssl_Connection, METH_VARARGS, ssl_Connection_doc }, |
| 81 | { NULL, NULL } |
| 82 | }; |
| 83 | |
| 84 | /* |
| 85 | * Initialize SSL sub module |
| 86 | * |
| 87 | * Arguments: None |
| 88 | * Returns: None |
| 89 | */ |
| 90 | void |
| 91 | initSSL(void) |
| 92 | { |
| 93 | static void *ssl_API[ssl_API_pointers]; |
| 94 | PyObject *ssl_api_object; |
| 95 | PyObject *module, *dict; |
| 96 | |
| 97 | SSL_library_init(); |
| 98 | ERR_load_SSL_strings(); |
| 99 | |
| 100 | import_crypto(); |
| 101 | |
| 102 | if ((module = Py_InitModule3("SSL", ssl_methods, ssl_doc)) == NULL) |
| 103 | return; |
| 104 | |
| 105 | /* Initialize the C API pointer array */ |
| 106 | ssl_API[ssl_Context_New_NUM] = (void *)ssl_Context_New; |
| 107 | ssl_API[ssl_Connection_New_NUM] = (void *)ssl_Connection_New; |
| 108 | ssl_api_object = PyCObject_FromVoidPtr((void *)ssl_API, NULL); |
| 109 | if (ssl_api_object != NULL) |
| 110 | PyModule_AddObject(module, "_C_API", ssl_api_object); |
| 111 | |
| 112 | /* Exceptions */ |
| 113 | /* |
| 114 | * ADD_EXCEPTION(dict,name,base) expands to a correct Exception declaration, |
| 115 | * inserting OpenSSL.SSL.name into dict, derviving the exception from base. |
| 116 | */ |
| 117 | #define ADD_EXCEPTION(_name, _base) \ |
| 118 | do { \ |
| 119 | ssl_##_name = PyErr_NewException("OpenSSL.SSL."#_name, _base, NULL);\ |
| 120 | if (ssl_##_name == NULL) \ |
| 121 | goto error; \ |
| 122 | if (PyModule_AddObject(module, #_name, ssl_##_name) != 0) \ |
| 123 | goto error; \ |
| 124 | } while (0) |
| 125 | |
| 126 | ssl_Error = PyErr_NewException("OpenSSL.SSL.Error", NULL, NULL); |
| 127 | if (ssl_Error == NULL) |
| 128 | goto error; |
| 129 | if (PyModule_AddObject(module, "Error", ssl_Error) != 0) |
| 130 | goto error; |
| 131 | |
| 132 | ADD_EXCEPTION(ZeroReturnError, ssl_Error); |
| 133 | ADD_EXCEPTION(WantReadError, ssl_Error); |
| 134 | ADD_EXCEPTION(WantWriteError, ssl_Error); |
| 135 | ADD_EXCEPTION(WantX509LookupError, ssl_Error); |
| 136 | ADD_EXCEPTION(SysCallError, ssl_Error); |
| 137 | #undef ADD_EXCEPTION |
| 138 | |
| 139 | /* Method constants */ |
| 140 | PyModule_AddIntConstant(module, "SSLv2_METHOD", ssl_SSLv2_METHOD); |
| 141 | PyModule_AddIntConstant(module, "SSLv3_METHOD", ssl_SSLv3_METHOD); |
| 142 | PyModule_AddIntConstant(module, "SSLv23_METHOD", ssl_SSLv23_METHOD); |
| 143 | PyModule_AddIntConstant(module, "TLSv1_METHOD", ssl_TLSv1_METHOD); |
| 144 | |
| 145 | /* Verify constants */ |
| 146 | PyModule_AddIntConstant(module, "VERIFY_NONE", SSL_VERIFY_NONE); |
| 147 | PyModule_AddIntConstant(module, "VERIFY_PEER", SSL_VERIFY_PEER); |
| 148 | PyModule_AddIntConstant(module, "VERIFY_FAIL_IF_NO_PEER_CERT", |
| 149 | SSL_VERIFY_FAIL_IF_NO_PEER_CERT); |
| 150 | PyModule_AddIntConstant(module, "VERIFY_CLIENT_ONCE", |
| 151 | SSL_VERIFY_CLIENT_ONCE); |
| 152 | |
| 153 | /* File type constants */ |
| 154 | PyModule_AddIntConstant(module, "FILETYPE_PEM", SSL_FILETYPE_PEM); |
| 155 | PyModule_AddIntConstant(module, "FILETYPE_ASN1", SSL_FILETYPE_ASN1); |
| 156 | |
| 157 | /* SSL option constants */ |
| 158 | PyModule_AddIntConstant(module, "OP_SINGLE_DH_USE", SSL_OP_SINGLE_DH_USE); |
| 159 | PyModule_AddIntConstant(module, "OP_EPHEMERAL_RSA", SSL_OP_EPHEMERAL_RSA); |
| 160 | PyModule_AddIntConstant(module, "OP_NO_SSLv2", SSL_OP_NO_SSLv2); |
| 161 | PyModule_AddIntConstant(module, "OP_NO_SSLv3", SSL_OP_NO_SSLv3); |
| 162 | PyModule_AddIntConstant(module, "OP_NO_TLSv1", SSL_OP_NO_TLSv1); |
| 163 | |
| 164 | /* More SSL option constants */ |
| 165 | PyModule_AddIntConstant(module, "OP_MICROSOFT_SESS_ID_BUG", SSL_OP_MICROSOFT_SESS_ID_BUG); |
| 166 | PyModule_AddIntConstant(module, "OP_NETSCAPE_CHALLENGE_BUG", SSL_OP_NETSCAPE_CHALLENGE_BUG); |
| 167 | PyModule_AddIntConstant(module, "OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG", SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG); |
| 168 | PyModule_AddIntConstant(module, "OP_SSLREF2_REUSE_CERT_TYPE_BUG", SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG); |
| 169 | PyModule_AddIntConstant(module, "OP_MICROSOFT_BIG_SSLV3_BUFFER", SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER); |
| 170 | PyModule_AddIntConstant(module, "OP_MSIE_SSLV2_RSA_PADDING", SSL_OP_MSIE_SSLV2_RSA_PADDING); |
| 171 | PyModule_AddIntConstant(module, "OP_SSLEAY_080_CLIENT_DH_BUG", SSL_OP_SSLEAY_080_CLIENT_DH_BUG); |
| 172 | PyModule_AddIntConstant(module, "OP_TLS_D5_BUG", SSL_OP_TLS_D5_BUG); |
| 173 | PyModule_AddIntConstant(module, "OP_TLS_BLOCK_PADDING_BUG", SSL_OP_TLS_BLOCK_PADDING_BUG); |
| 174 | PyModule_AddIntConstant(module, "OP_DONT_INSERT_EMPTY_FRAGMENTS", SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS); |
| 175 | PyModule_AddIntConstant(module, "OP_ALL", SSL_OP_ALL); |
| 176 | PyModule_AddIntConstant(module, "OP_CIPHER_SERVER_PREFERENCE", SSL_OP_CIPHER_SERVER_PREFERENCE); |
| 177 | PyModule_AddIntConstant(module, "OP_TLS_ROLLBACK_BUG", SSL_OP_TLS_ROLLBACK_BUG); |
| 178 | PyModule_AddIntConstant(module, "OP_PKCS1_CHECK_1", SSL_OP_PKCS1_CHECK_1); |
| 179 | PyModule_AddIntConstant(module, "OP_PKCS1_CHECK_2", SSL_OP_PKCS1_CHECK_2); |
| 180 | PyModule_AddIntConstant(module, "OP_NETSCAPE_CA_DN_BUG", SSL_OP_NETSCAPE_CA_DN_BUG); |
| 181 | PyModule_AddIntConstant(module, "OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG", SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG); |
| 182 | |
| 183 | dict = PyModule_GetDict(module); |
| 184 | if (!init_ssl_context(dict)) |
| 185 | goto error; |
| 186 | if (!init_ssl_connection(dict)) |
| 187 | goto error; |
| 188 | |
| 189 | error: |
| 190 | ; |
| 191 | } |