X-Git-Url: https://git.distorted.org.uk/~mdw/pyke/blobdiff_plain/73a712fa61e9b04ea6c1cbfc86e05cd4db1008b4..598327e56b4c57b391881c30f52f068e611552ba:/catacomb.c diff --git a/catacomb.c b/catacomb.c index 47a94dd..b54227f 100644 --- a/catacomb.c +++ b/catacomb.c @@ -1,13 +1,11 @@ /* -*-c-*- * - * $Id$ - * * Where the fun begins * * (c) 2004 Straylight/Edgeware */ -/*----- Licensing notice --------------------------------------------------* +/*----- Licensing notice --------------------------------------------------* * * This file is part of the Python interface to Catacomb. * @@ -15,12 +13,12 @@ * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * Catacomb/Python is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with Catacomb/Python; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. @@ -32,142 +30,37 @@ /*----- Main code ---------------------------------------------------------*/ -static void setconstants(PyObject *mod) -{ - static const struct { const char *name; unsigned long value; } consts[] = { -#define C(x) { #x, x } - C(FTY_PRIME), C(FTY_BINARY), - C(PGEN_PASS), C(PGEN_FAIL), C(PGEN_BEGIN), C(PGEN_TRY), C(PGEN_DONE), - C(PGEN_ABORT), - C(MPW_MAX), - C(PMODE_READ), C(PMODE_VERIFY), - C(KOPEN_READ), C(KOPEN_WRITE), C(KOPEN_NOFILE), - C(KEXP_FOREVER), C(KEXP_EXPIRE), - C(KF_ENCMASK), C(KENC_BINARY), C(KENC_MP), C(KENC_STRUCT), - C(KENC_ENCRYPT), C(KENC_STRING), C(KENC_EC), - C(KF_CATMASK), C(KCAT_SYMM), C(KCAT_PRIV), C(KCAT_PUB), C(KCAT_SHARE), - C(KF_NONSECRET), - C(KF_BURN), C(KF_OPT), +static const struct nameval consts[] = { +#define CF(f, x) { #x, f, x } +#define C(x) { #x, (x) >= 0 ? 0 : CF_SIGNED, x } + C(FTY_PRIME), C(FTY_BINARY), + C(PGEN_PASS), C(PGEN_FAIL), C(PGEN_BEGIN), C(PGEN_TRY), C(PGEN_DONE), + C(PGEN_ABORT), + C(MPW_MAX), + C(RAND_IBITS), + C(PMODE_READ), C(PMODE_VERIFY), + C(KOPEN_READ), C(KOPEN_WRITE), C(KOPEN_NOFILE), + CF(0, KEXP_FOREVER), CF(0, KEXP_EXPIRE), + C(KF_ENCMASK), C(KENC_BINARY), C(KENC_MP), C(KENC_STRUCT), + C(KENC_ENCRYPT), C(KENC_STRING), C(KENC_EC), + C(KF_CATMASK), C(KCAT_SYMM), C(KCAT_PRIV), C(KCAT_PUB), C(KCAT_SHARE), + C(KF_NONSECRET), + C(KF_BURN), C(KF_OPT), + C(EC_XONLY), C(EC_YBIT), C(EC_LSB), C(EC_CMPR), C(EC_EXPLY), C(EC_SORT), + C(X25519_KEYSZ), C(X25519_PUBSZ), C(X25519_OUTSZ), + C(X448_KEYSZ), C(X448_PUBSZ), C(X448_OUTSZ), + C(ED25519_KEYSZ), C(ED25519_PUBSZ), C(ED25519_SIGSZ), + C(ED25519_MAXPERSOSZ), + C(ED448_KEYSZ), C(ED448_PUBSZ), C(ED448_SIGSZ), C(ED448_MAXPERSOSZ), + C(AEADF_PCHSZ), C(AEADF_PCMSZ), C(AEADF_PCTSZ), + C(AEADF_AADNDEP), C(AEADF_AADFIRST), C(AEADF_NOAAD), #define ENTRY(tag, val, str) C(KERR_##tag), - KEY_ERRORS(ENTRY) + KEY_ERRORS(ENTRY) #undef ENTRY #undef C - { 0 } - }; - int i; - PyObject *x; - - for (i = 0; consts[i].name; i++) { - if (consts[i].value > LONG_MAX) - x = PyLong_FromUnsignedLong(consts[i].value); - else - x = PyInt_FromLong(consts[i].value); - PyModule_AddObject(mod, (/*unconst*/ char *)consts[i].name, x); - } -} - -#define GETU_(n) \ - PyObject *getu##n(uint##n w) \ - { \ - if (w <= MASK##n) \ - return (PyInt_FromLong(w)); \ - else \ - return (PyLong_FromUnsignedLong(w)); \ - } -DOUINTSZ(GETU_) - -PyObject *getbool(int b) -{ - if (b) RETURN_TRUE; - else RETURN_FALSE; -} - -PyObject *abstract_pynew(PyTypeObject *ty, PyObject *arg, PyObject *kw) -{ - PyErr_SetString(PyExc_TypeError, "can't instantiate this class"); - return (0); -} - -int convulong(PyObject *o, void *pp) -{ - long i; - unsigned long *p = pp; - PyObject *t; - - if (PyInt_Check(o)) { - i = PyInt_AS_LONG(o); - if (i < 0) TYERR("must be nonnegative"); - *p = i; - } else { - if ((t = PyNumber_Long(o)) == 0) goto end; - *p = PyLong_AsUnsignedLong(t); - Py_DECREF(t); - if (PyErr_Occurred()) goto end; - } - return (1); -end: - return (0); -} - -#define CONVU_(n) \ - int convu##n(PyObject *o, void *pp) \ - { \ - unsigned long u; \ - uint##n *p = pp; \ - \ - if (!convulong(o, &u)) goto end; \ - if (u > MASK##n) TYERR("out of range"); \ - *p = u; \ - return (1); \ - end: \ - return (0); \ - } -DOUINTSZ(CONVU_) - -int convuint(PyObject *o, void *pp) -{ - unsigned long u; - unsigned *p = pp; - - if (!convulong(o, &u)) goto end; - if (u > UINT_MAX) TYERR("out of range"); - *p = u; - return (1); -end: - return (0); -} - -int convmpw(PyObject *o, void *pp) -{ - unsigned long u; - unsigned *p = pp; - - if (!convulong(o, &u)) goto end; - if (u > MPW_MAX) TYERR("out of range"); - *p = u; - return (1); -end: - return (0); -} - -int convszt(PyObject *o, void *pp) -{ - unsigned long u; - size_t *p = pp; - - if (!convulong(o, &u)) goto end; - if (u > ~(size_t)0) TYERR("out of range"); - *p = u; - return (1); -end: - return (0); -} - -int convbool(PyObject *o, void *pp) -{ - *(int *)pp = PyObject_IsTrue(o); - return (1); -} +#undef CF + { 0 } +}; PyObject *mexp_common(PyObject *me, PyObject *arg, size_t efsz, @@ -181,11 +74,12 @@ PyObject *mexp_common(PyObject *me, PyObject *arg, PyObject *qq, *x, *y, *z = 0; char *v = 0, *vv; - if (PyTuple_Size(arg) == 1) - arg = PyTuple_GetItem(arg, 0); + if (PyTuple_GET_SIZE(arg) == 1) + arg = PyTuple_GET_ITEM(arg, 0); Py_INCREF(arg); if (!PySequence_Check(arg)) TYERR("not a sequence"); - n = PySequence_Size(arg); if (!n) { z = id(me); goto end; } + n = PySequence_Size(arg); if (n < 0) goto end; + if (!n) { z = id(me); goto end; } x = PySequence_GetItem(arg, 0); if (PySequence_Check(x)) flat = 0; @@ -235,141 +129,60 @@ end: return (z); } -PyObject * mkexc(PyObject *mod, PyObject *base, - const char *name, PyMethodDef *mm) -{ - PyObject *nameobj = 0; - PyObject *dict = 0; - PyObject *exc = 0; - PyObject *func = 0; - PyObject *meth = 0; - - if ((nameobj = PyString_FromFormat("%s.%s", - PyModule_GetName(mod), - name)) == 0 || - (dict = PyDict_New()) == 0 || - (exc = PyErr_NewException(PyString_AS_STRING(nameobj), - base, dict)) == 0) - goto fail; - - if (mm) { - while (mm->ml_name) { - if ((func = PyCFunction_NewEx(mm, 0, mod)) == 0 || - (meth = PyMethod_New(func, 0, exc)) == 0 || - PyDict_SetItemString(dict, mm->ml_name, meth)) - goto fail; - Py_DECREF(func); func = 0; - Py_DECREF(meth); meth = 0; - mm++; - } - } - -done: - Py_XDECREF(nameobj); - Py_XDECREF(dict); - return (exc); - -fail: - Py_XDECREF(exc); - Py_XDECREF(func); - Py_XDECREF(meth); - exc = 0; - goto done; -} - -DA_DECL(method_v, PyMethodDef); -static method_v global_pymethods = DA_INIT; -void addmethods(const PyMethodDef *m) -{ - size_t n; - - for (n = 0; m[n].ml_name; n++); - DA_ENSURE(&global_pymethods, n); - memcpy(DA(&global_pymethods) + DA_LEN(&global_pymethods), - m, n * sizeof(*m)); - DA_EXTEND(&global_pymethods, n); -} - -static const PyTypeObject emptytype = { 0 }; - -void *newtype(PyTypeObject *metaty, - const PyTypeObject *skel, - const char *name) -{ - PyHeapTypeObject *ty = - (PyHeapTypeObject *)_PyObject_GC_Malloc(_PyObject_VAR_SIZE(metaty, 0)); - if (!skel) skel = &emptytype; - memcpy(ty, skel, sizeof(*skel)); - if (ty->type.tp_base) Py_INCREF(ty->type.tp_base); -#define COPY(blah) do { \ - if (ty->type.tp_as_##blah) { \ - memcpy(&ty->as_##blah, \ - ty->type.tp_as_##blah, \ - sizeof(ty->as_##blah)); \ - ty->type.tp_as_##blah = &ty->as_##blah; \ - } \ - } while (0) - COPY(number); - COPY(sequence); - COPY(mapping); - COPY(buffer); -#undef COPY - if (name) - ty->name = PyString_FromString(name); - else if (ty->type.tp_name) - ty->name = PyString_FromString(ty->type.tp_name); - if (ty->name) - ty->type.tp_name = PyString_AS_STRING(ty->name); - PyObject_INIT(&ty->type, metaty); - Py_INCREF(metaty); - return (ty); -} - static PyObject *smallprimes(void) { PyObject *v = PyList_New(NPRIME); int i; for (i = 0; i < NPRIME; i++) - PyList_SetItem(v, i, PyInt_FromLong(primetab[i])); + PyList_SET_ITEM(v, i, PyInt_FromLong(primetab[i])); return (v); } -PyTypeObject *inittype(PyTypeObject *tyskel) -{ - PyTypeObject *ty = newtype(&PyType_Type, tyskel, 0); - ty->tp_flags |= Py_TPFLAGS_HEAPTYPE; - PyType_Ready(ty); - return (ty); -} - static PyObject *meth__ego(PyObject *me, PyObject *arg) { char *argv0; if (!PyArg_ParseTuple(arg, "s:_ego", &argv0)) return (0); - if (strcmp(QUIS, "") == 0) + if (STRCMP(QUIS, ==, "")) ego(argv0); RETURN_NONE; } static PyMethodDef methods[] = { #define METHNAME(func) meth_##func - METH (_ego, "_ego(ARGV0)") + METH (_ego, "_ego(ARGV0)") #undef METHNAME { 0 } }; -void init_base(void) { - static const PyMethodDef mzero = { 0 }; +static void init_random(void) +{ +#if PY_VERSION_HEX >= 0x02060000 + char *seed; + uint32 r; + + if (!Py_HashRandomizationFlag) return; + seed = getenv("PYTHONHASHSEED"); + if (!seed || STRCMP(seed, ==, "random")) r = GR_WORD(&rand_global); + else r = strtoul(seed, 0, 0); + if (!r) r = 0xe011f220; /* zero doesn't work well */ + unihash_setkey(&unihash_global, r); +#endif +} + +EXPORT void init_base(void) +{ PyObject *mod; + + modname = PyString_FromString("catacomb"); addmethods(methods); INIT_MODULES; - DA_PUSH(&global_pymethods, mzero); - mod = Py_InitModule("catacomb._base", DA(&global_pymethods)); + init_random(); + mod = Py_InitModule("catacomb._base", donemethods()); INSERT_MODULES; INSERT("smallprimes", smallprimes()); - setconstants(mod); + setconstants(mod, consts); } /*----- That's all, folks -------------------------------------------------*/