diff options
author | Mariusz Mazur | 2004-12-04 11:21:22 (GMT) |
---|---|---|
committer | Mariusz Mazur | 2004-12-04 11:21:22 (GMT) |
commit | 80d5d00142f6b25bf4c87a404100f6caa867716f (patch) | |
tree | a03936963ab614e94c35b030d9bd0a21754a0e3a /ucred | |
parent | 0c5bac077f75038d740f3b5f311aab95eb006592 (diff) | |
download | pld-ftp-admin-80d5d00142f6b25bf4c87a404100f6caa867716f.zip pld-ftp-admin-80d5d00142f6b25bf4c87a404100f6caa867716f.tar.gz |
- python module to send credentials through a unix socket; needs work
Changed files:
ucred/setup.py -> 1.1
ucred/ucred.c -> 1.1
Diffstat (limited to 'ucred')
-rw-r--r-- | ucred/setup.py | 4 | ||||
-rw-r--r-- | ucred/ucred.c | 253 |
2 files changed, 257 insertions, 0 deletions
diff --git a/ucred/setup.py b/ucred/setup.py new file mode 100644 index 0000000..1730c01 --- /dev/null +++ b/ucred/setup.py @@ -0,0 +1,4 @@ +from distutils.core import setup, Extension +setup(name="ucred",#version="1.0", + ext_modules=[Extension("ucred", ["ucred.c"])]) + diff --git a/ucred/ucred.c b/ucred/ucred.c new file mode 100644 index 0000000..1a2d816 --- /dev/null +++ b/ucred/ucred.c @@ -0,0 +1,253 @@ +#include <Python.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <signal.h> + +PyObject *g_socketerror; // socket.error + +static PyObject *usockmsgs_sendmsg(PyObject *self, PyObject *args, PyObject *keywds); +static PyObject *usockmsgs_recvmsg(PyObject *self, PyObject *args, PyObject *keywds); + +static PyMethodDef usockmsgsMethods[] = { + {"sendmsg", usockmsgs_sendmsg, METH_VARARGS|METH_KEYWORDS, NULL}, + {"recvmsg", usockmsgs_recvmsg, METH_VARARGS|METH_KEYWORDS, NULL}, + {NULL, NULL, 0, NULL} +}; + +void initusockmsgs(void) { + PyObject *module; + module = Py_InitModule("usockmsgs", usockmsgsMethods); +// if(-1 == PyModule_AddIntConstant(module, "SCM_RIGHTS", SCM_RIGHTS)) { +// return; +// } + if(-1 == PyModule_AddIntConstant(module, "SCM_CREDENTIALS", SCM_CREDENTIALS)) { + return; + } + + + module = PyImport_ImportModule("socket"); + if(!module) { + return; + } + g_socketerror = PyObject_GetAttrString(module, "error"); + if(!g_socketerror) { + return; + } +} + +static PyObject *usockmsgs_sendmsg(PyObject *self, PyObject *args, PyObject *keywds) { + int fd; + int flags=0; + int ret; + char *cmsg_buf = NULL; + struct msghdr msg; + struct iovec iov[1]; + PyObject *ancillary = NULL; +// char *host; +// int port; + + static char *kwlist[] = {"fd", + "data", +// "host", "port", + "flags", + "ancillary", + NULL}; + +// kill(0, SIGTRAP); + if (!PyArg_ParseTupleAndKeywords(args, keywds, "it#|iO", kwlist, + &fd, + &iov[0].iov_base, + &iov[0].iov_len, +// &host, +// &port, + &flags, + &ancillary)) { + return NULL; + } +// kill(0, SIGTRAP); + + msg.msg_name = NULL; + msg.msg_namelen = 0; + + msg.msg_iov = iov; + msg.msg_iovlen = 1; + + msg.msg_control = NULL; + msg.msg_controllen = 0; + + msg.msg_flags = 0; + + if(ancillary) { + struct cmsghdr *cur; + char *data, *cmsg_data; + int data_len, type, level; + + if(!PyArg_ParseTuple(ancillary, "iit#", + &level, + &type, + &data, + &data_len)) { + return NULL; + } + cmsg_buf = malloc(CMSG_SPACE(data_len)); + if (!cmsg_buf) { + PyErr_NoMemory(); + return NULL; + } + msg.msg_control = cmsg_buf; + msg.msg_controllen = CMSG_SPACE(data_len); + + cur = CMSG_FIRSTHDR(&msg); + cur->cmsg_level = level; + cur->cmsg_type = type; + cur->cmsg_len = CMSG_LEN(data_len); + cmsg_data = CMSG_DATA(cur); + memcpy(cmsg_data, data, data_len); + msg.msg_controllen = cur->cmsg_len; // ugh weird C API. CMSG_SPACE includes alignment, unline CMSG_LEN + } + + ret = sendmsg(fd, &msg, flags); + free(cmsg_buf); // this is initialized to NULL and then, optionally, to return value of malloc + if(ret < 0) { + PyErr_SetFromErrno(g_socketerror); + return NULL; + } + + return Py_BuildValue("i", ret); +} + +#define CMSG_BUFSIZE (4*1024) // har har arbitrary and hopefully unused +static PyObject *usockmsgs_recvmsg(PyObject *self, PyObject *args, PyObject *keywds) { + int fd; + int flags=0; + size_t maxsize=8192; + size_t cmsg_size=4*1024; // enough to store all file descriptors + int ret; + struct msghdr msg; + struct iovec iov[1]; +// char cmsgbuf[CMSG_SPACE(CMSG_BUFSIZE)]; + char *cmsgbuf; + PyObject *ancillary; + + static char *kwlist[] = {"fd", "flags", "maxsize", "cmsg_size", NULL}; + + if (!PyArg_ParseTupleAndKeywords(args, keywds, "i|iii", kwlist, + &fd, &flags, &maxsize, &cmsg_size)) { + return NULL; + } + cmsg_size = CMSG_SPACE(cmsg_size); + + msg.msg_name = NULL; + msg.msg_namelen = 0; + + iov[0].iov_len = maxsize; + iov[0].iov_base = malloc(maxsize); + if (!iov[0].iov_base) { + PyErr_NoMemory(); + return NULL; + } + msg.msg_iov = iov; + msg.msg_iovlen = 1; + + cmsgbuf = malloc(cmsg_size); + if (!cmsgbuf) { + PyErr_NoMemory(); + return NULL; + } + memset(cmsgbuf, 0, cmsg_size); + msg.msg_control = cmsgbuf; + msg.msg_controllen = cmsg_size; + + ret = recvmsg(fd, &msg, flags); + if (ret < 0) { + PyErr_SetFromErrno(g_socketerror); + free(iov[0].iov_base); + free(cmsgbuf); + return NULL; + } + + ancillary = PyList_New(0); + if (!ancillary) { + free(iov[0].iov_base); + free(cmsgbuf); + return NULL; + } + + { + struct cmsghdr *cur; + + for (cur=CMSG_FIRSTHDR(&msg); cur; cur=CMSG_NXTHDR(&msg, cur)) { + PyObject *entry; + + assert(cur->cmsg_len >= sizeof(struct cmsghdr)); // no null ancillary data messages? + + entry = Py_BuildValue("(iis#)", + cur->cmsg_level, + cur->cmsg_type, + CMSG_DATA(cur), + cur->cmsg_len - sizeof(struct cmsghdr)); + if (PyList_Append(ancillary, entry) < 0) { + Py_DECREF(ancillary); + Py_DECREF(entry); + free(iov[0].iov_base); + free(cmsgbuf); + return NULL; + } + } + } + + { + PyObject *r; + r = Py_BuildValue("s#iO", + iov[0].iov_base, ret, + msg.msg_flags, + ancillary); + free(iov[0].iov_base); + free(cmsgbuf); + return r; + } +} + +// Useful code for sendmsg, multiple ancillary data case +/* + iterator = PyObject_GetIter(ancillary); // TODO: Py_DECREF me everywhere! + if (!iterator) { + return NULL; + } + while ((item = PyIter_Next(iterator))) { + PyObject *rest; + + if (!cur) { + Py_DECREF(iterator); + return NULL; + } + + if (!PyArg_ParseTuple(item, "iiO", + &cur->cmsg_level, + &cur->cmsg_type, + &rest)) { + return NULL; + } + char *data; + int len; + + if (PyString_AsStringAndSize(rest, &data, &len)) { + return NULL; + } + + memcpy(CMSG_DATA(cur), data, len); + cur->cmsg_len = CMSG_LEN(len); + real_controllen += CMSG_SPACE(len); + } + + cur = CMSG_NXTHDR(&msg, cur); + Py_DECREF(item); + } + Py_DECREF(iterator); + + if (PyErr_Occurred()) + return NULL; + + msg.msg_controllen = real_controllen; +*/ + |