diff options
author | wiktor w brodlo <wiktor@brodlo.net> | 2011-06-15 16:59:54 +0000 |
---|---|---|
committer | wiktor w brodlo <wiktor@brodlo.net> | 2011-06-15 16:59:54 +0000 |
commit | 2590d96369d0217e31dc2812690dde61dac417b5 (patch) | |
tree | 82276f787b08a28548e342c7921486f1acefab9f /storage/devicelibs/crypto.py | |
parent | first commit (diff) | |
download | anaconda-2590d96369d0217e31dc2812690dde61dac417b5.tar.gz anaconda-2590d96369d0217e31dc2812690dde61dac417b5.tar.bz2 anaconda-2590d96369d0217e31dc2812690dde61dac417b5.zip |
Initial import from Sabayon (ver 0.9.9.56)
Diffstat (limited to 'storage/devicelibs/crypto.py')
-rw-r--r-- | storage/devicelibs/crypto.py | 193 |
1 files changed, 193 insertions, 0 deletions
diff --git a/storage/devicelibs/crypto.py b/storage/devicelibs/crypto.py new file mode 100644 index 0000000..136435d --- /dev/null +++ b/storage/devicelibs/crypto.py @@ -0,0 +1,193 @@ +# +# crypto.py +# +# Copyright (C) 2009 Red Hat, Inc. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify +# 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. +# +# This program 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 this program. If not, see <http://www.gnu.org/licenses/>. +# +# Author(s): Dave Lehman <dlehman@redhat.com> +# Martin Sivak <msivak@redhat.com> +# + +import os +from pycryptsetup import CryptSetup +import iutil + +from ..errors import * + +import gettext +_ = lambda x: gettext.ldgettext("anaconda", x) + +# Keep the character set size a power of two to make sure all characters are +# equally likely +GENERATED_PASSPHRASE_CHARSET = ("0123456789" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "./") +# 20 chars * 6 bits per char = 120 "bits of security" +GENERATED_PASSPHRASE_LENGTH = 20 + +def generateBackupPassphrase(): + rnd = os.urandom(GENERATED_PASSPHRASE_LENGTH) + cs = GENERATED_PASSPHRASE_CHARSET + raw = "".join([cs[ord(c) % len(cs)] for c in rnd]) + + # Make the result easier to read + parts = [] + for i in xrange(0, len(raw), 5): + parts.append(raw[i : i + 5]) + return "-".join(parts) + +def askyes(question): + return True + +def dolog(priority, text): + pass + +def is_luks(device): + cs = CryptSetup(yesDialog = askyes, logFunc = dolog) + return cs.isLuks(device) + +def luks_uuid(device): + cs = CryptSetup(yesDialog = askyes, logFunc = dolog) + return cs.luksUUID(device).strip() + +def luks_status(name): + """True means active, False means inactive (or non-existent)""" + cs = CryptSetup(yesDialog = askyes, logFunc = dolog) + return cs.luksStatus(name)!=0 + +def luks_format(device, + passphrase=None, key_file=None, + cipher=None, key_size=None): + cs = CryptSetup(yesDialog = askyes, logFunc = dolog) + key_file_unlink = False + + if passphrase: + key_file = cs.prepare_passphrase_file(passphrase) + key_file_unlink = True + elif key_file and os.path.isfile(key_file): + pass + else: + raise ValueError("luks_format requires either a passphrase or a key file") + + #None is not considered as default value and pycryptsetup doesn't accept it + #so we need to filter out all Nones + kwargs = {} + kwargs["device"] = device + if cipher: kwargs["cipher"] = cipher + if key_file: kwargs["keyfile"] = key_file + if key_size: kwargs["keysize"] = key_size + + rc = cs.luksFormat(**kwargs) + if key_file_unlink: os.unlink(key_file) + + if rc: + raise CryptoError("luks_format failed for '%s'" % device) + +def luks_open(device, name, passphrase=None, key_file=None): + cs = CryptSetup(yesDialog = askyes, logFunc = dolog) + key_file_unlink = False + + if passphrase: + key_file = cs.prepare_passphrase_file(passphrase) + key_file_unlink = True + elif key_file and os.path.isfile(key_file): + pass + else: + raise ValueError("luks_open requires either a passphrase or a key file") + + rc = cs.luksOpen(device = device, name = name, keyfile = key_file) + if key_file_unlink: os.unlink(key_file) + if rc: + raise CryptoError("luks_open failed for %s (%s)" % (device, name)) + +def luks_close(name): + cs = CryptSetup(yesDialog = askyes, logFunc = dolog) + rc = cs.luksClose(name) + if rc: + raise CryptoError("luks_close failed for %s" % name) + +def luks_add_key(device, + new_passphrase=None, new_key_file=None, + passphrase=None, key_file=None): + + params = ["-q"] + + p = os.pipe() + if passphrase: + os.write(p[1], "%s\n" % passphrase) + elif key_file and os.path.isfile(key_file): + params.extend(["--key-file", key_file]) + else: + raise CryptoError("luks_add_key requires either a passphrase or a key file") + + params.extend(["luksAddKey", device]) + + if new_passphrase: + os.write(p[1], "%s\n" % new_passphrase) + elif new_key_file and os.path.isfile(new_key_file): + params.append("%s" % new_key_file) + else: + raise CryptoError("luks_add_key requires either a passphrase or a key file to add") + + os.close(p[1]) + + rc = iutil.execWithRedirect("cryptsetup", params, + stdin = p[0], + stdout = "/dev/tty5", + stderr = "/dev/tty5") + + os.close(p[0]) + if rc: + raise CryptoError("luks add key failed with errcode %d" % (rc,)) + +def luks_remove_key(device, + del_passphrase=None, del_key_file=None, + passphrase=None, key_file=None): + + params = [] + + p = os.pipe() + if del_passphrase: #the first question is about the key we want to remove + os.write(p[1], "%s\n" % del_passphrase) + + if passphrase: + os.write(p[1], "%s\n" % passphrase) + elif key_file and os.path.isfile(key_file): + params.extend(["--key-file", key_file]) + else: + raise CryptoError("luks_remove_key requires either a passphrase or a key file") + + params.extend(["luksRemoveKey", device]) + + if del_passphrase: + pass + elif del_key_file and os.path.isfile(del_key_file): + params.append("%s" % del_key_file) + else: + raise CryptoError("luks_remove_key requires either a passphrase or a key file to remove") + + os.close(p[1]) + + rc = iutil.execWithRedirect("cryptsetup", params, + stdin = p[0], + stdout = "/dev/tty5", + stderr = "/dev/tty5") + + os.close(p[0]) + if rc: + raise CryptoError("luks_remove_key failed with errcode %d" % (rc,)) + + |