~ubuntu-branches/debian/sid/cryptsetup/sid

« back to all changes in this revision

Viewing changes to python/pycryptsetup.c

  • Committer: Package Import Robot
  • Author(s): Jonas Meurer
  • Date: 2012-02-05 03:17:59 UTC
  • mfrom: (0.2.9)
  • Revision ID: package-import@ubuntu.com-20120205031759-kua3bplwunj0q2zl
Tags: 2:1.4.1-1
* new upstream release (1.4.0 + 1.4.1) (closes: #647851)
  - fixes typo in german translation. (closes: #645528)
  - remove patches, all incorporated upstream.
  - soname bump, rename library package to libcryptsetup4
* check for busybox in initramfs cryptroot hook, and install the sed binary
  in case it's either not installed or not activated. (closes: #591853)
* add checks for 'type $KEYSCRIPT' to initscripts cryptdisks.functions, and
  to cryptroot initramfs script/hook. this adds support for keyscripts inside
  $PATH. thanks to Ian Jackson for the suggestion. (closes: #597583)
* use argument '--sysinit' for vgchange in cryptroot initramfs script. Thanks
  to Christoph Anton Mitterer for the suggestion.
* add option for discard/trim features to crypttab and initramfs scripts.
  Thanks to intrigeri and Peter Colberg for patches. (closes: #648868)
* print $target on error in initramfs hook. Thanks to Daniel Hahler for the
  bugreport. (closes: #648192)
* add a warning about using decrypt_derived keyscript for devices with
  persistent data. Thanks to Arno Wagner for pointing this out.
* remove quotes from resume device candidates at get_resume_devs() in
  initramfs hook script. Thanks to Johannes Rohr. (closes: #634017)
* support custom $TABFILE, thanks to Douglas Huff. (closes: #638317)
* fix get_lvm_deps() in initramfs cryptroot hook to add all physical volumes
  of lvm volume group that contains the rootfs logical volume, even if the
  rootfs is lv is not spread over all physical volumes. Thanks to Christian
  Pernegger for bugreport and patch. (closes: #634109)
* debian/initramfs/cryptroot-script: Move check for maximum number of tries
  behind the while loop, to make the warning appear in case that maximum
  number of tries is reached. Thanks to Chistian Lamparter for bugreport and
  patch. (closes: #646083)
* incorporate changes to package descriptions and debconf templates that
  suggested by debian-l10n-english people. Special thanks go to Justin B Rye.
* acknowledge NMU, thanks a lot to Christian Perrier for his great work on
  the i18n front. (closes: #633105, #641719, #641839, #641947, #642470,
  #640056, #642540, #643633, #643962, #644853)
* add and update debconf translations:
  - italian, thanks to Milo Casagrande, Francesca Ciceri. (closes: #656933)
  - german, thanks to Erik Pfannenstein. (closes: #642147)
  - spanish, thanks to Camaleón. (closes: #658360)
  - russian, thanks to Yuri Kuzlov (closes: #654676)
* set architecture to linux-any, depends on linux kernel anyway. Thanks to
  Christoph Egger. (closes: #638257)
* small updates to the copyright file.
* add targets build-indep and build-arch to debian/rules, thanks to lintian.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Python bindings to libcryptsetup
 
3
 *
 
4
 * Copyright (C) 2009-2011, Red Hat, Inc. All rights reserved.
 
5
 * Written by Martin Sivak
 
6
 *
 
7
 * This file is free software; you can redistribute it and/or
 
8
 * modify it under the terms of the GNU Lesser General Public
 
9
 * License as published by the Free Software Foundation; either
 
10
 * version 2.1 of the License, or (at your option) any later version.
 
11
 *
 
12
 * This file is distributed in the hope that it will be useful,
 
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
15
 * Lesser General Public License for more details.
 
16
 *
 
17
 * You should have received a copy of the GNU Lesser General Public
 
18
 * License along with this file; if not, write to the Free Software
 
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 
20
 */
 
21
 
 
22
#include <Python.h>
 
23
#include <structmember.h>
 
24
#include <errno.h>
 
25
 
 
26
#include "libcryptsetup.h"
 
27
 
 
28
typedef struct {
 
29
        PyObject_HEAD
 
30
 
 
31
        /* Type-specific fields go here. */
 
32
        struct crypt_device *device;
 
33
        char *activated_as;
 
34
 
 
35
        /* Callbacks */
 
36
        PyObject *yesDialogCB;
 
37
        PyObject *cmdLineLogCB;
 
38
        PyObject *passwordDialogCB;
 
39
} CryptSetupObject;
 
40
 
 
41
static int yesDialog(const char *msg, void *this)
 
42
{
 
43
        CryptSetupObject *self = this;
 
44
        PyObject *result, *arglist;
 
45
        int r;
 
46
 
 
47
        if (self->yesDialogCB){
 
48
                arglist = Py_BuildValue("(s)", msg);
 
49
                if (!arglist)
 
50
                        return -ENOMEM;
 
51
 
 
52
                result = PyEval_CallObject(self->yesDialogCB, arglist);
 
53
                Py_DECREF(arglist);
 
54
 
 
55
                if (!result)
 
56
                        return -EINVAL;
 
57
 
 
58
                if (!PyArg_Parse(result, "i", &r))
 
59
                        r = -EINVAL;
 
60
 
 
61
                Py_DECREF(result);
 
62
                return r;
 
63
        }
 
64
 
 
65
        return 1;
 
66
}
 
67
 
 
68
static int passwordDialog(const char *msg, char *buf, size_t length, void *this)
 
69
{
 
70
        CryptSetupObject *self = this;
 
71
        PyObject *result, *arglist;
 
72
        size_t len;
 
73
        char *res = NULL;
 
74
 
 
75
        if(self->passwordDialogCB){
 
76
                arglist = Py_BuildValue("(s)", msg);
 
77
                if (!arglist)
 
78
                        return -ENOMEM;
 
79
 
 
80
                result = PyEval_CallObject(self->passwordDialogCB, arglist);
 
81
                Py_DECREF(arglist);
 
82
 
 
83
                if (!result)
 
84
                        return -EINVAL;
 
85
 
 
86
                if (!PyArg_Parse(result, "z", &res)) {
 
87
                        Py_DECREF(result);
 
88
                        return -EINVAL;
 
89
                }
 
90
 
 
91
                strncpy(buf, res, length - 1);
 
92
                len = strlen(res);
 
93
 
 
94
                memset(res, 0, len);
 
95
                Py_DECREF(result);
 
96
 
 
97
                return (int)len;
 
98
        }
 
99
 
 
100
        return -EINVAL;
 
101
}
 
102
 
 
103
static void cmdLineLog(int cls, const char *msg, void *this)
 
104
{
 
105
        CryptSetupObject *self = this;
 
106
        PyObject *result, *arglist;
 
107
 
 
108
        if(self->cmdLineLogCB) {
 
109
                arglist = Py_BuildValue("(is)", cls, msg);
 
110
                if(!arglist)
 
111
                        return;
 
112
 
 
113
                result = PyEval_CallObject(self->cmdLineLogCB, arglist);
 
114
                Py_DECREF(arglist);
 
115
                Py_XDECREF(result);
 
116
        }
 
117
}
 
118
 
 
119
static void CryptSetup_dealloc(CryptSetupObject* self)
 
120
{
 
121
        /* free the callbacks */
 
122
        Py_XDECREF(self->yesDialogCB);
 
123
        Py_XDECREF(self->cmdLineLogCB);
 
124
        Py_XDECREF(self->passwordDialogCB);
 
125
 
 
126
        free(self->activated_as);
 
127
 
 
128
        crypt_free(self->device);
 
129
 
 
130
        /* free self */
 
131
        self->ob_type->tp_free((PyObject*)self);
 
132
}
 
133
 
 
134
static PyObject *CryptSetup_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 
135
{
 
136
        CryptSetupObject *self = (CryptSetupObject *)type->tp_alloc(type, 0);
 
137
 
 
138
        if (self) {
 
139
                self->yesDialogCB = NULL;
 
140
                self->passwordDialogCB = NULL;
 
141
                self->cmdLineLogCB = NULL;
 
142
                self->activated_as = NULL;
 
143
        }
 
144
 
 
145
        return (PyObject *)self;
 
146
}
 
147
 
 
148
static PyObject *PyObjectResult(int is)
 
149
{
 
150
        PyObject *result = Py_BuildValue("i", is);
 
151
 
 
152
        if (!result)
 
153
                PyErr_SetString(PyExc_RuntimeError, "Error during constructing values for return value");
 
154
 
 
155
        return result;
 
156
}
 
157
 
 
158
#define CryptSetup_HELP "CryptSetup object\n\n\
 
159
constructor takes one to five arguments:\n\
 
160
  __init__(device, name, yesDialog, passwordDialog, logFunc)\n\n\
 
161
  yesDialog - python function with func(text) signature, \n\
 
162
              which asks the user question text and returns 1\n\
 
163
              of the answer was positive or 0 if not\n\
 
164
  logFunc   - python function with func(level, text) signature to log stuff somewhere"
 
165
 
 
166
static int CryptSetup_init(CryptSetupObject* self, PyObject *args, PyObject *kwds)
 
167
{
 
168
        static char *kwlist[] = {"device", "name", "yesDialog", "passwordDialog", "logFunc", NULL};
 
169
        PyObject *yesDialogCB = NULL,
 
170
                 *passwordDialogCB = NULL,
 
171
                 *cmdLineLogCB = NULL,
 
172
                 *tmp = NULL;
 
173
        char *device = NULL, *deviceName = NULL;
 
174
        int r;
 
175
 
 
176
        if (!PyArg_ParseTupleAndKeywords(args, kwds, "|zzOOO", kwlist, &device, &deviceName,
 
177
                                         &yesDialogCB, &passwordDialogCB, &cmdLineLogCB))
 
178
                return -1;
 
179
 
 
180
        if (device) {
 
181
                if (crypt_init(&(self->device), device)) {
 
182
                        PyErr_SetString(PyExc_IOError, "Device cannot be opened");
 
183
                        return -1;
 
184
                }
 
185
                /* Try to load header form device */
 
186
                r = crypt_load(self->device, NULL, NULL);
 
187
                if (r && r != -EINVAL) {
 
188
                        PyErr_SetString(PyExc_RuntimeError, "Cannot initialize device context");
 
189
                        return -1;
 
190
                }
 
191
        } else if (deviceName) {
 
192
                if (crypt_init_by_name(&(self->device), deviceName)) {
 
193
                        PyErr_SetString(PyExc_IOError, "Device cannot be opened");
 
194
                        return -1;
 
195
                }
 
196
                /* Context is initialized automatically from active device */
 
197
        } else {
 
198
                PyErr_SetString(PyExc_RuntimeError, "Either device file or luks name has to be specified");
 
199
                return -1;
 
200
        }
 
201
 
 
202
        if(deviceName)
 
203
                self->activated_as = strdup(deviceName);
 
204
 
 
205
        if (yesDialogCB) {
 
206
                tmp = self->yesDialogCB;
 
207
                Py_INCREF(yesDialogCB);
 
208
                self->yesDialogCB = yesDialogCB;
 
209
                Py_XDECREF(tmp);
 
210
                crypt_set_confirm_callback(self->device, yesDialog, self);
 
211
        }
 
212
 
 
213
        if (passwordDialogCB) {
 
214
                tmp = self->passwordDialogCB;
 
215
                Py_INCREF(passwordDialogCB);
 
216
                self->passwordDialogCB = passwordDialogCB;
 
217
                Py_XDECREF(tmp);
 
218
                crypt_set_password_callback(self->device, passwordDialog, self);
 
219
        }
 
220
 
 
221
        if (cmdLineLogCB) {
 
222
                tmp = self->cmdLineLogCB;
 
223
                Py_INCREF(cmdLineLogCB);
 
224
                self->cmdLineLogCB = cmdLineLogCB;
 
225
                Py_XDECREF(tmp);
 
226
                crypt_set_log_callback(self->device, cmdLineLog, self);
 
227
        }
 
228
 
 
229
        return 0;
 
230
}
 
231
 
 
232
#define CryptSetup_activate_HELP "Activate LUKS device\n\n\
 
233
  activate(name)"
 
234
 
 
235
static PyObject *CryptSetup_activate(CryptSetupObject* self, PyObject *args, PyObject *kwds)
 
236
{
 
237
        static char *kwlist[] = {"name", "passphrase", NULL};
 
238
        char *name = NULL, *passphrase = NULL;
 
239
        int is;
 
240
 
 
241
        if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|s", kwlist, &name, &passphrase))
 
242
                return NULL;
 
243
 
 
244
        // FIXME: allow keyfile and \0 in passphrase
 
245
        is = crypt_activate_by_passphrase(self->device, name, CRYPT_ANY_SLOT,
 
246
                                          passphrase, passphrase ? strlen(passphrase) : 0, 0);
 
247
 
 
248
        if (is >= 0) {
 
249
                free(self->activated_as);
 
250
                self->activated_as = strdup(name);
 
251
        }
 
252
 
 
253
        return PyObjectResult(is);
 
254
}
 
255
 
 
256
#define CryptSetup_deactivate_HELP "Dectivate LUKS device\n\n\
 
257
  deactivate()"
 
258
 
 
259
static PyObject *CryptSetup_deactivate(CryptSetupObject* self, PyObject *args, PyObject *kwds)
 
260
{
 
261
        int is = crypt_deactivate(self->device, self->activated_as);
 
262
 
 
263
        if (!is) {
 
264
                free(self->activated_as);
 
265
                self->activated_as = NULL;
 
266
        }
 
267
 
 
268
        return PyObjectResult(is);
 
269
}
 
270
 
 
271
#define CryptSetup_askyes_HELP "Asks a question using the configured dialog CB\n\n\
 
272
  int askyes(message)"
 
273
 
 
274
static PyObject *CryptSetup_askyes(CryptSetupObject* self, PyObject *args, PyObject *kwds)
 
275
{
 
276
        static char *kwlist[] = {"message", NULL};
 
277
        PyObject *message = NULL, *result, *arglist;
 
278
 
 
279
        if (!PyArg_ParseTupleAndKeywords(args, kwds, "O", kwlist, &message))
 
280
                return NULL;
 
281
 
 
282
        Py_INCREF(message);
 
283
 
 
284
        arglist = Py_BuildValue("(O)", message);
 
285
        if (!arglist){
 
286
                PyErr_SetString(PyExc_RuntimeError, "Error during constructing values for internal call");
 
287
                return NULL;
 
288
        }
 
289
 
 
290
        result = PyEval_CallObject(self->yesDialogCB, arglist);
 
291
        Py_DECREF(arglist);
 
292
        Py_DECREF(message);
 
293
 
 
294
        return result;
 
295
}
 
296
 
 
297
#define CryptSetup_log_HELP "Logs a string using the configured log CB\n\n\
 
298
  log(int level, message)"
 
299
 
 
300
static PyObject *CryptSetup_log(CryptSetupObject* self, PyObject *args, PyObject *kwds)
 
301
{
 
302
        static char *kwlist[] = {"priority", "message", NULL};
 
303
        PyObject *message = NULL, *priority = NULL, *result, *arglist;
 
304
 
 
305
        if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO", kwlist, &message, &priority))
 
306
                return NULL;
 
307
 
 
308
        Py_INCREF(message);
 
309
        Py_INCREF(priority);
 
310
 
 
311
        arglist = Py_BuildValue("(OO)", message, priority);
 
312
        if (!arglist){
 
313
                PyErr_SetString(PyExc_RuntimeError, "Error during constructing values for internal call");
 
314
                return NULL;
 
315
        }
 
316
 
 
317
        result = PyEval_CallObject(self->cmdLineLogCB, arglist);
 
318
        Py_DECREF(arglist);
 
319
        Py_DECREF(priority);
 
320
        Py_DECREF(message);
 
321
 
 
322
        return result;
 
323
}
 
324
 
 
325
#define CryptSetup_luksUUID_HELP "Get UUID of the LUKS device\n\n\
 
326
  luksUUID()"
 
327
 
 
328
static PyObject *CryptSetup_luksUUID(CryptSetupObject* self, PyObject *args, PyObject *kwds)
 
329
{
 
330
        PyObject *result;
 
331
 
 
332
        result = Py_BuildValue("s", crypt_get_uuid(self->device));
 
333
        if (!result)
 
334
                PyErr_SetString(PyExc_RuntimeError, "Error during constructing values for return value");
 
335
 
 
336
        return result;
 
337
}
 
338
 
 
339
#define CryptSetup_isLuks_HELP "Is the device LUKS?\n\n\
 
340
  isLuks()"
 
341
 
 
342
static PyObject *CryptSetup_isLuks(CryptSetupObject* self, PyObject *args, PyObject *kwds)
 
343
{
 
344
        return PyObjectResult(crypt_load(self->device, CRYPT_LUKS1, NULL));
 
345
}
 
346
 
 
347
#define CryptSetup_Info_HELP "Returns dictionary with info about opened device\nKeys:\n\
 
348
  dir\n  name\n  uuid\n  cipher\n  cipher_mode\n  keysize\n  device\n\
 
349
  offset\n  size\n  skip\n  mode\n"
 
350
 
 
351
static PyObject *CryptSetup_Info(CryptSetupObject* self, PyObject *args, PyObject *kwds)
 
352
{
 
353
        PyObject *result;
 
354
 
 
355
        result = Py_BuildValue("{s:s,s:s,s:z,s:s,s:s,s:s,s:i,s:K}",
 
356
                                "dir",          crypt_get_dir(),
 
357
                                "device",       crypt_get_device_name(self->device),
 
358
                                "name",         self->activated_as,
 
359
                                "uuid",         crypt_get_uuid(self->device),
 
360
                                "cipher",       crypt_get_cipher(self->device),
 
361
                                "cipher_mode",  crypt_get_cipher_mode(self->device),
 
362
                                "keysize",      crypt_get_volume_key_size(self->device) * 8,
 
363
                                //"size",       co.size,
 
364
                                //"mode",       (co.flags & CRYPT_FLAG_READONLY) ? "readonly" : "read/write",
 
365
                                "offset",       crypt_get_data_offset(self->device)
 
366
                                );
 
367
 
 
368
        if (!result)
 
369
                PyErr_SetString(PyExc_RuntimeError, "Error during constructing values for return value");
 
370
 
 
371
        return result;
 
372
}
 
373
 
 
374
#define CryptSetup_luksFormat_HELP "Format device to enable LUKS\n\n\
 
375
  luksFormat(cipher = 'aes', cipherMode = 'cbc-essiv:sha256', keysize = 256)\n\n\
 
376
  cipher - cipher specification, e.g. aes, serpent\n\
 
377
  cipherMode - cipher mode specification, e.g. cbc-essiv:sha256, xts-plain64\n\
 
378
  keysize - key size in bits"
 
379
 
 
380
static PyObject *CryptSetup_luksFormat(CryptSetupObject* self, PyObject *args, PyObject *kwds)
 
381
{
 
382
        static char *kwlist[] = {"cipher", "cipherMode", "keysize", NULL};
 
383
        char *cipher_mode = NULL, *cipher = NULL;
 
384
        int keysize = 256;
 
385
        PyObject *keysize_object = NULL;
 
386
 
 
387
        if (!PyArg_ParseTupleAndKeywords(args, kwds, "|zzO", kwlist, 
 
388
                                        &cipher, &cipher_mode, &keysize_object))
 
389
                return NULL;
 
390
 
 
391
        if (!keysize_object || keysize_object == Py_None) {
 
392
                /* use default value */
 
393
        } else if (!PyInt_Check(keysize_object)) {
 
394
                PyErr_SetString(PyExc_TypeError, "keysize must be an integer");
 
395
                return NULL;
 
396
        } else if (PyInt_AsLong(keysize_object) % 8) {
 
397
                PyErr_SetString(PyExc_TypeError, "keysize must have integer value dividable by 8");
 
398
                return NULL;
 
399
        } else if (PyInt_AsLong(keysize_object) <= 0) {
 
400
                PyErr_SetString(PyExc_TypeError, "keysize must be positive number bigger than 0");
 
401
                return NULL;
 
402
        } else
 
403
                keysize = PyInt_AsLong(keysize_object);
 
404
 
 
405
        // FIXME use #defined defaults
 
406
        return PyObjectResult(crypt_format(self->device, CRYPT_LUKS1,
 
407
                                cipher ?: "aes", cipher_mode ?: "cbc-essiv:sha256",
 
408
                                NULL, NULL, keysize / 8, NULL));
 
409
}
 
410
 
 
411
#define CryptSetup_addKeyByPassphrase_HELP "Initialize keyslot using passphrase\n\n\
 
412
  addKeyByPassphrase(passphrase, newPassphrase, slot)\n\n\
 
413
  passphrase - string or none to ask the user\n\
 
414
  newPassphrase - passphrase to add\n\
 
415
  slot - which slot to use (optional)"
 
416
 
 
417
static PyObject *CryptSetup_addKeyByPassphrase(CryptSetupObject* self, PyObject *args, PyObject *kwds)
 
418
{
 
419
        static char *kwlist[] = {"passphrase", "newPassphrase", "slot", NULL};
 
420
        char *passphrase = NULL, *newpassphrase = NULL;
 
421
        size_t passphrase_len = 0, newpassphrase_len = 0;
 
422
        int slot = CRYPT_ANY_SLOT;
 
423
 
 
424
        if (!PyArg_ParseTupleAndKeywords(args, kwds, "ss|i", kwlist, &passphrase, &newpassphrase, &slot))
 
425
                return NULL;
 
426
 
 
427
        if(passphrase)
 
428
                passphrase_len = strlen(passphrase);
 
429
 
 
430
        if(newpassphrase)
 
431
                newpassphrase_len = strlen(newpassphrase);
 
432
 
 
433
        return PyObjectResult(crypt_keyslot_add_by_passphrase(self->device, slot,
 
434
                                        passphrase, passphrase_len,
 
435
                                        newpassphrase, newpassphrase_len));
 
436
}
 
437
 
 
438
#define CryptSetup_addKeyByVolumeKey_HELP "Initialize keyslot using cached volume key\n\n\
 
439
  addKeyByVolumeKey(passphrase, newPassphrase, slot)\n\n\
 
440
  newPassphrase - passphrase to add\n\
 
441
  slot - which slot to use (optional)"
 
442
 
 
443
static PyObject *CryptSetup_addKeyByVolumeKey(CryptSetupObject* self, PyObject *args, PyObject *kwds)
 
444
{
 
445
        static char *kwlist[] = {"newPassphrase", "slot", NULL};
 
446
        char *newpassphrase = NULL;
 
447
        size_t newpassphrase_len = 0;
 
448
        int slot = CRYPT_ANY_SLOT;
 
449
 
 
450
        if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|i", kwlist, &newpassphrase, &slot))
 
451
                return NULL;
 
452
 
 
453
        if (newpassphrase)
 
454
                newpassphrase_len = strlen(newpassphrase);
 
455
 
 
456
        return PyObjectResult(crypt_keyslot_add_by_volume_key(self->device, slot,
 
457
                                        NULL, 0, newpassphrase, newpassphrase_len));
 
458
}
 
459
 
 
460
#define CryptSetup_removePassphrase_HELP "Destroy keyslot using passphrase\n\n\
 
461
  removePassphrase(passphrase)\n\n\
 
462
  passphrase - string or none to ask the user"
 
463
 
 
464
static PyObject *CryptSetup_removePassphrase(CryptSetupObject* self, PyObject *args, PyObject *kwds)
 
465
{
 
466
        static char *kwlist[] = {"passphrase", NULL};
 
467
        char *passphrase = NULL;
 
468
        size_t passphrase_len = 0;
 
469
        int is;
 
470
 
 
471
        if (!PyArg_ParseTupleAndKeywords(args, kwds, "s", kwlist, &passphrase))
 
472
                return NULL;
 
473
 
 
474
        if (passphrase)
 
475
                passphrase_len = strlen(passphrase);
 
476
 
 
477
        is = crypt_activate_by_passphrase(self->device, NULL, CRYPT_ANY_SLOT,
 
478
                                          passphrase, passphrase_len, 0);
 
479
        if (is < 0)
 
480
                return PyObjectResult(is);
 
481
 
 
482
        return PyObjectResult(crypt_keyslot_destroy(self->device, is));
 
483
}
 
484
 
 
485
#define CryptSetup_killSlot_HELP "Destroy keyslot\n\n\
 
486
  killSlot(slot)\n\n\
 
487
  slot - the slot to remove"
 
488
 
 
489
static PyObject *CryptSetup_killSlot(CryptSetupObject* self, PyObject *args, PyObject *kwds)
 
490
{
 
491
        static char *kwlist[] = {"slot", NULL};
 
492
        int slot = CRYPT_ANY_SLOT;
 
493
 
 
494
        if (!PyArg_ParseTupleAndKeywords(args, kwds, "i", kwlist, &slot))
 
495
                return NULL;
 
496
 
 
497
        switch (crypt_keyslot_status(self->device, slot)) {
 
498
        case CRYPT_SLOT_ACTIVE:
 
499
                return PyObjectResult(crypt_keyslot_destroy(self->device, slot));
 
500
        case CRYPT_SLOT_ACTIVE_LAST:
 
501
                PyErr_SetString(PyExc_ValueError, "Last slot, removing it would render the device unusable");
 
502
                break;
 
503
        case CRYPT_SLOT_INACTIVE:
 
504
                PyErr_SetString(PyExc_ValueError, "Inactive slot");
 
505
                break;
 
506
        case CRYPT_SLOT_INVALID:
 
507
                PyErr_SetString(PyExc_ValueError, "Invalid slot");
 
508
                break;
 
509
        }
 
510
 
 
511
        return NULL;
 
512
}
 
513
 
 
514
#define CryptSetup_Status_HELP "Status of LUKS device\n\n\
 
515
  luksStatus()"
 
516
 
 
517
static PyObject *CryptSetup_Status(CryptSetupObject* self, PyObject *args, PyObject *kwds)
 
518
{
 
519
        if (!self->activated_as){
 
520
                PyErr_SetString(PyExc_IOError, "Device has not been activated yet.");
 
521
                return NULL;
 
522
        }
 
523
 
 
524
        return PyObjectResult(crypt_status(self->device, self->activated_as));
 
525
}
 
526
 
 
527
#define CryptSetup_Resume_HELP "Resume LUKS device\n\n\
 
528
  luksOpen(passphrase)\n\n\
 
529
  passphrase - string or none to ask the user"
 
530
 
 
531
static PyObject *CryptSetup_Resume(CryptSetupObject* self, PyObject *args, PyObject *kwds)
 
532
{
 
533
        static char *kwlist[] = {"passphrase", NULL};
 
534
        char* passphrase = NULL;
 
535
        size_t passphrase_len = 0;
 
536
 
 
537
        if (!self->activated_as){
 
538
                PyErr_SetString(PyExc_IOError, "Device has not been activated yet.");
 
539
                return NULL;
 
540
        }
 
541
 
 
542
        if (! PyArg_ParseTupleAndKeywords(args, kwds, "|s", kwlist, &passphrase))
 
543
                return NULL;
 
544
 
 
545
        if (passphrase)
 
546
                passphrase_len = strlen(passphrase);
 
547
 
 
548
        return PyObjectResult(crypt_resume_by_passphrase(self->device, self->activated_as,
 
549
                                        CRYPT_ANY_SLOT, passphrase, passphrase_len));
 
550
}
 
551
 
 
552
#define CryptSetup_Suspend_HELP "Suspend LUKS device\n\n\
 
553
  luksSupsend()"
 
554
 
 
555
static PyObject *CryptSetup_Suspend(CryptSetupObject* self, PyObject *args, PyObject *kwds)
 
556
{
 
557
        if (!self->activated_as){
 
558
                PyErr_SetString(PyExc_IOError, "Device has not been activated yet.");
 
559
                return NULL;
 
560
        }
 
561
 
 
562
        return PyObjectResult(crypt_suspend(self->device, self->activated_as));
 
563
}
 
564
 
 
565
#define CryptSetup_debugLevel_HELP "Set debug level\n\n\
 
566
  debugLevel(level)\n\n\
 
567
  level - debug level"
 
568
 
 
569
static PyObject *CryptSetup_debugLevel(CryptSetupObject* self, PyObject *args, PyObject *kwds)
 
570
{
 
571
        static char *kwlist[] = {"level", NULL};
 
572
        int level = 0;
 
573
 
 
574
        if (!PyArg_ParseTupleAndKeywords(args, kwds, "i", kwlist, &level))
 
575
                return NULL;
 
576
 
 
577
        crypt_set_debug_level(level);
 
578
 
 
579
        Py_RETURN_NONE;
 
580
}
 
581
 
 
582
#define CryptSetup_iterationTime_HELP "Set iteration time\n\n\
 
583
  iterationTime(time_ms)\n\n\
 
584
  time_ms - time in miliseconds"
 
585
 
 
586
static PyObject *CryptSetup_iterationTime(CryptSetupObject* self, PyObject *args, PyObject *kwds)
 
587
{
 
588
        static char *kwlist[] = {"time_ms", NULL};
 
589
        uint64_t time_ms = 0;
 
590
 
 
591
        if (!PyArg_ParseTupleAndKeywords(args, kwds, "K", kwlist, &time_ms))
 
592
                return NULL;
 
593
 
 
594
        crypt_set_iteration_time(self->device, time_ms);
 
595
 
 
596
        Py_RETURN_NONE;
 
597
}
 
598
 
 
599
static PyMemberDef CryptSetup_members[] = {
 
600
        {"yesDialogCB", T_OBJECT_EX, offsetof(CryptSetupObject, yesDialogCB), 0, "confirmation dialog callback"},
 
601
        {"cmdLineLogCB", T_OBJECT_EX, offsetof(CryptSetupObject, cmdLineLogCB), 0, "logging callback"},
 
602
        {"passwordDialogCB", T_OBJECT_EX, offsetof(CryptSetupObject, passwordDialogCB), 0, "password dialog callback"},
 
603
        {NULL}
 
604
};
 
605
 
 
606
static PyMethodDef CryptSetup_methods[] = {
 
607
        /* self-test methods */
 
608
        {"log", (PyCFunction)CryptSetup_log, METH_VARARGS|METH_KEYWORDS, CryptSetup_askyes_HELP},
 
609
        {"askyes", (PyCFunction)CryptSetup_askyes, METH_VARARGS|METH_KEYWORDS, CryptSetup_log_HELP},
 
610
 
 
611
        /* activation and deactivation */
 
612
        {"deactivate", (PyCFunction)CryptSetup_deactivate, METH_NOARGS, CryptSetup_deactivate_HELP},
 
613
        {"activate", (PyCFunction)CryptSetup_activate, METH_VARARGS|METH_KEYWORDS, CryptSetup_activate_HELP},
 
614
 
 
615
        /* cryptsetup info entrypoints */
 
616
        {"luksUUID", (PyCFunction)CryptSetup_luksUUID, METH_NOARGS, CryptSetup_luksUUID_HELP},
 
617
        {"isLuks", (PyCFunction)CryptSetup_isLuks, METH_NOARGS, CryptSetup_isLuks_HELP},
 
618
        {"info", (PyCFunction)CryptSetup_Info, METH_NOARGS, CryptSetup_Info_HELP},  
 
619
        {"status", (PyCFunction)CryptSetup_Status, METH_NOARGS, CryptSetup_Status_HELP},
 
620
 
 
621
        /* cryptsetup mgmt entrypoints */
 
622
        {"luksFormat", (PyCFunction)CryptSetup_luksFormat, METH_VARARGS|METH_KEYWORDS, CryptSetup_luksFormat_HELP},
 
623
        {"addKeyByPassphrase", (PyCFunction)CryptSetup_addKeyByPassphrase, METH_VARARGS|METH_KEYWORDS, CryptSetup_addKeyByPassphrase_HELP},
 
624
        {"addKeyByVolumeKey", (PyCFunction)CryptSetup_addKeyByVolumeKey, METH_VARARGS|METH_KEYWORDS, CryptSetup_addKeyByVolumeKey_HELP},
 
625
        {"removePassphrase", (PyCFunction)CryptSetup_removePassphrase, METH_VARARGS|METH_KEYWORDS, CryptSetup_removePassphrase_HELP},
 
626
        {"killSlot", (PyCFunction)CryptSetup_killSlot, METH_VARARGS|METH_KEYWORDS, CryptSetup_killSlot_HELP},
 
627
 
 
628
        /* suspend resume */
 
629
        {"resume", (PyCFunction)CryptSetup_Resume, METH_VARARGS|METH_KEYWORDS, CryptSetup_Resume_HELP},
 
630
        {"suspend", (PyCFunction)CryptSetup_Suspend, METH_NOARGS, CryptSetup_Suspend_HELP},
 
631
 
 
632
        /* misc */
 
633
        {"debugLevel", (PyCFunction)CryptSetup_debugLevel, METH_VARARGS|METH_KEYWORDS, CryptSetup_debugLevel_HELP},
 
634
        {"iterationTime", (PyCFunction)CryptSetup_iterationTime, METH_VARARGS|METH_KEYWORDS, CryptSetup_iterationTime_HELP},
 
635
 
 
636
        {NULL} /* Sentinel */
 
637
};
 
638
 
 
639
static PyTypeObject CryptSetupType = {
 
640
        PyObject_HEAD_INIT(NULL)
 
641
        0, /*ob_size*/
 
642
        "pycryptsetup.CryptSetup", /*tp_name*/
 
643
        sizeof(CryptSetupObject), /*tp_basicsize*/
 
644
        0, /*tp_itemsize*/
 
645
        (destructor)CryptSetup_dealloc, /*tp_dealloc*/
 
646
        0, /*tp_print*/
 
647
        0, /*tp_getattr*/
 
648
        0, /*tp_setattr*/
 
649
        0, /*tp_compare*/
 
650
        0, /*tp_repr*/
 
651
        0, /*tp_as_number*/
 
652
        0, /*tp_as_sequence*/
 
653
        0, /*tp_as_mapping*/
 
654
        0, /*tp_hash */
 
655
        0, /*tp_call*/
 
656
        0, /*tp_str*/
 
657
        0, /*tp_getattro*/
 
658
        0, /*tp_setattro*/
 
659
        0, /*tp_as_buffer*/
 
660
        Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
 
661
        CryptSetup_HELP, /* tp_doc */
 
662
        0, /* tp_traverse */
 
663
        0, /* tp_clear */
 
664
        0, /* tp_richcompare */
 
665
        0, /* tp_weaklistoffset */
 
666
        0, /* tp_iter */
 
667
        0, /* tp_iternext */
 
668
        CryptSetup_methods, /* tp_methods */
 
669
        CryptSetup_members, /* tp_members */
 
670
        0, /* tp_getset */
 
671
        0, /* tp_base */
 
672
        0, /* tp_dict */
 
673
        0, /* tp_descr_get */
 
674
        0, /* tp_descr_set */
 
675
        0, /* tp_dictoffset */
 
676
        (initproc)CryptSetup_init, /* tp_init */
 
677
        0, /* tp_alloc */
 
678
        CryptSetup_new, /* tp_new */
 
679
};
 
680
 
 
681
static PyMethodDef pycryptsetup_methods[] = {
 
682
        {NULL} /* Sentinel */
 
683
};
 
684
 
 
685
PyMODINIT_FUNC initpycryptsetup(void);
 
686
PyMODINIT_FUNC initpycryptsetup(void)
 
687
{
 
688
        PyObject *m;
 
689
 
 
690
        if (PyType_Ready(&CryptSetupType) < 0)
 
691
                return;
 
692
 
 
693
        m = Py_InitModule3("pycryptsetup", pycryptsetup_methods, "CryptSetup pythonized API.");
 
694
        Py_INCREF(&CryptSetupType);
 
695
 
 
696
        PyModule_AddObject(m, "CryptSetup", (PyObject *)&CryptSetupType);
 
697
 
 
698
        /* debug constants */
 
699
        PyModule_AddIntConstant(m, "CRYPT_DEBUG_ALL", CRYPT_DEBUG_ALL);
 
700
        PyModule_AddIntConstant(m, "CRYPT_DEBUG_NONE", CRYPT_DEBUG_NONE);
 
701
 
 
702
        /* log constants */
 
703
        PyModule_AddIntConstant(m, "CRYPT_LOG_NORMAL", CRYPT_LOG_NORMAL);
 
704
        PyModule_AddIntConstant(m, "CRYPT_LOG_ERROR", CRYPT_LOG_ERROR);
 
705
        PyModule_AddIntConstant(m, "CRYPT_LOG_VERBOSE", CRYPT_LOG_VERBOSE);
 
706
        PyModule_AddIntConstant(m, "CRYPT_LOG_DEBUG", CRYPT_LOG_DEBUG);
 
707
 
 
708
        /* status constants */
 
709
        PyModule_AddIntConstant(m, "CRYPT_INVALID", CRYPT_INVALID);
 
710
        PyModule_AddIntConstant(m, "CRYPT_INACTIVE", CRYPT_INACTIVE);
 
711
        PyModule_AddIntConstant(m, "CRYPT_ACTIVE", CRYPT_ACTIVE);
 
712
        PyModule_AddIntConstant(m, "CRYPT_BUSY", CRYPT_BUSY);
 
713
}