/* Socket module header file.
 * This is provided for other applications that need binary access to the PySSLObject, e.g.
 * IO code that needs the ssl as set up by Python
 */

#ifndef _SSL_H
#define _SSL_H

#include "Python.h"
#include "openssl/ssl.h"

#ifdef __cplusplus
extern "C" {
#endif

#define PySSL_MODULE_NAME    "_ssl"
#define PySSL_CAPI_NAME      "CAPI"
#define PySSL_CAPSULE_NAME  (PySSL_MODULE_NAME "." PySSL_CAPI_NAME)

#define CCP 1


/* SSL socket object */

#define X509_NAME_MAXLEN 256

typedef struct {
    PyObject_HEAD
    PySocketSockObject *Socket;         /* Socket on which we're layered */
    SSL_CTX*            ctx;
    SSL*                ssl;
    X509*               peer_cert;
    char                server[X509_NAME_MAXLEN];
    char                issuer[X509_NAME_MAXLEN];
    int                 shutdown_seen_zero;
#if CCP
    BIO                 *external_bio;      /* the "other" end of a bio pair */
    PyObject            *PyBio;             /* a python bio object */
    PyObject            *read_buffer;       /* reveived data, not yet delivered to bio */
    size_t              read_buffer_offset; /* index into the read_buffer string */
    PyObject            *write_buffer;      /* used to store failed writes */
#endif

} PySSLObject;

/* --- C API ----------------------------------------------------*/

/* For an explanation of the API mechanism, see socketmodule.h
 * which implements a similar scheme.
 */

/* C API for usage by other Python modules */
typedef struct {
    PyTypeObject *SSL_Type;
    PyObject *error;
} PySSLModule_APIObject;

#ifndef PySSL_BUILDING_SSL

/* --- C API ----------------------------------------------------*/

/* Interfacestructure to C API for other modules.
   Call PySSLModule_ImportModuleAndAPI() to initialize this
   structure. After that usage is simple:

   if (!PyArg_ParseTuple(args, "O!",
                         &PySSLModule.SSL_Type, (PySSLObject*)&SSLObject))
                         
       return NULL;
   ...
*/

static
PySSLModule_APIObject PySSLModule;

/* You *must* call this before using any of the functions in
   PySSLModule and check its outcome; otherwise all accesses will
   result in a segfault. Returns 0 on success. */

static
int PySSLModule_ImportModuleAndAPI(void)
{
    void *api;

    api = PyCapsule_Import(PySSL_CAPSULE_NAME, 1);
    if (api == NULL)
        return -1;
    memcpy(&PySSLModule, api, sizeof(PySSLModule));
    return 0;
}

#endif /* !PySSL_BUILDING_SSL */

#ifdef __cplusplus
}
#endif
#endif /* _SSL_H */