diff options
author | Minteck <contact@minteck.org> | 2023-01-10 14:54:04 +0100 |
---|---|---|
committer | Minteck <contact@minteck.org> | 2023-01-10 14:54:04 +0100 |
commit | 99c1d9af689e5325f3cf535c4007b3aeb8325229 (patch) | |
tree | e663b3c2ebdbd67c818ac0c5147f0ce1d2463cda /alarm/node_modules/node-forge/tests/forge_ssl | |
parent | 9871b03912fc28ad38b4037ebf26a78aa937baba (diff) | |
download | pluralconnect-99c1d9af689e5325f3cf535c4007b3aeb8325229.tar.gz pluralconnect-99c1d9af689e5325f3cf535c4007b3aeb8325229.tar.bz2 pluralconnect-99c1d9af689e5325f3cf535c4007b3aeb8325229.zip |
Update - This is an automated commit
Diffstat (limited to 'alarm/node_modules/node-forge/tests/forge_ssl')
5 files changed, 0 insertions, 2536 deletions
diff --git a/alarm/node_modules/node-forge/tests/forge_ssl/forge/__init__.py b/alarm/node_modules/node-forge/tests/forge_ssl/forge/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/alarm/node_modules/node-forge/tests/forge_ssl/forge/__init__.py +++ /dev/null diff --git a/alarm/node_modules/node-forge/tests/forge_ssl/forge/_ssl.c b/alarm/node_modules/node-forge/tests/forge_ssl/forge/_ssl.c deleted file mode 100644 index bdef8c9..0000000 --- a/alarm/node_modules/node-forge/tests/forge_ssl/forge/_ssl.c +++ /dev/null @@ -1,1770 +0,0 @@ -/* SSL socket module - - SSL support based on patches by Brian E Gallew and Laszlo Kovacs. - Re-worked a bit by Bill Janssen to add server-side support and - certificate decoding. Chris Stawarz contributed some non-blocking - patches. - - This module is imported by ssl.py. It should *not* be used - directly. - - XXX should partial writes be enabled, SSL_MODE_ENABLE_PARTIAL_WRITE? - - XXX integrate several "shutdown modes" as suggested in - http://bugs.python.org/issue8108#msg102867 ? -*/ - -#include "Python.h" - -#ifdef WITH_THREAD -#include "pythread.h" -#define PySSL_BEGIN_ALLOW_THREADS { \ - PyThreadState *_save = NULL; \ - if (_ssl_locks_count>0) {_save = PyEval_SaveThread();} -#define PySSL_BLOCK_THREADS if (_ssl_locks_count>0){PyEval_RestoreThread(_save)}; -#define PySSL_UNBLOCK_THREADS if (_ssl_locks_count>0){_save = PyEval_SaveThread()}; -#define PySSL_END_ALLOW_THREADS if (_ssl_locks_count>0){PyEval_RestoreThread(_save);} \ - } - -#else /* no WITH_THREAD */ - -#define PySSL_BEGIN_ALLOW_THREADS -#define PySSL_BLOCK_THREADS -#define PySSL_UNBLOCK_THREADS -#define PySSL_END_ALLOW_THREADS - -#endif - -enum py_ssl_error { - /* these mirror ssl.h */ - PY_SSL_ERROR_NONE, - PY_SSL_ERROR_SSL, - PY_SSL_ERROR_WANT_READ, - PY_SSL_ERROR_WANT_WRITE, - PY_SSL_ERROR_WANT_X509_LOOKUP, - PY_SSL_ERROR_SYSCALL, /* look at error stack/return value/errno */ - PY_SSL_ERROR_ZERO_RETURN, - PY_SSL_ERROR_WANT_CONNECT, - /* start of non ssl.h errorcodes */ - PY_SSL_ERROR_EOF, /* special case of SSL_ERROR_SYSCALL */ - PY_SSL_ERROR_INVALID_ERROR_CODE -}; - -enum py_ssl_server_or_client { - PY_SSL_CLIENT, - PY_SSL_SERVER -}; - -enum py_ssl_cert_requirements { - PY_SSL_CERT_NONE, - PY_SSL_CERT_OPTIONAL, - PY_SSL_CERT_REQUIRED -}; - -enum py_ssl_version { - PY_SSL_VERSION_SSL2, - PY_SSL_VERSION_SSL3, - PY_SSL_VERSION_SSL23, - PY_SSL_VERSION_TLS1 -}; - -enum py_ssl_sess_cache_mode { - PY_SSL_SESS_CACHE_OFF, - PY_SSL_SESS_CACHE_CLIENT, - PY_SSL_SESS_CACHE_SERVER, - PY_SSL_SESS_CACHE_BOTH -}; - -/* Include symbols from _socket module */ -#include "socketmodule.h" - -#if defined(HAVE_POLL_H) -#include <poll.h> -#elif defined(HAVE_SYS_POLL_H) -#include <sys/poll.h> -#endif - -/* Include OpenSSL header files */ -#include "openssl/rsa.h" -#include "openssl/crypto.h" -#include "openssl/x509.h" -#include "openssl/x509v3.h" -#include "openssl/pem.h" -#include "openssl/ssl.h" -#include "openssl/err.h" -#include "openssl/rand.h" - -/* SSL error object */ -static PyObject *PySSLErrorObject; - -#ifdef WITH_THREAD - -/* serves as a flag to see whether we've initialized the SSL thread support. */ -/* 0 means no, greater than 0 means yes */ - -static unsigned int _ssl_locks_count = 0; - -#endif /* def WITH_THREAD */ - -/* SSL socket object */ - -#define X509_NAME_MAXLEN 256 - -/* RAND_* APIs got added to OpenSSL in 0.9.5 */ -#if OPENSSL_VERSION_NUMBER >= 0x0090500fL -# define HAVE_OPENSSL_RAND 1 -#else -# undef HAVE_OPENSSL_RAND -#endif - -typedef struct { - PyObject_HEAD - PySocketSockObject *Socket; /* Socket on which we're layered */ - int inherited; - SSL_CTX* ctx; - SSL* ssl; - X509* peer_cert; - char server[X509_NAME_MAXLEN]; - char issuer[X509_NAME_MAXLEN]; - int shutdown_seen_zero; - -} PySSLObject; - -static PyTypeObject PySSL_Type; -static PyObject *PySSL_SSLwrite(PySSLObject *self, PyObject *args); -static PyObject *PySSL_SSLread(PySSLObject *self, PyObject *args); -static int check_socket_and_wait_for_timeout(PySocketSockObject *s, - int writing); -static PyObject *PySSL_peercert(PySSLObject *self, PyObject *args); -static PyObject *PySSL_cipher(PySSLObject *self); - -#define PySSLObject_Check(v) (Py_TYPE(v) == &PySSL_Type) - -typedef enum { - SOCKET_IS_NONBLOCKING, - SOCKET_IS_BLOCKING, - SOCKET_HAS_TIMED_OUT, - SOCKET_HAS_BEEN_CLOSED, - SOCKET_TOO_LARGE_FOR_SELECT, - SOCKET_OPERATION_OK -} timeout_state; - -/* Wrap error strings with filename and line # */ -#define STRINGIFY1(x) #x -#define STRINGIFY2(x) STRINGIFY1(x) -#define ERRSTR1(x,y,z) (x ":" y ": " z) -#define ERRSTR(x) ERRSTR1("_ssl.c", STRINGIFY2(__LINE__), x) - -/* XXX It might be helpful to augment the error message generated - below with the name of the SSL function that generated the error. - I expect it's obvious most of the time. -*/ - -static PyObject * -PySSL_SetError(PySSLObject *obj, int ret, char *filename, int lineno) -{ - PyObject *v; - char buf[2048]; - char *errstr; - int err; - enum py_ssl_error p = PY_SSL_ERROR_NONE; - - assert(ret <= 0); - - if (obj->ssl != NULL) { - err = SSL_get_error(obj->ssl, ret); - - switch (err) { - case SSL_ERROR_ZERO_RETURN: - errstr = "TLS/SSL connection has been closed"; - p = PY_SSL_ERROR_ZERO_RETURN; - break; - case SSL_ERROR_WANT_READ: - errstr = "The operation did not complete (read)"; - p = PY_SSL_ERROR_WANT_READ; - break; - case SSL_ERROR_WANT_WRITE: - p = PY_SSL_ERROR_WANT_WRITE; - errstr = "The operation did not complete (write)"; - break; - case SSL_ERROR_WANT_X509_LOOKUP: - p = PY_SSL_ERROR_WANT_X509_LOOKUP; - errstr = "The operation did not complete (X509 lookup)"; - break; - case SSL_ERROR_WANT_CONNECT: - p = PY_SSL_ERROR_WANT_CONNECT; - errstr = "The operation did not complete (connect)"; - break; - case SSL_ERROR_SYSCALL: - { - unsigned long e = ERR_get_error(); - if (e == 0) { - if (ret == 0 || !obj->Socket) { - p = PY_SSL_ERROR_EOF; - errstr = "EOF occurred in violation of protocol"; - } else if (ret == -1) { - /* underlying BIO reported an I/O error */ - ERR_clear_error(); - return obj->Socket->errorhandler(); - } else { /* possible? */ - p = PY_SSL_ERROR_SYSCALL; - errstr = "Some I/O error occurred"; - } - } else { - p = PY_SSL_ERROR_SYSCALL; - /* XXX Protected by global interpreter lock */ - errstr = ERR_error_string(e, NULL); - } - break; - } - case SSL_ERROR_SSL: - { - unsigned long e = ERR_get_error(); - p = PY_SSL_ERROR_SSL; - if (e != 0) - /* XXX Protected by global interpreter lock */ - errstr = ERR_error_string(e, NULL); - else { /* possible? */ - errstr = "A failure in the SSL library occurred"; - } - break; - } - default: - p = PY_SSL_ERROR_INVALID_ERROR_CODE; - errstr = "Invalid error code"; - } - } else { - errstr = ERR_error_string(ERR_peek_last_error(), NULL); - } - PyOS_snprintf(buf, sizeof(buf), "_ssl.c:%d: %s", lineno, errstr); - ERR_clear_error(); - v = Py_BuildValue("(is)", p, buf); - if (v != NULL) { - PyErr_SetObject(PySSLErrorObject, v); - Py_DECREF(v); - } - return NULL; -} - -static PyObject * -_setSSLError (char *errstr, int errcode, char *filename, int lineno) { - - char buf[2048]; - PyObject *v; - - if (errstr == NULL) { - errcode = ERR_peek_last_error(); - errstr = ERR_error_string(errcode, NULL); - } - PyOS_snprintf(buf, sizeof(buf), "_ssl.c:%d: %s", lineno, errstr); - ERR_clear_error(); - v = Py_BuildValue("(is)", errcode, buf); - if (v != NULL) { - PyErr_SetObject(PySSLErrorObject, v); - Py_DECREF(v); - } - return NULL; -} - -static PySSLObject * -newPySSLObject(PySSLObject *ssl_object, PySocketSockObject *Sock, - char *key_file, char *cert_file, - enum py_ssl_server_or_client socket_type, - enum py_ssl_cert_requirements certreq, - enum py_ssl_version proto_version, - enum py_ssl_sess_cache_mode cache_mode, - char *sess_id_ctx, - char *cacerts_file) -{ - PySSLObject *self; - char *errstr = NULL; - int ret; - int verification_mode; - int sess_cache_mode; - - self = PyObject_New(PySSLObject, &PySSL_Type); /* Create new object */ - if (self == NULL) - return NULL; - memset(self->server, '\0', sizeof(char) * X509_NAME_MAXLEN); - memset(self->issuer, '\0', sizeof(char) * X509_NAME_MAXLEN); - self->peer_cert = NULL; - self->inherited = 0; - self->ssl = NULL; - self->ctx = NULL; - self->Socket = NULL; - - /* Make sure the SSL error state is initialized */ - (void) ERR_get_state(); - ERR_clear_error(); - - if ((key_file && !cert_file) || (!key_file && cert_file)) { - errstr = ERRSTR("Both the key & certificate files " - "must be specified"); - goto fail; - } - - if ((socket_type == PY_SSL_SERVER) && (ssl_object == NULL) && - ((key_file == NULL) || (cert_file == NULL))) { - errstr = ERRSTR("Both the key & certificate files " - "must be specified for server-side operation"); - goto fail; - } - - if (ssl_object != NULL) { - self->inherited = 1; - self->ctx = ssl_object->ctx; - } else { - self->inherited = 0; - - PySSL_BEGIN_ALLOW_THREADS - if (proto_version == PY_SSL_VERSION_TLS1) - self->ctx = SSL_CTX_new(TLSv1_method()); /* Set up context */ - else if (proto_version == PY_SSL_VERSION_SSL3) - self->ctx = SSL_CTX_new(SSLv3_method()); /* Set up context */ - else if (proto_version == PY_SSL_VERSION_SSL2) - self->ctx = SSL_CTX_new(SSLv2_method()); /* Set up context */ - else if (proto_version == PY_SSL_VERSION_SSL23) - self->ctx = SSL_CTX_new(SSLv23_method()); /* Set up context */ - PySSL_END_ALLOW_THREADS - } - - if (self->ctx == NULL) { - errstr = ERRSTR("Invalid SSL protocol variant specified."); - goto fail; - } - - if (self->inherited == 0 && certreq != PY_SSL_CERT_NONE) { - if (cacerts_file == NULL) { - errstr = ERRSTR("No root certificates specified for " - "verification of other-side certificates."); - goto fail; - } else { - PySSL_BEGIN_ALLOW_THREADS - ret = SSL_CTX_load_verify_locations(self->ctx, - cacerts_file, - NULL); - PySSL_END_ALLOW_THREADS - if (ret != 1) { - _setSSLError(NULL, 0, __FILE__, __LINE__); - goto fail; - } - } - } - if (self->inherited == 0 && key_file) { - PySSL_BEGIN_ALLOW_THREADS - ret = SSL_CTX_use_PrivateKey_file(self->ctx, key_file, - SSL_FILETYPE_PEM); - PySSL_END_ALLOW_THREADS - if (ret != 1) { - _setSSLError(NULL, ret, __FILE__, __LINE__); - goto fail; - } - - PySSL_BEGIN_ALLOW_THREADS - ret = SSL_CTX_use_certificate_chain_file(self->ctx, - cert_file); - PySSL_END_ALLOW_THREADS - if (ret != 1) { - /* - fprintf(stderr, "ret is %d, errcode is %lu, %lu, with file \"%s\"\n", - ret, ERR_peek_error(), ERR_peek_last_error(), cert_file); - */ - if (ERR_peek_last_error() != 0) { - _setSSLError(NULL, ret, __FILE__, __LINE__); - goto fail; - } - } - } - - if (self->inherited == 0) { - /* ssl compatibility */ - SSL_CTX_set_options(self->ctx, SSL_OP_ALL); - - /* session cache mode */ - PySSL_BEGIN_ALLOW_THREADS - sess_cache_mode = SSL_SESS_CACHE_SERVER; - if (cache_mode == PY_SSL_SESS_CACHE_OFF) - sess_cache_mode = SSL_SESS_CACHE_OFF; - else if (cache_mode == PY_SSL_SESS_CACHE_CLIENT) - sess_cache_mode = SSL_SESS_CACHE_CLIENT; - else if (cache_mode == PY_SSL_SESS_CACHE_SERVER) - sess_cache_mode = SSL_SESS_CACHE_SERVER; - else if (cache_mode == PY_SSL_SESS_CACHE_BOTH) - sess_cache_mode = SSL_SESS_CACHE_BOTH; - SSL_CTX_set_session_cache_mode(self->ctx, sess_cache_mode); - - /* session id context */ - if (sess_id_ctx != NULL) - SSL_CTX_set_session_id_context(self->ctx, - (const unsigned char*)sess_id_ctx, - strlen(sess_id_ctx)); - PySSL_END_ALLOW_THREADS - - verification_mode = SSL_VERIFY_NONE; - if (certreq == PY_SSL_CERT_OPTIONAL) - verification_mode = SSL_VERIFY_PEER; - else if (certreq == PY_SSL_CERT_REQUIRED) - verification_mode = (SSL_VERIFY_PEER | - SSL_VERIFY_FAIL_IF_NO_PEER_CERT); - SSL_CTX_set_verify(self->ctx, verification_mode, - NULL); /* set verify lvl */ - } - - self->ssl = SSL_new(self->ctx); /* New ssl struct */ - SSL_set_fd(self->ssl, Sock->sock_fd); /* Set the socket for SSL */ -#ifdef SSL_MODE_AUTO_RETRY - SSL_set_mode(self->ssl, SSL_MODE_AUTO_RETRY); -#endif - - /* If the socket is in non-blocking mode or timeout mode, set the BIO - * to non-blocking mode (blocking is the default) - */ - if (Sock->sock_timeout >= 0.0) { - /* Set both the read and write BIO's to non-blocking mode */ - BIO_set_nbio(SSL_get_rbio(self->ssl), 1); - BIO_set_nbio(SSL_get_wbio(self->ssl), 1); - } - - PySSL_BEGIN_ALLOW_THREADS - if (socket_type == PY_SSL_CLIENT) - SSL_set_connect_state(self->ssl); - else - SSL_set_accept_state(self->ssl); - PySSL_END_ALLOW_THREADS - - self->Socket = Sock; - Py_INCREF(self->Socket); - return self; - fail: - if (errstr) - PyErr_SetString(PySSLErrorObject, errstr); - Py_DECREF(self); - return NULL; -} - -static PyObject * -PySSL_sslwrap(PyObject *self, PyObject *args) -{ - PySocketSockObject *Sock; - int server_side = 0; - int verification_mode = PY_SSL_CERT_NONE; - int protocol = PY_SSL_VERSION_SSL23; - int sess_cache_mode = PY_SSL_SESS_CACHE_SERVER; - char *sess_id_ctx = NULL; - char *key_file = NULL; - char *cert_file = NULL; - char *cacerts_file = NULL; - - if (!PyArg_ParseTuple(args, "O!i|zziiizz:sslwrap", - PySocketModule.Sock_Type, - &Sock, - &server_side, - &key_file, &cert_file, - &verification_mode, &protocol, - &sess_cache_mode, &sess_id_ctx, - &cacerts_file)) - return NULL; - - /* - fprintf(stderr, - "server_side is %d, keyfile %p, certfile %p, verify_mode %d, " - "protocol %d, sess_cache_mode %d, sess_id_ctx %p, certs %p\n", - server_side, key_file, cert_file, verification_mode, - protocol, sess_cache_mode, sess_id_ctx, cacerts_file); - */ - - return (PyObject *) newPySSLObject(NULL, Sock, key_file, cert_file, - server_side, verification_mode, - protocol, sess_cache_mode, sess_id_ctx, - cacerts_file); -} - -PyDoc_STRVAR(sslwrap_doc, -"sslwrap(socket, server_side, [keyfile, certfile, certs_mode, protocol,\n" -" sess_cache_mode, sess_id_ctx, cacertsfile]) -> sslobject"); - -/* SSL object methods */ - -static PyObject * -PySSL_SSLwrap_accepted(PySSLObject *self, PyObject *args) -{ - PySocketSockObject *Sock; - - if (!PyArg_ParseTuple(args, "O!:sslwrap", - PySocketModule.Sock_Type, - &Sock)) - return NULL; - - return (PyObject *) newPySSLObject(self, Sock, NULL, NULL, - PY_SSL_SERVER, 0, 0, 0, NULL, NULL); -} - -PyDoc_STRVAR(PySSL_SSLwrap_accepted_doc, -"wrap_accepted(socket) -> sslobject"); - -static PyObject *PySSL_SSLdo_handshake(PySSLObject *self) -{ - int ret; - int err; - int sockstate, nonblocking; - - /* just in case the blocking state of the socket has been changed */ - nonblocking = (self->Socket->sock_timeout >= 0.0); - BIO_set_nbio(SSL_get_rbio(self->ssl), nonblocking); - BIO_set_nbio(SSL_get_wbio(self->ssl), nonblocking); - - /* Actually negotiate SSL connection */ - /* XXX If SSL_do_handshake() returns 0, it's also a failure. */ - sockstate = 0; - do { - PySSL_BEGIN_ALLOW_THREADS - ret = SSL_do_handshake(self->ssl); - err = SSL_get_error(self->ssl, ret); - PySSL_END_ALLOW_THREADS - if(PyErr_CheckSignals()) { - return NULL; - } - if (err == SSL_ERROR_WANT_READ) { - sockstate = check_socket_and_wait_for_timeout(self->Socket, 0); - } else if (err == SSL_ERROR_WANT_WRITE) { - sockstate = check_socket_and_wait_for_timeout(self->Socket, 1); - } else { - sockstate = SOCKET_OPERATION_OK; - } - if (sockstate == SOCKET_HAS_TIMED_OUT) { - PyErr_SetString(PySSLErrorObject, - ERRSTR("The handshake operation timed out")); - return NULL; - } else if (sockstate == SOCKET_HAS_BEEN_CLOSED) { - PyErr_SetString(PySSLErrorObject, - ERRSTR("Underlying socket has been closed.")); - return NULL; - } else if (sockstate == SOCKET_TOO_LARGE_FOR_SELECT) { - PyErr_SetString(PySSLErrorObject, - ERRSTR("Underlying socket too large for select().")); - return NULL; - } else if (sockstate == SOCKET_IS_NONBLOCKING) { - break; - } - } while (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE); - if (ret < 1) - return PySSL_SetError(self, ret, __FILE__, __LINE__); - - if (self->peer_cert) - X509_free (self->peer_cert); - PySSL_BEGIN_ALLOW_THREADS - if ((self->peer_cert = SSL_get_peer_certificate(self->ssl))) { - X509_NAME_oneline(X509_get_subject_name(self->peer_cert), - self->server, X509_NAME_MAXLEN); - X509_NAME_oneline(X509_get_issuer_name(self->peer_cert), - self->issuer, X509_NAME_MAXLEN); - } - PySSL_END_ALLOW_THREADS - - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject * -PySSL_server(PySSLObject *self) -{ - return PyString_FromString(self->server); -} - -static PyObject * -PySSL_issuer(PySSLObject *self) -{ - return PyString_FromString(self->issuer); -} - -static PyObject * -_create_tuple_for_attribute (ASN1_OBJECT *name, ASN1_STRING *value) { - - char namebuf[X509_NAME_MAXLEN]; - int buflen; - PyObject *name_obj; - PyObject *value_obj; - PyObject *attr; - unsigned char *valuebuf = NULL; - - buflen = OBJ_obj2txt(namebuf, sizeof(namebuf), name, 0); - if (buflen < 0) { - _setSSLError(NULL, 0, __FILE__, __LINE__); - goto fail; - } - name_obj = PyString_FromStringAndSize(namebuf, buflen); - if (name_obj == NULL) - goto fail; - - buflen = ASN1_STRING_to_UTF8(&valuebuf, value); - if (buflen < 0) { - _setSSLError(NULL, 0, __FILE__, __LINE__); - Py_DECREF(name_obj); - goto fail; - } - value_obj = PyUnicode_DecodeUTF8((char *) valuebuf, - buflen, "strict"); - OPENSSL_free(valuebuf); - if (value_obj == NULL) { - Py_DECREF(name_obj); - goto fail; - } - attr = PyTuple_New(2); - if (attr == NULL) { - Py_DECREF(name_obj); - Py_DECREF(value_obj); - goto fail; - } - PyTuple_SET_ITEM(attr, 0, name_obj); - PyTuple_SET_ITEM(attr, 1, value_obj); - return attr; - - fail: - return NULL; -} - -static PyObject * -_create_tuple_for_X509_NAME (X509_NAME *xname) -{ - PyObject *dn = NULL; /* tuple which represents the "distinguished name" */ - PyObject *rdn = NULL; /* tuple to hold a "relative distinguished name" */ - PyObject *rdnt; - PyObject *attr = NULL; /* tuple to hold an attribute */ - int entry_count = X509_NAME_entry_count(xname); - X509_NAME_ENTRY *entry; - ASN1_OBJECT *name; - ASN1_STRING *value; - int index_counter; - int rdn_level = -1; - int retcode; - - dn = PyList_New(0); - if (dn == NULL) - return NULL; - /* now create another tuple to hold the top-level RDN */ - rdn = PyList_New(0); - if (rdn == NULL) - goto fail0; - - for (index_counter = 0; - index_counter < entry_count; - index_counter++) - { - entry = X509_NAME_get_entry(xname, index_counter); - - /* check to see if we've gotten to a new RDN */ - if (rdn_level >= 0) { - if (rdn_level != entry->set) { - /* yes, new RDN */ - /* add old RDN to DN */ - rdnt = PyList_AsTuple(rdn); - Py_DECREF(rdn); - if (rdnt == NULL) - goto fail0; - retcode = PyList_Append(dn, rdnt); - Py_DECREF(rdnt); - if (retcode < 0) - goto fail0; - /* create new RDN */ - rdn = PyList_New(0); - if (rdn == NULL) - goto fail0; - } - } - rdn_level = entry->set; - - /* now add this attribute to the current RDN */ - name = X509_NAME_ENTRY_get_object(entry); - value = X509_NAME_ENTRY_get_data(entry); - attr = _create_tuple_for_attribute(name, value); - /* - fprintf(stderr, "RDN level %d, attribute %s: %s\n", - entry->set, - PyString_AS_STRING(PyTuple_GET_ITEM(attr, 0)), - PyString_AS_STRING(PyTuple_GET_ITEM(attr, 1))); - */ - if (attr == NULL) - goto fail1; - retcode = PyList_Append(rdn, attr); - Py_DECREF(attr); - if (retcode < 0) - goto fail1; - } - /* now, there's typically a dangling RDN */ - if ((rdn != NULL) && (PyList_Size(rdn) > 0)) { - rdnt = PyList_AsTuple(rdn); - Py_DECREF(rdn); - if (rdnt == NULL) - goto fail0; - retcode = PyList_Append(dn, rdnt); - Py_DECREF(rdnt); - if (retcode < 0) - goto fail0; - } - - /* convert list to tuple */ - rdnt = PyList_AsTuple(dn); - Py_DECREF(dn); - if (rdnt == NULL) - return NULL; - return rdnt; - - fail1: - Py_XDECREF(rdn); - - fail0: - Py_XDECREF(dn); - return NULL; -} - -static PyObject * -_get_peer_alt_names (X509 *certificate) { - - /* this code follows the procedure outlined in - OpenSSL's crypto/x509v3/v3_prn.c:X509v3_EXT_print() - function to extract the STACK_OF(GENERAL_NAME), - then iterates through the stack to add the - names. */ - - int i, j; - PyObject *peer_alt_names = Py_None; - PyObject *v, *t; - X509_EXTENSION *ext = NULL; - GENERAL_NAMES *names = NULL; - GENERAL_NAME *name; - X509V3_EXT_METHOD *method; - BIO *biobuf = NULL; - char buf[2048]; - char *vptr; - int len; - const unsigned char *p; - - if (certificate == NULL) - return peer_alt_names; - - /* get a memory buffer */ - biobuf = BIO_new(BIO_s_mem()); - - i = 0; - while ((i = X509_get_ext_by_NID( - certificate, NID_subject_alt_name, i)) >= 0) { - - if (peer_alt_names == Py_None) { - peer_alt_names = PyList_New(0); - if (peer_alt_names == NULL) - goto fail; - } - - /* now decode the altName */ - ext = X509_get_ext(certificate, i); - if(!(method = X509V3_EXT_get(ext))) { - PyErr_SetString(PySSLErrorObject, - ERRSTR("No method for internalizing subjectAltName!")); - goto fail; - } - - p = ext->value->data; - if (method->it) - names = (GENERAL_NAMES*) (ASN1_item_d2i(NULL, - &p, - ext->value->length, - ASN1_ITEM_ptr(method->it))); - else - names = (GENERAL_NAMES*) (method->d2i(NULL, - &p, - ext->value->length)); - - for(j = 0; j < sk_GENERAL_NAME_num(names); j++) { - - /* get a rendering of each name in the set of names */ - - name = sk_GENERAL_NAME_value(names, j); - if (name->type == GEN_DIRNAME) { - - /* we special-case DirName as a tuple of tuples of attributes */ - - t = PyTuple_New(2); - if (t == NULL) { - goto fail; - } - - v = PyString_FromString("DirName"); - if (v == NULL) { - Py_DECREF(t); - goto fail; - } - PyTuple_SET_ITEM(t, 0, v); - - v = _create_tuple_for_X509_NAME (name->d.dirn); - if (v == NULL) { - Py_DECREF(t); - goto fail; - } - PyTuple_SET_ITEM(t, 1, v); - - } else { - - /* for everything else, we use the OpenSSL print form */ - - (void) BIO_reset(biobuf); - GENERAL_NAME_print(biobuf, name); - len = BIO_gets(biobuf, buf, sizeof(buf)-1); - if (len < 0) { - _setSSLError(NULL, 0, __FILE__, __LINE__); - goto fail; - } - vptr = strchr(buf, ':'); - if (vptr == NULL) - goto fail; - t = PyTuple_New(2); - if (t == NULL) - goto fail; - v = PyString_FromStringAndSize(buf, (vptr - buf)); - if (v == NULL) { - Py_DECREF(t); - goto fail; - } - PyTuple_SET_ITEM(t, 0, v); - v = PyString_FromStringAndSize((vptr + 1), (len - (vptr - buf + 1))); - if (v == NULL) { - Py_DECREF(t); - goto fail; - } - PyTuple_SET_ITEM(t, 1, v); - } - - /* and add that rendering to the list */ - - if (PyList_Append(peer_alt_names, t) < 0) { - Py_DECREF(t); - goto fail; - } - Py_DECREF(t); - } - } - BIO_free(biobuf); - if (peer_alt_names != Py_None) { - v = PyList_AsTuple(peer_alt_names); - Py_DECREF(peer_alt_names); - return v; - } else { - return peer_alt_names; - } - - - fail: - if (biobuf != NULL) - BIO_free(biobuf); - - if (peer_alt_names != Py_None) { - Py_XDECREF(peer_alt_names); - } - - return NULL; -} - -static PyObject * -_decode_certificate (X509 *certificate, int verbose) { - - PyObject *retval = NULL; - BIO *biobuf = NULL; - PyObject *peer; - PyObject *peer_alt_names = NULL; - PyObject *issuer; - PyObject *version; - PyObject *sn_obj; - ASN1_INTEGER *serialNumber; - char buf[2048]; - int len; - ASN1_TIME *notBefore, *notAfter; - PyObject *pnotBefore, *pnotAfter; - - retval = PyDict_New(); - if (retval == NULL) - return NULL; - - peer = _create_tuple_for_X509_NAME( - X509_get_subject_name(certificate)); - if (peer == NULL) - goto fail0; - if (PyDict_SetItemString(retval, (const char *) "subject", peer) < 0) { - Py_DECREF(peer); - goto fail0; - } - Py_DECREF(peer); - - if (verbose) { - issuer = _create_tuple_for_X509_NAME( - X509_get_issuer_name(certificate)); - if (issuer == NULL) - goto fail0; - if (PyDict_SetItemString(retval, (const char *)"issuer", issuer) < 0) { - Py_DECREF(issuer); - goto fail0; - } - Py_DECREF(issuer); - - version = PyInt_FromLong(X509_get_version(certificate) + 1); - if (PyDict_SetItemString(retval, "version", version) < 0) { - Py_DECREF(version); - goto fail0; - } - Py_DECREF(version); - } - - /* get a memory buffer */ - biobuf = BIO_new(BIO_s_mem()); - - if (verbose) { - - (void) BIO_reset(biobuf); - serialNumber = X509_get_serialNumber(certificate); - /* should not exceed 20 octets, 160 bits, so buf is big enough */ - i2a_ASN1_INTEGER(biobuf, serialNumber); - len = BIO_gets(biobuf, buf, sizeof(buf)-1); - if (len < 0) { - _setSSLError(NULL, 0, __FILE__, __LINE__); - goto fail1; - } - sn_obj = PyString_FromStringAndSize(buf, len); - if (sn_obj == NULL) - goto fail1; - if (PyDict_SetItemString(retval, "serialNumber", sn_obj) < 0) { - Py_DECREF(sn_obj); - goto fail1; - } - Py_DECREF(sn_obj); - - (void) BIO_reset(biobuf); - notBefore = X509_get_notBefore(certificate); - ASN1_TIME_print(biobuf, notBefore); - len = BIO_gets(biobuf, buf, sizeof(buf)-1); - if (len < 0) { - _setSSLError(NULL, 0, __FILE__, __LINE__); - goto fail1; - } - pnotBefore = PyString_FromStringAndSize(buf, len); - if (pnotBefore == NULL) - goto fail1; - if (PyDict_SetItemString(retval, "notBefore", pnotBefore) < 0) { - Py_DECREF(pnotBefore); - goto fail1; - } - Py_DECREF(pnotBefore); - } - - (void) BIO_reset(biobuf); - notAfter = X509_get_notAfter(certificate); - ASN1_TIME_print(biobuf, notAfter); - len = BIO_gets(biobuf, buf, sizeof(buf)-1); - if (len < 0) { - _setSSLError(NULL, 0, __FILE__, __LINE__); - goto fail1; - } - pnotAfter = PyString_FromStringAndSize(buf, len); - if (pnotAfter == NULL) - goto fail1; - if (PyDict_SetItemString(retval, "notAfter", pnotAfter) < 0) { - Py_DECREF(pnotAfter); - goto fail1; - } - Py_DECREF(pnotAfter); - - /* Now look for subjectAltName */ - - peer_alt_names = _get_peer_alt_names(certificate); - if (peer_alt_names == NULL) - goto fail1; - else if (peer_alt_names != Py_None) { - if (PyDict_SetItemString(retval, "subjectAltName", - peer_alt_names) < 0) { - Py_DECREF(peer_alt_names); - goto fail1; - } - Py_DECREF(peer_alt_names); - } - - BIO_free(biobuf); - return retval; - - fail1: - if (biobuf != NULL) - BIO_free(biobuf); - fail0: - Py_XDECREF(retval); - return NULL; -} - - -static PyObject * -PySSL_test_decode_certificate (PyObject *mod, PyObject *args) { - - PyObject *retval = NULL; - char *filename = NULL; - X509 *x=NULL; - BIO *cert; - int verbose = 1; - - if (!PyArg_ParseTuple(args, "s|i:test_decode_certificate", &filename, &verbose)) - return NULL; - - if ((cert=BIO_new(BIO_s_file())) == NULL) { - PyErr_SetString(PySSLErrorObject, "Can't malloc memory to read file"); - goto fail0; - } - - if (BIO_read_filename(cert,filename) <= 0) { - PyErr_SetString(PySSLErrorObject, "Can't open file"); - goto fail0; - } - - x = PEM_read_bio_X509_AUX(cert,NULL, NULL, NULL); - if (x == NULL) { - PyErr_SetString(PySSLErrorObject, "Error decoding PEM-encoded file"); - goto fail0; - } - - retval = _decode_certificate(x, verbose); - - fail0: - - if (cert != NULL) BIO_free(cert); - return retval; -} - - -static PyObject * -PySSL_peercert(PySSLObject *self, PyObject *args) -{ - PyObject *retval = NULL; - int len; - int verification; - PyObject *binary_mode = Py_None; - - if (!PyArg_ParseTuple(args, "|O:peer_certificate", &binary_mode)) - return NULL; - - if (!self->peer_cert) - Py_RETURN_NONE; - - if (PyObject_IsTrue(binary_mode)) { - /* return cert in DER-encoded format */ - - unsigned char *bytes_buf = NULL; - - bytes_buf = NULL; - len = i2d_X509(self->peer_cert, &bytes_buf); - if (len < 0) { - PySSL_SetError(self, len, __FILE__, __LINE__); - return NULL; - } - retval = PyString_FromStringAndSize((const char *) bytes_buf, len); - OPENSSL_free(bytes_buf); - return retval; - - } else { - - verification = SSL_CTX_get_verify_mode(self->ctx); - if ((verification & SSL_VERIFY_PEER) == 0) - return PyDict_New(); - else - return _decode_certificate (self->peer_cert, 0); - } -} - -PyDoc_STRVAR(PySSL_peercert_doc, -"peer_certificate([der=False]) -> certificate\n\ -\n\ -Returns the certificate for the peer. If no certificate was provided,\n\ -returns None. If a certificate was provided, but not validated, returns\n\ -an empty dictionary. Otherwise returns a dict containing information\n\ -about the peer certificate.\n\ -\n\ -If the optional argument is True, returns a DER-encoded copy of the\n\ -peer certificate, or None if no certificate was provided. This will\n\ -return the certificate even if it wasn't validated."); - -static PyObject *PySSL_cipher (PySSLObject *self) { - - PyObject *retval, *v; - SSL_CIPHER *current; - char *cipher_name; - char *cipher_protocol; - - if (self->ssl == NULL) - return Py_None; - current = SSL_get_current_cipher(self->ssl); - if (current == NULL) - return Py_None; - - retval = PyTuple_New(3); - if (retval == NULL) - return NULL; - - cipher_name = (char *) SSL_CIPHER_get_name(current); - if (cipher_name == NULL) { - PyTuple_SET_ITEM(retval, 0, Py_None); - } else { - v = PyString_FromString(cipher_name); - if (v == NULL) - goto fail0; - PyTuple_SET_ITEM(retval, 0, v); - } - cipher_protocol = SSL_CIPHER_get_version(current); - if (cipher_protocol == NULL) { - PyTuple_SET_ITEM(retval, 1, Py_None); - } else { - v = PyString_FromString(cipher_protocol); - if (v == NULL) - goto fail0; - PyTuple_SET_ITEM(retval, 1, v); - } - v = PyInt_FromLong(SSL_CIPHER_get_bits(current, NULL)); - if (v == NULL) - goto fail0; - PyTuple_SET_ITEM(retval, 2, v); - return retval; - - fail0: - Py_DECREF(retval); - return NULL; -} - -static void PySSL_dealloc(PySSLObject *self) -{ - if (self->peer_cert) /* Possible not to have one? */ - X509_free (self->peer_cert); - if (self->ssl) - SSL_free(self->ssl); - if (self->ctx && self->inherited == 0) - SSL_CTX_free(self->ctx); - Py_XDECREF(self->Socket); - PyObject_Del(self); -} - -/* If the socket has a timeout, do a select()/poll() on the socket. - The argument writing indicates the direction. - Returns one of the possibilities in the timeout_state enum (above). - */ - -static int -check_socket_and_wait_for_timeout(PySocketSockObject *s, int writing) -{ - fd_set fds; - struct timeval tv; - int rc; - - /* Nothing to do unless we're in timeout mode (not non-blocking) */ - if (s->sock_timeout < 0.0) - return SOCKET_IS_BLOCKING; - else if (s->sock_timeout == 0.0) - return SOCKET_IS_NONBLOCKING; - - /* Guard against closed socket */ - if (s->sock_fd < 0) - return SOCKET_HAS_BEEN_CLOSED; - - /* Prefer poll, if available, since you can poll() any fd - * which can't be done with select(). */ -#ifdef HAVE_POLL - { - struct pollfd pollfd; - int timeout; - - pollfd.fd = s->sock_fd; - pollfd.events = writing ? POLLOUT : POLLIN; - - /* s->sock_timeout is in seconds, timeout in ms */ - timeout = (int)(s->sock_timeout * 1000 + 0.5); - PySSL_BEGIN_ALLOW_THREADS - rc = poll(&pollfd, 1, timeout); - PySSL_END_ALLOW_THREADS - - goto normal_return; - } -#endif - - /* Guard against socket too large for select*/ -#ifndef Py_SOCKET_FD_CAN_BE_GE_FD_SETSIZE - if (s->sock_fd >= FD_SETSIZE) - return SOCKET_TOO_LARGE_FOR_SELECT; -#endif - - /* Construct the arguments to select */ - tv.tv_sec = (int)s->sock_timeout; - tv.tv_usec = (int)((s->sock_timeout - tv.tv_sec) * 1e6); - FD_ZERO(&fds); - FD_SET(s->sock_fd, &fds); - - /* See if the socket is ready */ - PySSL_BEGIN_ALLOW_THREADS - if (writing) - rc = select(s->sock_fd+1, NULL, &fds, NULL, &tv); - else - rc = select(s->sock_fd+1, &fds, NULL, NULL, &tv); - PySSL_END_ALLOW_THREADS - -#ifdef HAVE_POLL -normal_return: -#endif - /* Return SOCKET_TIMED_OUT on timeout, SOCKET_OPERATION_OK otherwise - (when we are able to write or when there's something to read) */ - return rc == 0 ? SOCKET_HAS_TIMED_OUT : SOCKET_OPERATION_OK; -} - -static PyObject *PySSL_SSLwrite(PySSLObject *self, PyObject *args) -{ - char *data; - int len; - int count; - int sockstate; - int err; - int nonblocking; - - if (!PyArg_ParseTuple(args, "s#:write", &data, &count)) - return NULL; - - /* just in case the blocking state of the socket has been changed */ - nonblocking = (self->Socket->sock_timeout >= 0.0); - BIO_set_nbio(SSL_get_rbio(self->ssl), nonblocking); - BIO_set_nbio(SSL_get_wbio(self->ssl), nonblocking); - - sockstate = check_socket_and_wait_for_timeout(self->Socket, 1); - if (sockstate == SOCKET_HAS_TIMED_OUT) { - PyErr_SetString(PySSLErrorObject, - "The write operation timed out"); - return NULL; - } else if (sockstate == SOCKET_HAS_BEEN_CLOSED) { - PyErr_SetString(PySSLErrorObject, - "Underlying socket has been closed."); - return NULL; - } else if (sockstate == SOCKET_TOO_LARGE_FOR_SELECT) { - PyErr_SetString(PySSLErrorObject, - "Underlying socket too large for select()."); - return NULL; - } - do { - err = 0; - PySSL_BEGIN_ALLOW_THREADS - len = SSL_write(self->ssl, data, count); - err = SSL_get_error(self->ssl, len); - PySSL_END_ALLOW_THREADS - if(PyErr_CheckSignals()) { - return NULL; - } - if (err == SSL_ERROR_WANT_READ) { - sockstate = check_socket_and_wait_for_timeout(self->Socket, 0); - } else if (err == SSL_ERROR_WANT_WRITE) { - sockstate = check_socket_and_wait_for_timeout(self->Socket, 1); - } else { - sockstate = SOCKET_OPERATION_OK; - } - if (sockstate == SOCKET_HAS_TIMED_OUT) { - PyErr_SetString(PySSLErrorObject, - "The write operation timed out"); - return NULL; - } else if (sockstate == SOCKET_HAS_BEEN_CLOSED) { - PyErr_SetString(PySSLErrorObject, - "Underlying socket has been closed."); - return NULL; - } else if (sockstate == SOCKET_IS_NONBLOCKING) { - break; - } - } while (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE); - if (len > 0) - return PyInt_FromLong(len); - else - return PySSL_SetError(self, len, __FILE__, __LINE__); -} - -PyDoc_STRVAR(PySSL_SSLwrite_doc, -"write(s) -> len\n\ -\n\ -Writes the string s into the SSL object. Returns the number\n\ -of bytes written."); - -static PyObject *PySSL_SSLpending(PySSLObject *self) -{ - int count = 0; - - PySSL_BEGIN_ALLOW_THREADS - count = SSL_pending(self->ssl); - PySSL_END_ALLOW_THREADS - if (count < 0) - return PySSL_SetError(self, count, __FILE__, __LINE__); - else - return PyInt_FromLong(count); -} - -PyDoc_STRVAR(PySSL_SSLpending_doc, -"pending() -> count\n\ -\n\ -Returns the number of already decrypted bytes available for read,\n\ -pending on the connection.\n"); - -static PyObject *PySSL_SSLread(PySSLObject *self, PyObject *args) -{ - PyObject *buf; - int count = 0; - int len = 1024; - int sockstate; - int err; - int nonblocking; - - if (!PyArg_ParseTuple(args, "|i:read", &len)) - return NULL; - - if (!(buf = PyString_FromStringAndSize((char *) 0, len))) - return NULL; - - /* just in case the blocking state of the socket has been changed */ - nonblocking = (self->Socket->sock_timeout >= 0.0); - BIO_set_nbio(SSL_get_rbio(self->ssl), nonblocking); - BIO_set_nbio(SSL_get_wbio(self->ssl), nonblocking); - - /* first check if there are bytes ready to be read */ - PySSL_BEGIN_ALLOW_THREADS - count = SSL_pending(self->ssl); - PySSL_END_ALLOW_THREADS - - if (!count) { - sockstate = check_socket_and_wait_for_timeout(self->Socket, 0); - if (sockstate == SOCKET_HAS_TIMED_OUT) { - PyErr_SetString(PySSLErrorObject, - "The read operation timed out"); - Py_DECREF(buf); - return NULL; - } else if (sockstate == SOCKET_TOO_LARGE_FOR_SELECT) { - PyErr_SetString(PySSLErrorObject, - "Underlying socket too large for select()."); - Py_DECREF(buf); - return NULL; - } else if (sockstate == SOCKET_HAS_BEEN_CLOSED) { - if (SSL_get_shutdown(self->ssl) != - SSL_RECEIVED_SHUTDOWN) - { - Py_DECREF(buf); - PyErr_SetString(PySSLErrorObject, - "Socket closed without SSL shutdown handshake"); - return NULL; - } else { - /* should contain a zero-length string */ - _PyString_Resize(&buf, 0); - return buf; - } - } - } - do { - err = 0; - PySSL_BEGIN_ALLOW_THREADS - count = SSL_read(self->ssl, PyString_AsString(buf), len); - err = SSL_get_error(self->ssl, count); - PySSL_END_ALLOW_THREADS - if(PyErr_CheckSignals()) { - Py_DECREF(buf); - return NULL; - } - if (err == SSL_ERROR_WANT_READ) { - sockstate = check_socket_and_wait_for_timeout(self->Socket, 0); - } else if (err == SSL_ERROR_WANT_WRITE) { - sockstate = check_socket_and_wait_for_timeout(self->Socket, 1); - } else if ((err == SSL_ERROR_ZERO_RETURN) && - (SSL_get_shutdown(self->ssl) == - SSL_RECEIVED_SHUTDOWN)) - { - _PyString_Resize(&buf, 0); - return buf; - } else { - sockstate = SOCKET_OPERATION_OK; - } - if (sockstate == SOCKET_HAS_TIMED_OUT) { - PyErr_SetString(PySSLErrorObject, - "The read operation timed out"); - Py_DECREF(buf); - return NULL; - } else if (sockstate == SOCKET_IS_NONBLOCKING) { - break; - } - } while (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE); - if (count <= 0) { - Py_DECREF(buf); - return PySSL_SetError(self, count, __FILE__, __LINE__); - } - if (count != len) - _PyString_Resize(&buf, count); - return buf; -} - -PyDoc_STRVAR(PySSL_SSLread_doc, -"read([len]) -> string\n\ -\n\ -Read up to len bytes from the SSL socket."); - -static PyObject *PySSL_SSLshutdown(PySSLObject *self) -{ - int err, ssl_err, sockstate, nonblocking; - int zeros = 0; - - /* Guard against closed socket */ - if (self->Socket->sock_fd < 0) { - PyErr_SetString(PySSLErrorObject, - "Underlying socket has been closed."); - return NULL; - } - - /* Just in case the blocking state of the socket has been changed */ - nonblocking = (self->Socket->sock_timeout >= 0.0); - BIO_set_nbio(SSL_get_rbio(self->ssl), nonblocking); - BIO_set_nbio(SSL_get_wbio(self->ssl), nonblocking); - - while (1) { - PySSL_BEGIN_ALLOW_THREADS - /* Disable read-ahead so that unwrap can work correctly. - * Otherwise OpenSSL might read in too much data, - * eating clear text data that happens to be - * transmitted after the SSL shutdown. - * Should be safe to call repeatedly everytime this - * function is used and the shutdown_seen_zero != 0 - * condition is met. - */ - if (self->shutdown_seen_zero) - SSL_set_read_ahead(self->ssl, 0); - err = SSL_shutdown(self->ssl); - PySSL_END_ALLOW_THREADS - /* If err == 1, a secure shutdown with SSL_shutdown() is complete */ - if (err > 0) - break; - if (err == 0) { - /* Don't loop endlessly; instead preserve legacy - behaviour of trying SSL_shutdown() only twice. - This looks necessary for OpenSSL < 0.9.8m */ - if (++zeros > 1) - break; - /* Shutdown was sent, now try receiving */ - self->shutdown_seen_zero = 1; - continue; - } - - /* Possibly retry shutdown until timeout or failure */ - ssl_err = SSL_get_error(self->ssl, err); - if (ssl_err == SSL_ERROR_WANT_READ) - sockstate = check_socket_and_wait_for_timeout(self->Socket, 0); - else if (ssl_err == SSL_ERROR_WANT_WRITE) - sockstate = check_socket_and_wait_for_timeout(self->Socket, 1); - else - break; - if (sockstate == SOCKET_HAS_TIMED_OUT) { - if (ssl_err == SSL_ERROR_WANT_READ) - PyErr_SetString(PySSLErrorObject, - "The read operation timed out"); - else - PyErr_SetString(PySSLErrorObject, - "The write operation timed out"); - return NULL; - } - else if (sockstate == SOCKET_TOO_LARGE_FOR_SELECT) { - PyErr_SetString(PySSLErrorObject, - "Underlying socket too large for select()."); - return NULL; - } - else if (sockstate != SOCKET_OPERATION_OK) - /* Retain the SSL error code */ - break; - } - - if (err < 0) - return PySSL_SetError(self, err, __FILE__, __LINE__); - else { - Py_INCREF(self->Socket); - return (PyObject *) (self->Socket); - } -} - -PyDoc_STRVAR(PySSL_SSLshutdown_doc, -"shutdown(s) -> socket\n\ -\n\ -Does the SSL shutdown handshake with the remote end, and returns\n\ -the underlying socket object."); - -static PyMethodDef PySSLMethods[] = { - {"wrap_accepted", (PyCFunction)PySSL_SSLwrap_accepted, METH_VARARGS, - PySSL_SSLwrap_accepted_doc}, - {"do_handshake", (PyCFunction)PySSL_SSLdo_handshake, METH_NOARGS}, - {"write", (PyCFunction)PySSL_SSLwrite, METH_VARARGS, - PySSL_SSLwrite_doc}, - {"read", (PyCFunction)PySSL_SSLread, METH_VARARGS, - PySSL_SSLread_doc}, - {"pending", (PyCFunction)PySSL_SSLpending, METH_NOARGS, - PySSL_SSLpending_doc}, - {"server", (PyCFunction)PySSL_server, METH_NOARGS}, - {"issuer", (PyCFunction)PySSL_issuer, METH_NOARGS}, - {"peer_certificate", (PyCFunction)PySSL_peercert, METH_VARARGS, - PySSL_peercert_doc}, - {"cipher", (PyCFunction)PySSL_cipher, METH_NOARGS}, - {"shutdown", (PyCFunction)PySSL_SSLshutdown, METH_NOARGS, - PySSL_SSLshutdown_doc}, - {NULL, NULL} -}; - -static PyObject *PySSL_getattr(PySSLObject *self, char *name) -{ - return Py_FindMethod(PySSLMethods, (PyObject *)self, name); -} - -static PyTypeObject PySSL_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "ssl.SSLContext", /*tp_name*/ - sizeof(PySSLObject), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - /* methods */ - (destructor)PySSL_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ - (getattrfunc)PySSL_getattr, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash*/ -}; - -#ifdef HAVE_OPENSSL_RAND - -/* helper routines for seeding the SSL PRNG */ -static PyObject * -PySSL_RAND_add(PyObject *self, PyObject *args) -{ - char *buf; - int len; - double entropy; - - if (!PyArg_ParseTuple(args, "s#d:RAND_add", &buf, &len, &entropy)) - return NULL; - RAND_add(buf, len, entropy); - Py_INCREF(Py_None); - return Py_None; -} - -PyDoc_STRVAR(PySSL_RAND_add_doc, -"RAND_add(string, entropy)\n\ -\n\ -Mix string into the OpenSSL PRNG state. entropy (a float) is a lower\n\ -bound on the entropy contained in string. See RFC 1750."); - -static PyObject * -PySSL_RAND_status(PyObject *self) -{ - return PyInt_FromLong(RAND_status()); -} - -PyDoc_STRVAR(PySSL_RAND_status_doc, -"RAND_status() -> 0 or 1\n\ -\n\ -Returns 1 if the OpenSSL PRNG has been seeded with enough data and 0 if not.\n\ -It is necessary to seed the PRNG with RAND_add() on some platforms before\n\ -using the ssl() function."); - -static PyObject * -PySSL_RAND_egd(PyObject *self, PyObject *arg) -{ - int bytes; - - if (!PyString_Check(arg)) - return PyErr_Format(PyExc_TypeError, - "RAND_egd() expected string, found %s", - Py_TYPE(arg)->tp_name); - bytes = RAND_egd(PyString_AS_STRING(arg)); - if (bytes == -1) { - PyErr_SetString(PySSLErrorObject, - "EGD connection failed or EGD did not return " - "enough data to seed the PRNG"); - return NULL; - } - return PyInt_FromLong(bytes); -} - -PyDoc_STRVAR(PySSL_RAND_egd_doc, -"RAND_egd(path) -> bytes\n\ -\n\ -Queries the entropy gather daemon (EGD) on the socket named by 'path'.\n\ -Returns number of bytes read. Raises SSLError if connection to EGD\n\ -fails or if it does provide enough data to seed PRNG."); - -#endif - -/* List of functions exported by this module. */ - -static PyMethodDef PySSL_methods[] = { - {"sslwrap", PySSL_sslwrap, - METH_VARARGS, sslwrap_doc}, - {"_test_decode_cert", PySSL_test_decode_certificate, - METH_VARARGS}, -#ifdef HAVE_OPENSSL_RAND - {"RAND_add", PySSL_RAND_add, METH_VARARGS, - PySSL_RAND_add_doc}, - {"RAND_egd", PySSL_RAND_egd, METH_O, - PySSL_RAND_egd_doc}, - {"RAND_status", (PyCFunction)PySSL_RAND_status, METH_NOARGS, - PySSL_RAND_status_doc}, -#endif - {NULL, NULL} /* Sentinel */ -}; - - -#ifdef WITH_THREAD - -/* an implementation of OpenSSL threading operations in terms - of the Python C thread library */ - -static PyThread_type_lock *_ssl_locks = NULL; - -static unsigned long _ssl_thread_id_function (void) { - return PyThread_get_thread_ident(); -} - -static void _ssl_thread_locking_function (int mode, int n, const char *file, int line) { - /* this function is needed to perform locking on shared data - structures. (Note that OpenSSL uses a number of global data - structures that will be implicitly shared whenever multiple threads - use OpenSSL.) Multi-threaded applications will crash at random if - it is not set. - - locking_function() must be able to handle up to CRYPTO_num_locks() - different mutex locks. It sets the n-th lock if mode & CRYPTO_LOCK, and - releases it otherwise. - - file and line are the file number of the function setting the - lock. They can be useful for debugging. - */ - - if ((_ssl_locks == NULL) || - (n < 0) || ((unsigned)n >= _ssl_locks_count)) - return; - - if (mode & CRYPTO_LOCK) { - PyThread_acquire_lock(_ssl_locks[n], 1); - } else { - PyThread_release_lock(_ssl_locks[n]); - } -} - -static int _setup_ssl_threads(void) { - - unsigned int i; - - if (_ssl_locks == NULL) { - _ssl_locks_count = CRYPTO_num_locks(); - _ssl_locks = (PyThread_type_lock *) - malloc(sizeof(PyThread_type_lock) * _ssl_locks_count); - if (_ssl_locks == NULL) - return 0; - memset(_ssl_locks, 0, sizeof(PyThread_type_lock) * _ssl_locks_count); - for (i = 0; i < _ssl_locks_count; i++) { - _ssl_locks[i] = PyThread_allocate_lock(); - if (_ssl_locks[i] == NULL) { - unsigned int j; - for (j = 0; j < i; j++) { - PyThread_free_lock(_ssl_locks[j]); - } - free(_ssl_locks); - return 0; - } - } - CRYPTO_set_locking_callback(_ssl_thread_locking_function); - CRYPTO_set_id_callback(_ssl_thread_id_function); - } - return 1; -} - -#endif /* def HAVE_THREAD */ - -PyDoc_STRVAR(module_doc, -"Implementation module for SSL socket operations. See the socket module\n\ -for documentation."); - -PyMODINIT_FUNC -init_forge_ssl(void) -{ - PyObject *m, *d; - - Py_TYPE(&PySSL_Type) = &PyType_Type; - - m = Py_InitModule3("_forge_ssl", PySSL_methods, module_doc); - if (m == NULL) - return; - d = PyModule_GetDict(m); - - /* Load _socket module and its C API */ - if (PySocketModule_ImportModuleAndAPI()) - return; - - /* Init OpenSSL */ - SSL_load_error_strings(); - SSL_library_init(); -#ifdef WITH_THREAD - /* note that this will start threading if not already started */ - if (!_setup_ssl_threads()) { - return; - } -#endif - OpenSSL_add_all_algorithms(); - - /* Add symbols to module dict */ - PySSLErrorObject = PyErr_NewException("ssl.SSLError", - PySocketModule.error, - NULL); - if (PySSLErrorObject == NULL) - return; - if (PyDict_SetItemString(d, "SSLError", PySSLErrorObject) != 0) - return; - if (PyDict_SetItemString(d, "SSLType", - (PyObject *)&PySSL_Type) != 0) - return; - PyModule_AddIntConstant(m, "SSL_ERROR_ZERO_RETURN", - PY_SSL_ERROR_ZERO_RETURN); - PyModule_AddIntConstant(m, "SSL_ERROR_WANT_READ", - PY_SSL_ERROR_WANT_READ); - PyModule_AddIntConstant(m, "SSL_ERROR_WANT_WRITE", - PY_SSL_ERROR_WANT_WRITE); - PyModule_AddIntConstant(m, "SSL_ERROR_WANT_X509_LOOKUP", - PY_SSL_ERROR_WANT_X509_LOOKUP); - PyModule_AddIntConstant(m, "SSL_ERROR_SYSCALL", - PY_SSL_ERROR_SYSCALL); - PyModule_AddIntConstant(m, "SSL_ERROR_SSL", - PY_SSL_ERROR_SSL); - PyModule_AddIntConstant(m, "SSL_ERROR_WANT_CONNECT", - PY_SSL_ERROR_WANT_CONNECT); - /* non ssl.h errorcodes */ - PyModule_AddIntConstant(m, "SSL_ERROR_EOF", - PY_SSL_ERROR_EOF); - PyModule_AddIntConstant(m, "SSL_ERROR_INVALID_ERROR_CODE", - PY_SSL_ERROR_INVALID_ERROR_CODE); - /* cert requirements */ - PyModule_AddIntConstant(m, "CERT_NONE", - PY_SSL_CERT_NONE); - PyModule_AddIntConstant(m, "CERT_OPTIONAL", - PY_SSL_CERT_OPTIONAL); - PyModule_AddIntConstant(m, "CERT_REQUIRED", - PY_SSL_CERT_REQUIRED); - - /* protocol versions */ - PyModule_AddIntConstant(m, "PROTOCOL_SSLv2", - PY_SSL_VERSION_SSL2); - PyModule_AddIntConstant(m, "PROTOCOL_SSLv3", - PY_SSL_VERSION_SSL3); - PyModule_AddIntConstant(m, "PROTOCOL_SSLv23", - PY_SSL_VERSION_SSL23); - PyModule_AddIntConstant(m, "PROTOCOL_TLSv1", - PY_SSL_VERSION_TLS1); - - /* session cache modes */ - PyModule_AddIntConstant(m, "SESS_CACHE_OFF", - PY_SSL_SESS_CACHE_OFF); - PyModule_AddIntConstant(m, "SESS_CACHE_CLIENT", - PY_SSL_SESS_CACHE_CLIENT); - PyModule_AddIntConstant(m, "SESS_CACHE_SERVER", - PY_SSL_SESS_CACHE_SERVER); - PyModule_AddIntConstant(m, "SESS_CACHE_BOTH", - PY_SSL_SESS_CACHE_BOTH); -} diff --git a/alarm/node_modules/node-forge/tests/forge_ssl/forge/socketmodule.h b/alarm/node_modules/node-forge/tests/forge_ssl/forge/socketmodule.h deleted file mode 100644 index a4415b5..0000000 --- a/alarm/node_modules/node-forge/tests/forge_ssl/forge/socketmodule.h +++ /dev/null @@ -1,268 +0,0 @@ -/* Socket module header file */ - -/* Includes needed for the sockaddr_* symbols below */ -#ifndef MS_WINDOWS -#ifdef __VMS -# include <socket.h> -# else -# include <sys/socket.h> -# endif -# include <netinet/in.h> -# if !(defined(__BEOS__) || defined(__CYGWIN__) || (defined(PYOS_OS2) && defined(PYCC_VACPP))) -# include <netinet/tcp.h> -# endif - -#else /* MS_WINDOWS */ -# include <winsock2.h> -# include <ws2tcpip.h> -/* VC6 is shipped with old platform headers, and does not have MSTcpIP.h - * Separate SDKs have all the functions we want, but older ones don't have - * any version information. - * I use SIO_GET_MULTICAST_FILTER to detect a decent SDK. - */ -# ifdef SIO_GET_MULTICAST_FILTER -# include <MSTcpIP.h> /* for SIO_RCVALL */ -# define HAVE_ADDRINFO -# define HAVE_SOCKADDR_STORAGE -# define HAVE_GETADDRINFO -# define HAVE_GETNAMEINFO -# define ENABLE_IPV6 -# else -typedef int socklen_t; -# endif /* IPPROTO_IPV6 */ -#endif /* MS_WINDOWS */ - -#ifdef HAVE_SYS_UN_H -# include <sys/un.h> -#else -# undef AF_UNIX -#endif - -#ifdef HAVE_LINUX_NETLINK_H -# ifdef HAVE_ASM_TYPES_H -# include <asm/types.h> -# endif -# include <linux/netlink.h> -#else -# undef AF_NETLINK -#endif - -#ifdef HAVE_BLUETOOTH_BLUETOOTH_H -/* -#include <bluetooth/bluetooth.h> -#include <bluetooth/rfcomm.h> -#include <bluetooth/l2cap.h> -#include <bluetooth/sco.h> -#include <bluetooth/hci.h> -*/ -#endif - -#ifdef HAVE_BLUETOOTH_H -#include <bluetooth.h> -#endif - -#ifdef HAVE_NETPACKET_PACKET_H -# include <sys/ioctl.h> -# include <net/if.h> -# include <netpacket/packet.h> -#endif - -#ifdef HAVE_LINUX_TIPC_H -# include <linux/tipc.h> -#endif - -#ifndef Py__SOCKET_H -#define Py__SOCKET_H -#ifdef __cplusplus -extern "C" { -#endif - -/* Python module and C API name */ -#define PySocket_MODULE_NAME "_socket" -#define PySocket_CAPI_NAME "CAPI" - -/* Abstract the socket file descriptor type */ -#ifdef MS_WINDOWS -typedef SOCKET SOCKET_T; -# ifdef MS_WIN64 -# define SIZEOF_SOCKET_T 8 -# else -# define SIZEOF_SOCKET_T 4 -# endif -#else -typedef int SOCKET_T; -# define SIZEOF_SOCKET_T SIZEOF_INT -#endif - -/* Socket address */ -typedef union sock_addr { - struct sockaddr_in in; -#ifdef AF_UNIX - struct sockaddr_un un; -#endif -#ifdef AF_NETLINK - struct sockaddr_nl nl; -#endif -#ifdef ENABLE_IPV6 - struct sockaddr_in6 in6; - struct sockaddr_storage storage; -#endif -#ifdef HAVE_BLUETOOTH_BLUETOOTH_H -/* - struct sockaddr_l2 bt_l2; - struct sockaddr_rc bt_rc; - struct sockaddr_sco bt_sco; - struct sockaddr_hci bt_hci; -*/ -#endif -#ifdef HAVE_NETPACKET_PACKET_H - struct sockaddr_ll ll; -#endif -} sock_addr_t; - -/* The object holding a socket. It holds some extra information, - like the address family, which is used to decode socket address - arguments properly. */ - -typedef struct { - PyObject_HEAD - SOCKET_T sock_fd; /* Socket file descriptor */ - int sock_family; /* Address family, e.g., AF_INET */ - int sock_type; /* Socket type, e.g., SOCK_STREAM */ - int sock_proto; /* Protocol type, usually 0 */ - PyObject *(*errorhandler)(void); /* Error handler; checks - errno, returns NULL and - sets a Python exception */ - double sock_timeout; /* Operation timeout in seconds; - 0.0 means non-blocking */ -} PySocketSockObject; - -/* --- C API ----------------------------------------------------*/ - -/* Short explanation of what this C API export mechanism does - and how it works: - - The _ssl module needs access to the type object defined in - the _socket module. Since cross-DLL linking introduces a lot of - problems on many platforms, the "trick" is to wrap the - C API of a module in a struct which then gets exported to - other modules via a PyCObject. - - The code in socketmodule.c defines this struct (which currently - only contains the type object reference, but could very - well also include other C APIs needed by other modules) - and exports it as PyCObject via the module dictionary - under the name "CAPI". - - Other modules can now include the socketmodule.h file - which defines the needed C APIs to import and set up - a static copy of this struct in the importing module. - - After initialization, the importing module can then - access the C APIs from the _socket module by simply - referring to the static struct, e.g. - - Load _socket module and its C API; this sets up the global - PySocketModule: - - if (PySocketModule_ImportModuleAndAPI()) - return; - - - Now use the C API as if it were defined in the using - module: - - if (!PyArg_ParseTuple(args, "O!|zz:ssl", - - PySocketModule.Sock_Type, - - (PyObject*)&Sock, - &key_file, &cert_file)) - return NULL; - - Support could easily be extended to export more C APIs/symbols - this way. Currently, only the type object is exported, - other candidates would be socket constructors and socket - access functions. - -*/ - -/* C API for usage by other Python modules */ -typedef struct { - PyTypeObject *Sock_Type; - PyObject *error; -} PySocketModule_APIObject; - -/* XXX The net effect of the following appears to be to define a function - XXX named PySocketModule_APIObject in _ssl.c. It's unclear why it isn't - XXX defined there directly. - - >>> It's defined here because other modules might also want to use - >>> the C API. - -*/ -#ifndef PySocket_BUILDING_SOCKET - -/* --- C API ----------------------------------------------------*/ - -/* Interfacestructure to C API for other modules. - Call PySocketModule_ImportModuleAndAPI() to initialize this - structure. After that usage is simple: - - if (!PyArg_ParseTuple(args, "O!|zz:ssl", - &PySocketModule.Sock_Type, (PyObject*)&Sock, - &key_file, &cert_file)) - return NULL; - ... -*/ - -static -PySocketModule_APIObject PySocketModule; - -/* You *must* call this before using any of the functions in - PySocketModule and check its outcome; otherwise all accesses will - result in a segfault. Returns 0 on success. */ - -#ifndef DPRINTF -# define DPRINTF if (0) printf -#endif - -static -int PySocketModule_ImportModuleAndAPI(void) -{ - PyObject *mod = 0, *v = 0; - char *apimodule = PySocket_MODULE_NAME; - char *apiname = PySocket_CAPI_NAME; - void *api; - - DPRINTF("Importing the %s C API...\n", apimodule); - mod = PyImport_ImportModuleNoBlock(apimodule); - if (mod == NULL) - goto onError; - DPRINTF(" %s package found\n", apimodule); - v = PyObject_GetAttrString(mod, apiname); - if (v == NULL) - goto onError; - Py_DECREF(mod); - DPRINTF(" API object %s found\n", apiname); - api = PyCObject_AsVoidPtr(v); - if (api == NULL) - goto onError; - Py_DECREF(v); - memcpy(&PySocketModule, api, sizeof(PySocketModule)); - DPRINTF(" API object loaded and initialized.\n"); - return 0; - - onError: - DPRINTF(" not found.\n"); - Py_XDECREF(mod); - Py_XDECREF(v); - return -1; -} - -#endif /* !PySocket_BUILDING_SOCKET */ - -#ifdef __cplusplus -} -#endif -#endif /* !Py__SOCKET_H */ diff --git a/alarm/node_modules/node-forge/tests/forge_ssl/forge/ssl.py b/alarm/node_modules/node-forge/tests/forge_ssl/forge/ssl.py deleted file mode 100644 index aa9fc14..0000000 --- a/alarm/node_modules/node-forge/tests/forge_ssl/forge/ssl.py +++ /dev/null @@ -1,486 +0,0 @@ -# Wrapper module for _ssl, providing some additional facilities -# implemented in Python. Written by Bill Janssen. - -"""\ -This module provides some more Pythonic support for SSL. - -Object types: - - SSLSocket -- subtype of socket.socket which does SSL over the socket - -Exceptions: - - SSLError -- exception raised for I/O errors - -Functions: - - cert_time_to_seconds -- convert time string used for certificate - notBefore and notAfter functions to integer - seconds past the Epoch (the time values - returned from time.time()) - - fetch_server_certificate (HOST, PORT) -- fetch the certificate provided - by the server running on HOST at port PORT. No - validation of the certificate is performed. - -Integer constants: - -SSL_ERROR_ZERO_RETURN -SSL_ERROR_WANT_READ -SSL_ERROR_WANT_WRITE -SSL_ERROR_WANT_X509_LOOKUP -SSL_ERROR_SYSCALL -SSL_ERROR_SSL -SSL_ERROR_WANT_CONNECT - -SSL_ERROR_EOF -SSL_ERROR_INVALID_ERROR_CODE - -The following group define certificate requirements that one side is -allowing/requiring from the other side: - -CERT_NONE - no certificates from the other side are required (or will - be looked at if provided) -CERT_OPTIONAL - certificates are not required, but if provided will be - validated, and if validation fails, the connection will - also fail -CERT_REQUIRED - certificates are required, and will be validated, and - if validation fails, the connection will also fail - -The following constants identify various SSL protocol variants: - -PROTOCOL_SSLv2 -PROTOCOL_SSLv3 -PROTOCOL_SSLv23 -PROTOCOL_TLSv1 - -The following constants identify various SSL session caching modes: - -SESS_CACHE_OFF -SESS_CACHE_CLIENT -SESS_CACHE_SERVER -SESS_CACHE_BOTH -""" - -import textwrap - -import _forge_ssl # if we can't import it, let the error propagate - -from _forge_ssl import SSLError -from _forge_ssl import CERT_NONE, CERT_OPTIONAL, CERT_REQUIRED -from _forge_ssl import PROTOCOL_SSLv2, PROTOCOL_SSLv3, PROTOCOL_SSLv23, PROTOCOL_TLSv1 -from _forge_ssl import SESS_CACHE_OFF, SESS_CACHE_CLIENT, SESS_CACHE_SERVER, SESS_CACHE_BOTH -from _forge_ssl import RAND_status, RAND_egd, RAND_add -from _forge_ssl import \ - SSL_ERROR_ZERO_RETURN, \ - SSL_ERROR_WANT_READ, \ - SSL_ERROR_WANT_WRITE, \ - SSL_ERROR_WANT_X509_LOOKUP, \ - SSL_ERROR_SYSCALL, \ - SSL_ERROR_SSL, \ - SSL_ERROR_WANT_CONNECT, \ - SSL_ERROR_EOF, \ - SSL_ERROR_INVALID_ERROR_CODE - -from socket import socket, _fileobject, _delegate_methods -from socket import error as socket_error -from socket import getnameinfo as _getnameinfo -import base64 # for DER-to-PEM translation -import errno - -class SSLSocket(socket): - - """This class implements a subtype of socket.socket that wraps - the underlying OS socket in an SSL context when necessary, and - provides read and write methods over that channel.""" - - def __init__(self, parent_socket, sock, keyfile=None, certfile=None, - server_side=False, cert_reqs=CERT_NONE, - ssl_version=PROTOCOL_SSLv23, - sess_cache_mode=SESS_CACHE_SERVER, - sess_id_ctx=None, - ca_certs=None, - do_handshake_on_connect=True, - suppress_ragged_eofs=True): - socket.__init__(self, _sock=sock._sock) - # The initializer for socket overrides the methods send(), recv(), etc. - # in the instancce, which we don't need -- but we want to provide the - # methods defined in SSLSocket. - for attr in _delegate_methods: - try: - delattr(self, attr) - except AttributeError: - pass - - if certfile and not keyfile: - keyfile = certfile - - create = True - connected = False - if not server_side: - # see if it's connected - try: - socket.getpeername(self) - connected = True - except socket_error, e: - if e.errno != errno.ENOTCONN: - raise - # no, no connection yet - self._sslobj = None - create = False - if create: - # yes, create the SSL object - if parent_socket == None: - self._sslobj = _forge_ssl.sslwrap( - self._sock, - server_side, - keyfile, certfile, - cert_reqs, ssl_version, - sess_cache_mode, sess_id_ctx, - ca_certs) - else: - self._sslobj = parent_socket._sslobj.wrap_accepted(self._sock) - - if connected and do_handshake_on_connect: - self.do_handshake() - self.keyfile = keyfile - self.certfile = certfile - self.cert_reqs = cert_reqs - self.ssl_version = ssl_version - self.sess_cache_mode = sess_cache_mode - self.sess_id_ctx = sess_id_ctx - self.ca_certs = ca_certs - self.do_handshake_on_connect = do_handshake_on_connect - self.suppress_ragged_eofs = suppress_ragged_eofs - self._makefile_refs = 0 - - def read(self, len=1024): - - """Read up to LEN bytes and return them. - Return zero-length string on EOF.""" - - try: - return self._sslobj.read(len) - except SSLError, x: - if x.args[0] == SSL_ERROR_EOF and self.suppress_ragged_eofs: - return '' - else: - raise - - def write(self, data): - - """Write DATA to the underlying SSL channel. Returns - number of bytes of DATA actually transmitted.""" - - return self._sslobj.write(data) - - def getpeercert(self, binary_form=False): - - """Returns a formatted version of the data in the - certificate provided by the other end of the SSL channel. - Return None if no certificate was provided, {} if a - certificate was provided, but not validated.""" - - return self._sslobj.peer_certificate(binary_form) - - def cipher(self): - - if not self._sslobj: - return None - else: - return self._sslobj.cipher() - - def send(self, data, flags=0): - if self._sslobj: - if flags != 0: - raise ValueError( - "non-zero flags not allowed in calls to send() on %s" % - self.__class__) - while True: - try: - v = self._sslobj.write(data) - except SSLError, x: - if x.args[0] == SSL_ERROR_WANT_READ: - return 0 - elif x.args[0] == SSL_ERROR_WANT_WRITE: - return 0 - else: - raise - else: - return v - else: - return socket.send(self, data, flags) - - def sendto(self, data, addr, flags=0): - if self._sslobj: - raise ValueError("sendto not allowed on instances of %s" % - self.__class__) - else: - return socket.sendto(self, data, addr, flags) - - def sendall(self, data, flags=0): - if self._sslobj: - if flags != 0: - raise ValueError( - "non-zero flags not allowed in calls to sendall() on %s" % - self.__class__) - amount = len(data) - count = 0 - while (count < amount): - v = self.send(data[count:]) - count += v - return amount - else: - return socket.sendall(self, data, flags) - - def recv(self, buflen=1024, flags=0): - if self._sslobj: - if flags != 0: - raise ValueError( - "non-zero flags not allowed in calls to recv() on %s" % - self.__class__) - return self.read(buflen) - else: - return socket.recv(self, buflen, flags) - - def recv_into(self, buffer, nbytes=None, flags=0): - if buffer and (nbytes is None): - nbytes = len(buffer) - elif nbytes is None: - nbytes = 1024 - if self._sslobj: - if flags != 0: - raise ValueError( - "non-zero flags not allowed in calls to recv_into() on %s" % - self.__class__) - tmp_buffer = self.read(nbytes) - v = len(tmp_buffer) - buffer[:v] = tmp_buffer - return v - else: - return socket.recv_into(self, buffer, nbytes, flags) - - def recvfrom(self, addr, buflen=1024, flags=0): - if self._sslobj: - raise ValueError("recvfrom not allowed on instances of %s" % - self.__class__) - else: - return socket.recvfrom(self, addr, buflen, flags) - - def recvfrom_into(self, buffer, nbytes=None, flags=0): - if self._sslobj: - raise ValueError("recvfrom_into not allowed on instances of %s" % - self.__class__) - else: - return socket.recvfrom_into(self, buffer, nbytes, flags) - - def pending(self): - if self._sslobj: - return self._sslobj.pending() - else: - return 0 - - def unwrap(self): - if self._sslobj: - try: - # if connected then shutdown - self.getpeername() - s = self._sslobj.shutdown() - except: - s = self._sock - self._sslobj = None - return s - else: - raise ValueError("No SSL wrapper around " + str(self)) - - def shutdown(self, how): - self._sslobj = None - socket.shutdown(self, how) - - def close(self): - if self._makefile_refs < 1: - if self._sslobj: - self.unwrap() - socket.close(self) - else: - self._makefile_refs -= 1 - - def do_handshake(self): - - """Perform a TLS/SSL handshake.""" - - self._sslobj.do_handshake() - - def connect(self, addr): - - """Connects to remote ADDR, and then wraps the connection in - an SSL channel.""" - - # Here we assume that the socket is client-side, and not - # connected at the time of the call. We connect it, then wrap it. - if self._sslobj: - raise ValueError("attempt to connect already-connected SSLSocket!") - socket.connect(self, addr) - self._sslobj = _forge_ssl.sslwrap(self._sock, False, - self.keyfile, self.certfile, - self.cert_reqs, self.ssl_version, - self.sess_cache_mode, - self.sess_id_ctx, - self.ca_certs) - if self.do_handshake_on_connect: - self.do_handshake() - - def accept(self): - - """Accepts a new connection from a remote client, and returns - a tuple containing that new connection wrapped with a server-side - SSL channel, and the address of the remote client.""" - - newsock, addr = socket.accept(self) - return (SSLSocket(self, - newsock, - keyfile=self.keyfile, - certfile=self.certfile, - server_side=True, - cert_reqs=self.cert_reqs, - ssl_version=self.ssl_version, - sess_cache_mode=self.sess_cache_mode, - sess_id_ctx=self.sess_id_ctx, - ca_certs=self.ca_certs, - do_handshake_on_connect=self.do_handshake_on_connect, - suppress_ragged_eofs=self.suppress_ragged_eofs), - addr) - - def makefile(self, mode='r', bufsize=-1): - - """Make and return a file-like object that - works with the SSL connection. Just use the code - from the socket module.""" - - self._makefile_refs += 1 - # close=True so as to decrement the reference count when done with - # the file-like object. - return _fileobject(self, mode, bufsize, close=True) - - - -def wrap_socket(sock, parent_socket=None, keyfile=None, certfile=None, - server_side=False, cert_reqs=CERT_NONE, - ssl_version=PROTOCOL_SSLv23, - sess_cache_mode=SESS_CACHE_SERVER, - sess_id_ctx=None, - ca_certs=None, - do_handshake_on_connect=True, - suppress_ragged_eofs=True): - - return SSLSocket(parent_socket, - sock, keyfile=keyfile, certfile=certfile, - server_side=server_side, cert_reqs=cert_reqs, - ssl_version=ssl_version, - sess_cache_mode=sess_cache_mode, - sess_id_ctx=sess_id_ctx, - ca_certs=ca_certs, - do_handshake_on_connect=do_handshake_on_connect, - suppress_ragged_eofs=suppress_ragged_eofs) - - -# some utility functions - -def cert_time_to_seconds(cert_time): - - """Takes a date-time string in standard ASN1_print form - ("MON DAY 24HOUR:MINUTE:SEC YEAR TIMEZONE") and return - a Python time value in seconds past the epoch.""" - - import time - return time.mktime(time.strptime(cert_time, "%b %d %H:%M:%S %Y GMT")) - -PEM_HEADER = "-----BEGIN CERTIFICATE-----" -PEM_FOOTER = "-----END CERTIFICATE-----" - -def DER_cert_to_PEM_cert(der_cert_bytes): - - """Takes a certificate in binary DER format and returns the - PEM version of it as a string.""" - - if hasattr(base64, 'standard_b64encode'): - # preferred because older API gets line-length wrong - f = base64.standard_b64encode(der_cert_bytes) - return (PEM_HEADER + '\n' + - textwrap.fill(f, 64) + '\n' + - PEM_FOOTER + '\n') - else: - return (PEM_HEADER + '\n' + - base64.encodestring(der_cert_bytes) + - PEM_FOOTER + '\n') - -def PEM_cert_to_DER_cert(pem_cert_string): - - """Takes a certificate in ASCII PEM format and returns the - DER-encoded version of it as a byte sequence""" - - if not pem_cert_string.startswith(PEM_HEADER): - raise ValueError("Invalid PEM encoding; must start with %s" - % PEM_HEADER) - if not pem_cert_string.strip().endswith(PEM_FOOTER): - raise ValueError("Invalid PEM encoding; must end with %s" - % PEM_FOOTER) - d = pem_cert_string.strip()[len(PEM_HEADER):-len(PEM_FOOTER)] - return base64.decodestring(d) - -def get_server_certificate(addr, ssl_version=PROTOCOL_SSLv3, ca_certs=None): - - """Retrieve the certificate from the server at the specified address, - and return it as a PEM-encoded string. - If 'ca_certs' is specified, validate the server cert against it. - If 'ssl_version' is specified, use it in the connection attempt.""" - - host, port = addr - if (ca_certs is not None): - cert_reqs = CERT_REQUIRED - else: - cert_reqs = CERT_NONE - s = wrap_socket(socket(), ssl_version=ssl_version, - cert_reqs=cert_reqs, ca_certs=ca_certs) - s.connect(addr) - dercert = s.getpeercert(True) - s.close() - return DER_cert_to_PEM_cert(dercert) - -def get_protocol_name(protocol_code): - if protocol_code == PROTOCOL_TLSv1: - return "TLSv1" - elif protocol_code == PROTOCOL_SSLv23: - return "SSLv23" - elif protocol_code == PROTOCOL_SSLv2: - return "SSLv2" - elif protocol_code == PROTOCOL_SSLv3: - return "SSLv3" - else: - return "<unknown>" - - -# a replacement for the old socket.ssl function - -def sslwrap_simple(sock, keyfile=None, certfile=None): - - """A replacement for the old socket.ssl function. Designed - for compability with Python 2.5 and earlier. Will disappear in - Python 3.0.""" - - if hasattr(sock, "_sock"): - sock = sock._sock - - ssl_sock = _forge_ssl.sslwrap(sock, 0, keyfile, certfile, - CERT_NONE, PROTOCOL_SSLv23, - SESS_CACHE_SERVER, None, None) - try: - sock.getpeername() - except: - # no, no connection yet - pass - else: - # yes, do the handshake - ssl_sock.do_handshake() - - return ssl_sock diff --git a/alarm/node_modules/node-forge/tests/forge_ssl/setup.py b/alarm/node_modules/node-forge/tests/forge_ssl/setup.py deleted file mode 100644 index 350ae37..0000000 --- a/alarm/node_modules/node-forge/tests/forge_ssl/setup.py +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env python - -from distutils.core import setup, Extension - -ssl = Extension('_forge_ssl', - sources = ['forge/_ssl.c']) - -setup (name = 'Forge SSL', - version = '1.0', - description = 'Python SSL with session cache support.', - ext_modules = [ssl], - py_modules = ['forge.ssl']) |