Fix deactivation of device when failed underlying node disappeared
[platform/upstream/cryptsetup.git] / python / pycryptsetup.c
index 419454b..7c6253a 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Python bindings to libcryptsetup
  *
- * Copyright (C) 2009-2011, Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2009-2012, Red Hat, Inc. All rights reserved.
  * Written by Martin Sivak
  *
  * This file is free software; you can redistribute it and/or
@@ -69,6 +69,7 @@ static int passwordDialog(const char *msg, char *buf, size_t length, void *this)
 {
        CryptSetupObject *self = this;
        PyObject *result, *arglist;
+       size_t len;
        char *res = NULL;
 
        if(self->passwordDialogCB){
@@ -88,10 +89,12 @@ static int passwordDialog(const char *msg, char *buf, size_t length, void *this)
                }
 
                strncpy(buf, res, length - 1);
+               len = strlen(res);
 
-               // FIXME: wipe res
+               memset(res, 0, len);
                Py_DECREF(result);
-               return strlen(buf);
+
+               return (int)len;
        }
 
        return -EINVAL;
@@ -168,6 +171,7 @@ static int CryptSetup_init(CryptSetupObject* self, PyObject *args, PyObject *kwd
                 *cmdLineLogCB = NULL,
                 *tmp = NULL;
        char *device = NULL, *deviceName = NULL;
+       int r;
 
        if (!PyArg_ParseTupleAndKeywords(args, kwds, "|zzOOO", kwlist, &device, &deviceName,
                                         &yesDialogCB, &passwordDialogCB, &cmdLineLogCB))
@@ -178,19 +182,23 @@ static int CryptSetup_init(CryptSetupObject* self, PyObject *args, PyObject *kwd
                        PyErr_SetString(PyExc_IOError, "Device cannot be opened");
                        return -1;
                }
-
+               /* Try to load header form device */
+               r = crypt_load(self->device, NULL, NULL);
+               if (r && r != -EINVAL) {
+                       PyErr_SetString(PyExc_RuntimeError, "Cannot initialize device context");
+                       return -1;
+               }
        } else if (deviceName) {
                if (crypt_init_by_name(&(self->device), deviceName)) {
                        PyErr_SetString(PyExc_IOError, "Device cannot be opened");
                        return -1;
                }
+               /* Context is initialized automatically from active device */
        } 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);
 
@@ -554,6 +562,40 @@ static PyObject *CryptSetup_Suspend(CryptSetupObject* self, PyObject *args, PyOb
        return PyObjectResult(crypt_suspend(self->device, self->activated_as));
 }
 
+#define CryptSetup_debugLevel_HELP "Set debug level\n\n\
+  debugLevel(level)\n\n\
+  level - debug level"
+
+static PyObject *CryptSetup_debugLevel(CryptSetupObject* self, PyObject *args, PyObject *kwds)
+{
+       static char *kwlist[] = {"level", NULL};
+       int level = 0;
+
+       if (!PyArg_ParseTupleAndKeywords(args, kwds, "i", kwlist, &level))
+               return NULL;
+
+       crypt_set_debug_level(level);
+
+       Py_RETURN_NONE;
+}
+
+#define CryptSetup_iterationTime_HELP "Set iteration time\n\n\
+  iterationTime(time_ms)\n\n\
+  time_ms - time in miliseconds"
+
+static PyObject *CryptSetup_iterationTime(CryptSetupObject* self, PyObject *args, PyObject *kwds)
+{
+       static char *kwlist[] = {"time_ms", NULL};
+       uint64_t time_ms = 0;
+
+       if (!PyArg_ParseTupleAndKeywords(args, kwds, "K", kwlist, &time_ms))
+               return NULL;
+
+       crypt_set_iteration_time(self->device, time_ms);
+
+       Py_RETURN_NONE;
+}
+
 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"},
@@ -587,6 +629,10 @@ static PyMethodDef CryptSetup_methods[] = {
        {"resume", (PyCFunction)CryptSetup_Resume, METH_VARARGS|METH_KEYWORDS, CryptSetup_Resume_HELP},
        {"suspend", (PyCFunction)CryptSetup_Suspend, METH_NOARGS, CryptSetup_Suspend_HELP},
 
+       /* misc */
+       {"debugLevel", (PyCFunction)CryptSetup_debugLevel, METH_VARARGS|METH_KEYWORDS, CryptSetup_debugLevel_HELP},
+       {"iterationTime", (PyCFunction)CryptSetup_iterationTime, METH_VARARGS|METH_KEYWORDS, CryptSetup_iterationTime_HELP},
+
        {NULL} /* Sentinel */
 };
 
@@ -645,7 +691,23 @@ PyMODINIT_FUNC initpycryptsetup(void)
                return;
 
        m = Py_InitModule3("pycryptsetup", pycryptsetup_methods, "CryptSetup pythonized API.");
-       Py_INCREF((PyObject *)&CryptSetupType);
+       Py_INCREF(&CryptSetupType);
 
        PyModule_AddObject(m, "CryptSetup", (PyObject *)&CryptSetupType);
+
+       /* debug constants */
+       PyModule_AddIntConstant(m, "CRYPT_DEBUG_ALL", CRYPT_DEBUG_ALL);
+       PyModule_AddIntConstant(m, "CRYPT_DEBUG_NONE", CRYPT_DEBUG_NONE);
+
+       /* log constants */
+       PyModule_AddIntConstant(m, "CRYPT_LOG_NORMAL", CRYPT_LOG_NORMAL);
+       PyModule_AddIntConstant(m, "CRYPT_LOG_ERROR", CRYPT_LOG_ERROR);
+       PyModule_AddIntConstant(m, "CRYPT_LOG_VERBOSE", CRYPT_LOG_VERBOSE);
+       PyModule_AddIntConstant(m, "CRYPT_LOG_DEBUG", CRYPT_LOG_DEBUG);
+
+       /* status constants */
+       PyModule_AddIntConstant(m, "CRYPT_INVALID", CRYPT_INVALID);
+       PyModule_AddIntConstant(m, "CRYPT_INACTIVE", CRYPT_INACTIVE);
+       PyModule_AddIntConstant(m, "CRYPT_ACTIVE", CRYPT_ACTIVE);
+       PyModule_AddIntConstant(m, "CRYPT_BUSY", CRYPT_BUSY);
 }