/* Copyright 2002-2004 Nick Mathewson. See LICENSE for licensing information*/
/* $Id: main.c,v 1.25 2004/03/06 00:04:38 nickm Exp $ */
/*
If you're not familiar with writing Python extensions, you should
read "Extending and Embedding the Python Interpreter" at
"http://www.python.org/doc/current/ext/ext.html".
*/
#include "_minionlib.h"
#ifndef TRUNCATED_OPENSSL_INCLUDES
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/rsa.h>
#else
#include <ssl.h>
#include <err.h>
#include <rsa.h>
#endif
#ifdef MS_WINDOWS
#if _MSC_VER >= 1300
#include <winsock2.h>
#else
#include <winsock.h>
#endif
#else /* not windows */
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#endif
#if defined(HAVE_POLL_H)
#include <poll.h>
#elif defined(HAVE_SYS_POLL_H)
#include <sys/poll.h>
#endif
#ifdef _POLL_EMUL_H_
#define POLL_IS_EMULATED 1
#else
#define POLL_IS_EMULATED 0
#endif
/* Macros to declare function tables for Python. */
#define ENTRY_ND(fn) { #fn, (PyCFunction)mm_##fn, METH_VARARGS|METH_KEYWORDS,\
0}
#define ENTRY(fn) { #fn, (PyCFunction)mm_##fn, METH_VARARGS|METH_KEYWORDS, \
(char*)mm_##fn##__doc__}
static struct PyMethodDef _mixcryptlib_functions[] = {
ENTRY(sha1),
ENTRY(aes_key),
ENTRY(aes_ctr128_crypt),
ENTRY(aes128_block_crypt),
ENTRY(strxor),
ENTRY(openssl_seed),
ENTRY(openssl_rand),
#ifdef MS_WINDOWS
ENTRY(win32_openssl_seed),
ENTRY(win32_get_random_bytes),
#endif
ENTRY(add_oaep_padding),
ENTRY(check_oaep_padding),
ENTRY(rsa_generate),
ENTRY(rsa_decode_key),
ENTRY(rsa_PEM_read_key),
ENTRY(rsa_make_public_key),
ENTRY(generate_dh_parameters),
ENTRY(generate_cert),
ENTRY(TLSContext_new),
ENTRY(FEC_generate),
{ NULL, NULL }
};
/* Helper method to create an exception object and register it in a
module's dictionary.
module_dict: A PyDictObject* for the module's namespace.
exception: Set to point to a pointer to the newly allocated exception.
longName: The fully qualified name of this exception.
itemString: The name of this exception within the module.
doc: The docstring for this exception.
returns 1 on failure; 0 on success */
static int
exc(PyObject *module_dict, PyObject **exception, char *longName,
char *itemString, char *doc)
{
PyObject *s, *exc_d;
if (!(s = PyString_FromString(doc)))
return 1;
if (!(exc_d = PyDict_New())) {
Py_DECREF(s);
return 1;
}
if (PyDict_SetItemString(exc_d, "__doc__", s)<0) {
Py_DECREF(s); Py_DECREF(exc_d);
return 1;
}
*exception = PyErr_NewException(longName, PyExc_Exception, exc_d);
if (! *exception) {
Py_DECREF(s); Py_DECREF(exc_d);
return 1;
}
if (PyDict_SetItemString(module_dict,itemString,*exception) < 0) {
Py_DECREF(s); Py_DECREF(exc_d); Py_DECREF(*exception);
return 1;
}
return 0;
}
/* Required by Python: magic method to tell the Python runtime about our
* new module and its contents. Also initializes OpenSSL as needed.
*/
DL_EXPORT(void)
init_minionlib(void)
{
PyObject *m, *d;
m = Py_InitModule("_minionlib", _mixcryptlib_functions);
d = PyModule_GetDict(m);
SSL_library_init();
SSL_load_error_strings();
/* crypt */
ERR_load_ERR_strings();
ERR_load_RSA_strings();
OpenSSL_add_all_algorithms();
if (exc(d, &mm_CryptoError, "mixminion._minionlib.CryptoError",
"CryptoError", mm_CryptoError__doc__))
return;
if (exc(d, &mm_TLSError, "mixminion._minionlib.TLSError",
"TLSError", mm_TLSError__doc__))
return;
if (exc(d, &mm_TLSWantRead, "mixminion._minionlib.TLSWantRead",
"TLSWantRead", mm_TLSWantRead__doc__))
return;
if (exc(d, &mm_TLSWantWrite, "mixminion._minionlib.TLSWantWrite",
"TLSWantWrite", mm_TLSWantWrite__doc__))
return;
if (exc(d, &mm_TLSClosed, "mixminion._minionlib.TLSClosed",
"TLSClosed", mm_TLSClosed__doc__))
return;
if (exc(d, &mm_FECError, "mixminion._minionlib.FECError",
"FECError", mm_FECError__doc__))
return;
/* We set ob_type here so that Cygwin and Win32 are happy. */
mm_RSA_Type.ob_type = mm_TLSContext_Type.ob_type =
mm_TLSSock_Type.ob_type = mm_FEC_Type.ob_type = &PyType_Type;
Py_INCREF(&mm_RSA_Type);
if (PyDict_SetItemString(d, "RSA", (PyObject*)&mm_RSA_Type) < 0)
return;
Py_INCREF(&mm_TLSContext_Type);
if (PyDict_SetItemString(d, "TLSContext",
(PyObject*)&mm_TLSContext_Type) < 0)
return;
Py_INCREF(&mm_TLSSock_Type);
if (PyDict_SetItemString(d, "TLSSock",
(PyObject*)&mm_TLSSock_Type) < 0)
return;
Py_INCREF(&mm_FEC_Type);
if (PyDict_SetItemString(d, "FEC",
(PyObject*)&mm_FEC_Type) < 0)
return;
/* For some reason, Python's socket module doesn't export
* IPTOS_*. IPTOS_THROUGHPUT should always be "0x08" on any
* sane sockets implementation, but life is always more complicated
* than that.
*/
#ifdef IPTOS_THROUGHPUT
if (PyDict_SetItemString(d, "IPTOS_THROUGHPUT",
PyInt_FromLong(IPTOS_THROUGHPUT)))
return;
#endif
if (PyDict_SetItemString(d, "POLL_IS_EMULATED",
PyInt_FromLong(POLL_IS_EMULATED)))
return;
}
/*
Local Variables:
mode:c
indent-tabs-mode:nil
c-basic-offset:8
End:
*/
syntax highlighted by Code2HTML, v. 0.9.1