def createCryptDir(self,userName,uid,gud,userDir):
        """
        Создать шифрование домашней директории, или подключить существующую
        """
        userPwd = getKey(userName)
        if not userPwd or userPwd == "XXXXXXXX":
            raise DesktopError(_("User password not found"))
        ecryptfsPath = path.join('/home/.ecryptfs',userName)
        if path.exists(ecryptfsPath):
            for d in (".ecryptfs",".Private"):
                source,target = path.join(ecryptfsPath,d),path.join(userDir,d)
                if not path.lexists(target):
                    os.symlink(source,target)
            try:
                if not mountEcryptfs(userName,userPwd,userDir):
                    raise DesktopError(_("Failed to mount ecrypted data"))
            except CommonError as e:
                raise DesktopError(_("Failed to mount ecrypted data")+": \"%s\""%str(e))
        else:
            tf = None
            try:
                # если профиль содержит только данные от бутстрапа core
                if isBootstrapDataOnly(userDir):
                    if childMounts(userDir):
                        raise DesktopError(
                            _("Failed to create encrypt user profile")+":"+
                            _("User home directory contains mount points"))
                    # поместить данные во временный tarfile
                    calculateName = ".calculate"
                    calculatePath = path.join(userDir,calculateName)
                    tf = tempfile.TemporaryFile()
                    with tarfile.open(fileobj=tf,mode='w:') as tarf:
                        tarf.add(calculatePath,calculateName)
                    tf.flush()
                    tf.seek(0)
                    # удалить эти данные
                    shutil.rmtree(calculatePath)

                # создать шифрованные данные
                e = process('/usr/bin/ecryptfs-setup-private','-u',userName,
                            '-b','-l',userPwd,stderr=STDOUT)
                if e.failed():
                    raise DesktopError(e.read())
                # если были данные от бутстрапа, то распаковать их
                if tf:
                    with tarfile.open(fileobj=tf,mode='r:') as tarf:
                        tarf.extractall(userDir)
            except Exception as e:
                if tf:
                    tf.seek(0)
                    bakArchName = path.join(userDir,".calculate.tar.bz2")
                    with open(bakArchName,'w') as f:
                        f.write(tf.read())
                raise DesktopError(str(e)+
                    _("Failed to create encrypt user profile"))
            finally:
                if tf:
                    tf.close()
Exemple #2
0
    def createCryptDir(self,userName,uid,gid,userDir,recreateOnError=False):
        """
        Создать шифрование домашней директории, или подключить существующую

        userName,uid,gid,userDir: параметры пользовательской учётной записи
        recreateOnError: пересоздать профиль при ошбиках (используется при доменной
        ученой записи, так пользователь при этом ничего не теряет - профиль на сервере)
        """
        userPwd = getKey(userName)
        error = ""
        # проверить наличие пароля в ключах ядра
        if not userPwd or userPwd == "XXXXXXXX":
            raise DesktopError(_("User password not found"))
        ecryptfsPath = path.join('/home/.ecryptfs',userName)
        # если шифрование уже используется
        if path.exists(ecryptfsPath):
            for d in (".ecryptfs",".Private"):
                source,target = path.join(ecryptfsPath,d),path.join(userDir,d)
                if not path.lexists(target):
                    os.symlink(source,target)
            # попытаться подключить шифрованные данные
            try:
                if not mountEcryptfs(userName,userPwd,userDir):
                    error = _("Failed to mount ecrypted data")
            except CommonError as e:
                error = _("Failed to mount ecrypted data")+": \"%s\""%str(e)
        # если при подключении произошли ошибки
        if error:
            # заархивировать текущий профиль и удалить его
            if recreateOnError:
                self.printSUCCESS(_("Recreating encrypted data"))
                if self.getMountUserPaths(userDir):
                    raise DesktopError(_("Failed to use directory encryption"))
                for source in (userDir,ecryptfsPath):
                    if path.exists(source):
                        if listDirectory(source):
                            target = source+".bak"
                            newtarget = target
                            if path.exists(target):
                                removeDir(target)
                            os.rename(source,newtarget)
                        else:
                            os.rmdir(source)
                self.createUserDir(userName,uid,gid,userDir)
            # ошибка создания шифрования
            else:
                raise DesktopError(error)
        # если нет шифрованных данных
        if not path.exists(ecryptfsPath):
            tf = None
            try:
                # если профиль содержит только данные от бутстрапа core
                if isBootstrapDataOnly(userDir):
                    if childMounts(userDir):
                        raise DesktopError(
                            _("Failed to create the encrypted user profile")+":"+
                            _("User home directory contains mount points"))
                    # поместить данные во временный tarfile
                    calculateName = ".calculate"
                    calculatePath = path.join(userDir,calculateName)
                    tf = tempfile.TemporaryFile()
                    with tarfile.open(fileobj=tf,mode='w:') as tarf:
                        tarf.add(calculatePath,calculateName)
                    tf.flush()
                    tf.seek(0)
                    # удалить эти данные
                    shutil.rmtree(calculatePath)

                # создать шифрованные данные
                e = process('/usr/bin/ecryptfs-setup-private','-u',userName,
                            '-b','-l',userPwd,stderr=STDOUT)
                if e.failed():
                    raise DesktopError(e.read())
                # если были данные от бутстрапа, то распаковать их
                if tf:
                    with tarfile.open(fileobj=tf,mode='r:') as tarf:
                        tarf.extractall(userDir)
            except Exception as e:
                # в случае ошибки сохраняем архив (с данными bootstrap)
                # из памяти в файловую систему
                if tf:
                    tf.seek(0)
                    bakArchName = path.join(userDir,".calculate.tar.bz2")
                    with open(bakArchName,'w') as f:
                        f.write(tf.read())
                raise DesktopError(str(e)+
                    _("Failed to create the encrypted user profile"))
            finally:
                if tf:
                    tf.close()
        return True