From 251c7f434f3024a7229400ed549880746e6871c7 Mon Sep 17 00:00:00 2001 From: Milan Broz Date: Fri, 4 Nov 2011 23:38:47 +0000 Subject: [PATCH] Merge pycryptsetup (Python libcryptsetup bindings). git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@672 36d66b0a-2a48-0410-832c-cd162a569da5 --- ChangeLog | 3 + Makefile.am | 1 + configure.in | 22 +- python/Makefile.am | 16 + python/pycryptsetup-test.py | 50 +++ python/pycryptsetup.c | 651 ++++++++++++++++++++++++++++++++++++ 6 files changed, 742 insertions(+), 1 deletion(-) create mode 100644 python/Makefile.am create mode 100755 python/pycryptsetup-test.py create mode 100644 python/pycryptsetup.c diff --git a/ChangeLog b/ChangeLog index 6ce65e1..ac74b8c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,6 @@ +2011-11-05 Milan Broz + * Merge pycryptsetup (Python libcryptsetup bindings). + 2011-10-27 Milan Broz * Fix crypt_get_volume_key_size() for plain device. * Fix FSF address in license text. diff --git a/Makefile.am b/Makefile.am index 58dcc9c..3f59b58 100644 --- a/Makefile.am +++ b/Makefile.am @@ -3,6 +3,7 @@ SUBDIRS = \ lib \ src \ man \ + python \ tests \ po diff --git a/configure.in b/configure.in index baa75b8..e090d51 100644 --- a/configure.in +++ b/configure.in @@ -1,5 +1,5 @@ AC_PREREQ([2.67]) -AC_INIT([cryptsetup],[1.4.0]) +AC_INIT([cryptsetup],[1.4.1-cvs]) dnl library version from ..[-] LIBCRYPTSETUP_VERSION=$(echo $PACKAGE_VERSION | cut -f1 -d-) @@ -260,6 +260,25 @@ AC_DEFUN([CS_NUM_WITH], [AC_ARG_WITH([$1], [CS_DEFINE([$1], [$3], [$2])] )]) +dnl ========================================================================== +dnl Python bindings +AC_ARG_ENABLE([python], AS_HELP_STRING([--enable-python],[enable Python bindings]), +[with_python=$enableval], +[with_python=no]) + +if test "x$with_python" = "xyes"; then + AM_PATH_PYTHON([2.4]) + + if ! test -x "$PYTHON-config" ; then + AC_MSG_ERROR([Cannot find python development packages to build bindings]) + fi + + PYTHON_INCLUDES=$($PYTHON-config --includes) + AC_SUBST(PYTHON_INCLUDES) +fi +AM_CONDITIONAL([PYTHON_CRYPTSETUP], [test "x$with_python" = "xyes"]) + +dnl ========================================================================== CS_STR_WITH([plain-hash], [password hashing function for plain mode], [ripemd160]) CS_STR_WITH([plain-cipher], [cipher for plain mode], [aes]) CS_STR_WITH([plain-mode], [cipher mode for plain mode], [cbc-essiv:sha256]) @@ -288,5 +307,6 @@ src/Makefile po/Makefile.in man/Makefile tests/Makefile +python/Makefile ]) AC_OUTPUT diff --git a/python/Makefile.am b/python/Makefile.am new file mode 100644 index 0000000..680a499 --- /dev/null +++ b/python/Makefile.am @@ -0,0 +1,16 @@ +INCLUDES = -I$(top_srcdir)/lib $(PYTHON_INCLUDES) +EXTRA_DIST = pycryptsetup-test.py +CLEANFILES = *.img + +if PYTHON_CRYPTSETUP +TESTS = pycryptsetup-test.py + +pyexec_LTLIBRARIES = pycryptsetup.la + +pycryptsetup_la_SOURCES = pycryptsetup.c +pycryptsetup_la_CPPFLAGS = $(AM_CPPFLAGS) $(PYTHON_CPPFLAGS) +pycryptsetup_la_LDFLAGS = -avoid-version -module +pycryptsetup_la_LIBADD = $(top_srcdir)/lib/libcryptsetup.la -lpython$(PYTHON_VERSION) +else +all: +endif diff --git a/python/pycryptsetup-test.py b/python/pycryptsetup-test.py new file mode 100755 index 0000000..b86e677 --- /dev/null +++ b/python/pycryptsetup-test.py @@ -0,0 +1,50 @@ +#!/usr/bin/python + +import sys +import os + +sys.path.insert(0, ".libs") +import pycryptsetup + +IMG = "test.img" +PASSWORD = "password" +DEVICE = "pycryptsetup_test_dev" + +def log(pri, txt): + if pri > 1: + return + print txt, + return + +def askyes(txt): + print "Asking about:", txt, "\n" + return 1 + +def askpassword(txt): + return PASSWORD + +os.system("dd if=/dev/zero of=" + IMG + " bs=1M count=32 >/dev/null 2>&1") + +c = pycryptsetup.CryptSetup( + device = IMG, + name = DEVICE, + yesDialog = askyes, + logFunc = log, + passwordDialog = askpassword) + +r = c.isLuks() +print "isLuks :", r +c.luksFormat() +print "isLuks :", c.isLuks() +print "luksUUID:", c.luksUUID() +print "addKey :", c.addKeyByVolumeKey(PASSWORD) +print "activate:", c.activate(name = DEVICE, passphrase = PASSWORD) +print "status :", c.status() +info = c.info() +print "cipher :", info["cipher"] +print "cmode :", info["cipher_mode"] +print "deact. :", c.deactivate() + +del c + +os.remove(IMG) diff --git a/python/pycryptsetup.c b/python/pycryptsetup.c new file mode 100644 index 0000000..419454b --- /dev/null +++ b/python/pycryptsetup.c @@ -0,0 +1,651 @@ +/* + * Python bindings to libcryptsetup + * + * Copyright (C) 2009-2011, Red Hat, Inc. All rights reserved. + * Written by Martin Sivak + * + * This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This file 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#include +#include + +#include "libcryptsetup.h" + +typedef struct { + PyObject_HEAD + + /* Type-specific fields go here. */ + struct crypt_device *device; + char *activated_as; + + /* Callbacks */ + PyObject *yesDialogCB; + PyObject *cmdLineLogCB; + PyObject *passwordDialogCB; +} CryptSetupObject; + +static int yesDialog(const char *msg, void *this) +{ + CryptSetupObject *self = this; + PyObject *result, *arglist; + int r; + + if (self->yesDialogCB){ + arglist = Py_BuildValue("(s)", msg); + if (!arglist) + return -ENOMEM; + + result = PyEval_CallObject(self->yesDialogCB, arglist); + Py_DECREF(arglist); + + if (!result) + return -EINVAL; + + if (!PyArg_Parse(result, "i", &r)) + r = -EINVAL; + + Py_DECREF(result); + return r; + } + + return 1; +} + +static int passwordDialog(const char *msg, char *buf, size_t length, void *this) +{ + CryptSetupObject *self = this; + PyObject *result, *arglist; + char *res = NULL; + + if(self->passwordDialogCB){ + arglist = Py_BuildValue("(s)", msg); + if (!arglist) + return -ENOMEM; + + result = PyEval_CallObject(self->passwordDialogCB, arglist); + Py_DECREF(arglist); + + if (!result) + return -EINVAL; + + if (!PyArg_Parse(result, "z", &res)) { + Py_DECREF(result); + return -EINVAL; + } + + strncpy(buf, res, length - 1); + + // FIXME: wipe res + Py_DECREF(result); + return strlen(buf); + } + + return -EINVAL; +} + +static void cmdLineLog(int cls, const char *msg, void *this) +{ + CryptSetupObject *self = this; + PyObject *result, *arglist; + + if(self->cmdLineLogCB) { + arglist = Py_BuildValue("(is)", cls, msg); + if(!arglist) + return; + + result = PyEval_CallObject(self->cmdLineLogCB, arglist); + Py_DECREF(arglist); + Py_XDECREF(result); + } +} + +static void CryptSetup_dealloc(CryptSetupObject* self) +{ + /* free the callbacks */ + Py_XDECREF(self->yesDialogCB); + Py_XDECREF(self->cmdLineLogCB); + Py_XDECREF(self->passwordDialogCB); + + free(self->activated_as); + + crypt_free(self->device); + + /* free self */ + self->ob_type->tp_free((PyObject*)self); +} + +static PyObject *CryptSetup_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + CryptSetupObject *self = (CryptSetupObject *)type->tp_alloc(type, 0); + + if (self) { + self->yesDialogCB = NULL; + self->passwordDialogCB = NULL; + self->cmdLineLogCB = NULL; + self->activated_as = NULL; + } + + return (PyObject *)self; +} + +static PyObject *PyObjectResult(int is) +{ + PyObject *result = Py_BuildValue("i", is); + + if (!result) + PyErr_SetString(PyExc_RuntimeError, "Error during constructing values for return value"); + + return result; +} + +#define CryptSetup_HELP "CryptSetup object\n\n\ +constructor takes one to five arguments:\n\ + __init__(device, name, yesDialog, passwordDialog, logFunc)\n\n\ + yesDialog - python function with func(text) signature, \n\ + which asks the user question text and returns 1\n\ + of the answer was positive or 0 if not\n\ + logFunc - python function with func(level, text) signature to log stuff somewhere" + +static int CryptSetup_init(CryptSetupObject* self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"device", "name", "yesDialog", "passwordDialog", "logFunc", NULL}; + PyObject *yesDialogCB = NULL, + *passwordDialogCB = NULL, + *cmdLineLogCB = NULL, + *tmp = NULL; + char *device = NULL, *deviceName = NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|zzOOO", kwlist, &device, &deviceName, + &yesDialogCB, &passwordDialogCB, &cmdLineLogCB)) + return -1; + + if (device) { + if (crypt_init(&(self->device), device)) { + PyErr_SetString(PyExc_IOError, "Device cannot be opened"); + return -1; + } + + } else if (deviceName) { + if (crypt_init_by_name(&(self->device), deviceName)) { + PyErr_SetString(PyExc_IOError, "Device cannot be opened"); + return -1; + } + } else { + PyErr_SetString(PyExc_RuntimeError, "Either device file or luks name has to be specified"); + return -1; + } + + // FIXME: check return code + crypt_load(self->device, NULL, NULL); + if(deviceName) + self->activated_as = strdup(deviceName); + + if (yesDialogCB) { + tmp = self->yesDialogCB; + Py_INCREF(yesDialogCB); + self->yesDialogCB = yesDialogCB; + Py_XDECREF(tmp); + crypt_set_confirm_callback(self->device, yesDialog, self); + } + + if (passwordDialogCB) { + tmp = self->passwordDialogCB; + Py_INCREF(passwordDialogCB); + self->passwordDialogCB = passwordDialogCB; + Py_XDECREF(tmp); + crypt_set_password_callback(self->device, passwordDialog, self); + } + + if (cmdLineLogCB) { + tmp = self->cmdLineLogCB; + Py_INCREF(cmdLineLogCB); + self->cmdLineLogCB = cmdLineLogCB; + Py_XDECREF(tmp); + crypt_set_log_callback(self->device, cmdLineLog, self); + } + + return 0; +} + +#define CryptSetup_activate_HELP "Activate LUKS device\n\n\ + activate(name)" + +static PyObject *CryptSetup_activate(CryptSetupObject* self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"name", "passphrase", NULL}; + char *name = NULL, *passphrase = NULL; + int is; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|s", kwlist, &name, &passphrase)) + return NULL; + + // FIXME: allow keyfile and \0 in passphrase + is = crypt_activate_by_passphrase(self->device, name, CRYPT_ANY_SLOT, + passphrase, passphrase ? strlen(passphrase) : 0, 0); + + if (is >= 0) { + free(self->activated_as); + self->activated_as = strdup(name); + } + + return PyObjectResult(is); +} + +#define CryptSetup_deactivate_HELP "Dectivate LUKS device\n\n\ + deactivate()" + +static PyObject *CryptSetup_deactivate(CryptSetupObject* self, PyObject *args, PyObject *kwds) +{ + int is = crypt_deactivate(self->device, self->activated_as); + + if (!is) { + free(self->activated_as); + self->activated_as = NULL; + } + + return PyObjectResult(is); +} + +#define CryptSetup_askyes_HELP "Asks a question using the configured dialog CB\n\n\ + int askyes(message)" + +static PyObject *CryptSetup_askyes(CryptSetupObject* self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"message", NULL}; + PyObject *message = NULL, *result, *arglist; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O", kwlist, &message)) + return NULL; + + Py_INCREF(message); + + arglist = Py_BuildValue("(O)", message); + if (!arglist){ + PyErr_SetString(PyExc_RuntimeError, "Error during constructing values for internal call"); + return NULL; + } + + result = PyEval_CallObject(self->yesDialogCB, arglist); + Py_DECREF(arglist); + Py_DECREF(message); + + return result; +} + +#define CryptSetup_log_HELP "Logs a string using the configured log CB\n\n\ + log(int level, message)" + +static PyObject *CryptSetup_log(CryptSetupObject* self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"priority", "message", NULL}; + PyObject *message = NULL, *priority = NULL, *result, *arglist; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO", kwlist, &message, &priority)) + return NULL; + + Py_INCREF(message); + Py_INCREF(priority); + + arglist = Py_BuildValue("(OO)", message, priority); + if (!arglist){ + PyErr_SetString(PyExc_RuntimeError, "Error during constructing values for internal call"); + return NULL; + } + + result = PyEval_CallObject(self->cmdLineLogCB, arglist); + Py_DECREF(arglist); + Py_DECREF(priority); + Py_DECREF(message); + + return result; +} + +#define CryptSetup_luksUUID_HELP "Get UUID of the LUKS device\n\n\ + luksUUID()" + +static PyObject *CryptSetup_luksUUID(CryptSetupObject* self, PyObject *args, PyObject *kwds) +{ + PyObject *result; + + result = Py_BuildValue("s", crypt_get_uuid(self->device)); + if (!result) + PyErr_SetString(PyExc_RuntimeError, "Error during constructing values for return value"); + + return result; +} + +#define CryptSetup_isLuks_HELP "Is the device LUKS?\n\n\ + isLuks()" + +static PyObject *CryptSetup_isLuks(CryptSetupObject* self, PyObject *args, PyObject *kwds) +{ + return PyObjectResult(crypt_load(self->device, CRYPT_LUKS1, NULL)); +} + +#define CryptSetup_Info_HELP "Returns dictionary with info about opened device\nKeys:\n\ + dir\n name\n uuid\n cipher\n cipher_mode\n keysize\n device\n\ + offset\n size\n skip\n mode\n" + +static PyObject *CryptSetup_Info(CryptSetupObject* self, PyObject *args, PyObject *kwds) +{ + PyObject *result; + + result = Py_BuildValue("{s:s,s:s,s:z,s:s,s:s,s:s,s:i,s:K}", + "dir", crypt_get_dir(), + "device", crypt_get_device_name(self->device), + "name", self->activated_as, + "uuid", crypt_get_uuid(self->device), + "cipher", crypt_get_cipher(self->device), + "cipher_mode", crypt_get_cipher_mode(self->device), + "keysize", crypt_get_volume_key_size(self->device) * 8, + //"size", co.size, + //"mode", (co.flags & CRYPT_FLAG_READONLY) ? "readonly" : "read/write", + "offset", crypt_get_data_offset(self->device) + ); + + if (!result) + PyErr_SetString(PyExc_RuntimeError, "Error during constructing values for return value"); + + return result; +} + +#define CryptSetup_luksFormat_HELP "Format device to enable LUKS\n\n\ + luksFormat(cipher = 'aes', cipherMode = 'cbc-essiv:sha256', keysize = 256)\n\n\ + cipher - cipher specification, e.g. aes, serpent\n\ + cipherMode - cipher mode specification, e.g. cbc-essiv:sha256, xts-plain64\n\ + keysize - key size in bits" + +static PyObject *CryptSetup_luksFormat(CryptSetupObject* self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"cipher", "cipherMode", "keysize", NULL}; + char *cipher_mode = NULL, *cipher = NULL; + int keysize = 256; + PyObject *keysize_object = NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|zzO", kwlist, + &cipher, &cipher_mode, &keysize_object)) + return NULL; + + if (!keysize_object || keysize_object == Py_None) { + /* use default value */ + } else if (!PyInt_Check(keysize_object)) { + PyErr_SetString(PyExc_TypeError, "keysize must be an integer"); + return NULL; + } else if (PyInt_AsLong(keysize_object) % 8) { + PyErr_SetString(PyExc_TypeError, "keysize must have integer value dividable by 8"); + return NULL; + } else if (PyInt_AsLong(keysize_object) <= 0) { + PyErr_SetString(PyExc_TypeError, "keysize must be positive number bigger than 0"); + return NULL; + } else + keysize = PyInt_AsLong(keysize_object); + + // FIXME use #defined defaults + return PyObjectResult(crypt_format(self->device, CRYPT_LUKS1, + cipher ?: "aes", cipher_mode ?: "cbc-essiv:sha256", + NULL, NULL, keysize / 8, NULL)); +} + +#define CryptSetup_addKeyByPassphrase_HELP "Initialize keyslot using passphrase\n\n\ + addKeyByPassphrase(passphrase, newPassphrase, slot)\n\n\ + passphrase - string or none to ask the user\n\ + newPassphrase - passphrase to add\n\ + slot - which slot to use (optional)" + +static PyObject *CryptSetup_addKeyByPassphrase(CryptSetupObject* self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"passphrase", "newPassphrase", "slot", NULL}; + char *passphrase = NULL, *newpassphrase = NULL; + size_t passphrase_len = 0, newpassphrase_len = 0; + int slot = CRYPT_ANY_SLOT; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "ss|i", kwlist, &passphrase, &newpassphrase, &slot)) + return NULL; + + if(passphrase) + passphrase_len = strlen(passphrase); + + if(newpassphrase) + newpassphrase_len = strlen(newpassphrase); + + return PyObjectResult(crypt_keyslot_add_by_passphrase(self->device, slot, + passphrase, passphrase_len, + newpassphrase, newpassphrase_len)); +} + +#define CryptSetup_addKeyByVolumeKey_HELP "Initialize keyslot using cached volume key\n\n\ + addKeyByVolumeKey(passphrase, newPassphrase, slot)\n\n\ + newPassphrase - passphrase to add\n\ + slot - which slot to use (optional)" + +static PyObject *CryptSetup_addKeyByVolumeKey(CryptSetupObject* self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"newPassphrase", "slot", NULL}; + char *newpassphrase = NULL; + size_t newpassphrase_len = 0; + int slot = CRYPT_ANY_SLOT; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|i", kwlist, &newpassphrase, &slot)) + return NULL; + + if (newpassphrase) + newpassphrase_len = strlen(newpassphrase); + + return PyObjectResult(crypt_keyslot_add_by_volume_key(self->device, slot, + NULL, 0, newpassphrase, newpassphrase_len)); +} + +#define CryptSetup_removePassphrase_HELP "Destroy keyslot using passphrase\n\n\ + removePassphrase(passphrase)\n\n\ + passphrase - string or none to ask the user" + +static PyObject *CryptSetup_removePassphrase(CryptSetupObject* self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"passphrase", NULL}; + char *passphrase = NULL; + size_t passphrase_len = 0; + int is; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "s", kwlist, &passphrase)) + return NULL; + + if (passphrase) + passphrase_len = strlen(passphrase); + + is = crypt_activate_by_passphrase(self->device, NULL, CRYPT_ANY_SLOT, + passphrase, passphrase_len, 0); + if (is < 0) + return PyObjectResult(is); + + return PyObjectResult(crypt_keyslot_destroy(self->device, is)); +} + +#define CryptSetup_killSlot_HELP "Destroy keyslot\n\n\ + killSlot(slot)\n\n\ + slot - the slot to remove" + +static PyObject *CryptSetup_killSlot(CryptSetupObject* self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"slot", NULL}; + int slot = CRYPT_ANY_SLOT; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "i", kwlist, &slot)) + return NULL; + + switch (crypt_keyslot_status(self->device, slot)) { + case CRYPT_SLOT_ACTIVE: + return PyObjectResult(crypt_keyslot_destroy(self->device, slot)); + case CRYPT_SLOT_ACTIVE_LAST: + PyErr_SetString(PyExc_ValueError, "Last slot, removing it would render the device unusable"); + break; + case CRYPT_SLOT_INACTIVE: + PyErr_SetString(PyExc_ValueError, "Inactive slot"); + break; + case CRYPT_SLOT_INVALID: + PyErr_SetString(PyExc_ValueError, "Invalid slot"); + break; + } + + return NULL; +} + +#define CryptSetup_Status_HELP "Status of LUKS device\n\n\ + luksStatus()" + +static PyObject *CryptSetup_Status(CryptSetupObject* self, PyObject *args, PyObject *kwds) +{ + if (!self->activated_as){ + PyErr_SetString(PyExc_IOError, "Device has not been activated yet."); + return NULL; + } + + return PyObjectResult(crypt_status(self->device, self->activated_as)); +} + +#define CryptSetup_Resume_HELP "Resume LUKS device\n\n\ + luksOpen(passphrase)\n\n\ + passphrase - string or none to ask the user" + +static PyObject *CryptSetup_Resume(CryptSetupObject* self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"passphrase", NULL}; + char* passphrase = NULL; + size_t passphrase_len = 0; + + if (!self->activated_as){ + PyErr_SetString(PyExc_IOError, "Device has not been activated yet."); + return NULL; + } + + if (! PyArg_ParseTupleAndKeywords(args, kwds, "|s", kwlist, &passphrase)) + return NULL; + + if (passphrase) + passphrase_len = strlen(passphrase); + + return PyObjectResult(crypt_resume_by_passphrase(self->device, self->activated_as, + CRYPT_ANY_SLOT, passphrase, passphrase_len)); +} + +#define CryptSetup_Suspend_HELP "Suspend LUKS device\n\n\ + luksSupsend()" + +static PyObject *CryptSetup_Suspend(CryptSetupObject* self, PyObject *args, PyObject *kwds) +{ + if (!self->activated_as){ + PyErr_SetString(PyExc_IOError, "Device has not been activated yet."); + return NULL; + } + + return PyObjectResult(crypt_suspend(self->device, self->activated_as)); +} + +static PyMemberDef CryptSetup_members[] = { + {"yesDialogCB", T_OBJECT_EX, offsetof(CryptSetupObject, yesDialogCB), 0, "confirmation dialog callback"}, + {"cmdLineLogCB", T_OBJECT_EX, offsetof(CryptSetupObject, cmdLineLogCB), 0, "logging callback"}, + {"passwordDialogCB", T_OBJECT_EX, offsetof(CryptSetupObject, passwordDialogCB), 0, "password dialog callback"}, + {NULL} +}; + +static PyMethodDef CryptSetup_methods[] = { + /* self-test methods */ + {"log", (PyCFunction)CryptSetup_log, METH_VARARGS|METH_KEYWORDS, CryptSetup_askyes_HELP}, + {"askyes", (PyCFunction)CryptSetup_askyes, METH_VARARGS|METH_KEYWORDS, CryptSetup_log_HELP}, + + /* activation and deactivation */ + {"deactivate", (PyCFunction)CryptSetup_deactivate, METH_NOARGS, CryptSetup_deactivate_HELP}, + {"activate", (PyCFunction)CryptSetup_activate, METH_VARARGS|METH_KEYWORDS, CryptSetup_activate_HELP}, + + /* cryptsetup info entrypoints */ + {"luksUUID", (PyCFunction)CryptSetup_luksUUID, METH_NOARGS, CryptSetup_luksUUID_HELP}, + {"isLuks", (PyCFunction)CryptSetup_isLuks, METH_NOARGS, CryptSetup_isLuks_HELP}, + {"info", (PyCFunction)CryptSetup_Info, METH_NOARGS, CryptSetup_Info_HELP}, + {"status", (PyCFunction)CryptSetup_Status, METH_NOARGS, CryptSetup_Status_HELP}, + + /* cryptsetup mgmt entrypoints */ + {"luksFormat", (PyCFunction)CryptSetup_luksFormat, METH_VARARGS|METH_KEYWORDS, CryptSetup_luksFormat_HELP}, + {"addKeyByPassphrase", (PyCFunction)CryptSetup_addKeyByPassphrase, METH_VARARGS|METH_KEYWORDS, CryptSetup_addKeyByPassphrase_HELP}, + {"addKeyByVolumeKey", (PyCFunction)CryptSetup_addKeyByVolumeKey, METH_VARARGS|METH_KEYWORDS, CryptSetup_addKeyByVolumeKey_HELP}, + {"removePassphrase", (PyCFunction)CryptSetup_removePassphrase, METH_VARARGS|METH_KEYWORDS, CryptSetup_removePassphrase_HELP}, + {"killSlot", (PyCFunction)CryptSetup_killSlot, METH_VARARGS|METH_KEYWORDS, CryptSetup_killSlot_HELP}, + + /* suspend resume */ + {"resume", (PyCFunction)CryptSetup_Resume, METH_VARARGS|METH_KEYWORDS, CryptSetup_Resume_HELP}, + {"suspend", (PyCFunction)CryptSetup_Suspend, METH_NOARGS, CryptSetup_Suspend_HELP}, + + {NULL} /* Sentinel */ +}; + +static PyTypeObject CryptSetupType = { + PyObject_HEAD_INIT(NULL) + 0, /*ob_size*/ + "pycryptsetup.CryptSetup", /*tp_name*/ + sizeof(CryptSetupObject), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + (destructor)CryptSetup_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + 0, /*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 */ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ + CryptSetup_HELP, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + CryptSetup_methods, /* tp_methods */ + CryptSetup_members, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)CryptSetup_init, /* tp_init */ + 0, /* tp_alloc */ + CryptSetup_new, /* tp_new */ +}; + +static PyMethodDef pycryptsetup_methods[] = { + {NULL} /* Sentinel */ +}; + +PyMODINIT_FUNC initpycryptsetup(void); +PyMODINIT_FUNC initpycryptsetup(void) +{ + PyObject *m; + + if (PyType_Ready(&CryptSetupType) < 0) + return; + + m = Py_InitModule3("pycryptsetup", pycryptsetup_methods, "CryptSetup pythonized API."); + Py_INCREF((PyObject *)&CryptSetupType); + + PyModule_AddObject(m, "CryptSetup", (PyObject *)&CryptSetupType); +} -- 2.34.1