Шифрование пользовательских профилей

Исправлена блокировка директории пользовательского профиля во время
настройки.
Библиотека _cl_keys перемещена в calculate-desktop.
master3.3 3.1.6
parent 7ca3e0b2ac
commit b686daac47

@ -27,6 +27,7 @@ import types
import getpass
from os import path
from datavars import DataVarsClient, DataVars, __version__,__app__
from calculate.lib.cl_template import (Template, iniParser,TemplatesError,
@ -35,10 +36,11 @@ from calculate.lib.cl_print import color_print
from calculate.lib.cl_ldap import ldapUser
from calculate.lib.utils.ip import Pinger, isOpenPort, IPError
from calculate.lib.utils.files import (runOsCommand, getModeFile, removeDir,
isMount, readFile, pathJoin, tarLinks)
from calculate.lib.utils.common import (getpathenv, appendProgramToEnvFile,
removeProgramToEnvFile)
from _cl_keys import getKey, clearKey
isMount, readFile, pathJoin, tarLinks,process,STDOUT,
readLinesFile,listDirectory)
from calculate.lib.utils.common import (getpathenv, appendProgramToEnvFile,
CommonError,removeProgramToEnvFile,mountEcryptfs)
from calculate.desktop._cl_keys import getKey, clearKey
from calculate.lib.convertenv import convertEnv
from calculate.lib.encrypt import encrypt
from cl_client_cache import userCache
@ -46,6 +48,7 @@ from shutil import copy2
from socket import gethostbyname
import tarfile
from collections import OrderedDict
from itertools import *
from calculate.core.server.func import safetyWrapper
@ -1126,6 +1129,51 @@ class Client(commandServer, encrypt):
return umountResult
return True
def createCryptDir(self,userName,uid,gid,userDir):
"""
Создать шифрование домашней директории, или подключить существующую
"""
userPwd = getKey(userName)
if not userPwd or userPwd == "XXXXXXXX":
raise ClientError(_("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)
error = ""
try:
if mountEcryptfs(userName,userPwd,userDir):
return True
except CommonError as e:
error = str(e)
if error:
if self.getMountUserPaths(userDir):
raise ClientError(_("Failed to use crypt directory"))
for source in (userDir,ecryptfsPath):
if path.exists(source):
if listDirectory(source):
target = source+".bak"
newtarget = target
for i in count(2):
if not path.exists(newtarget):
break
newtarget = "%s.%d"%(target,i)
os.rename(source,newtarget)
else:
os.rmdir(source)
if not os.path.exists(userDir):
os.makedirs(userDir)
os.chown(userDir,uid,gid)
os.chmod(userDir,0700)
e = process('/usr/bin/ecryptfs-setup-private',
'-u',userName,'-b','-l',userPwd,stderr=STDOUT)
if e.failed():
raise ClientError(e.read()+
_("Failed to create encrypt user profile"))
def initEnv(self):
"""
Init object variables
@ -1179,16 +1227,18 @@ class Client(commandServer, encrypt):
# check for domain workstation and [remote] was mounted
if not self.isDomain():
raise ClientError(_("The computer is not in the domain"))
# user config filename
configFileName = os.path.join(self.homeDir, self.configFileDesktop)
# user time object from config file
currentTimeObj = self.getDateObjClientConf(configFileName)
currentStatusSync = self.getSyncStatus(self.homeDir)
# create home directory if it is not exists
if not os.path.exists(self.homeDir):
os.makedirs(self.homeDir)
os.chown(self.homeDir,self.uid,self.gid)
os.chmod(self.homeDir,0700)
if self.clVars.Get('ur_home_crypt_set') == 'on':
self.createCryptDir(self.userName,self.uid,self.gid,self.homeDir)
# user config filename
configFileName = os.path.join(self.homeDir, self.configFileDesktop)
# user time object from config file
currentTimeObj = self.getDateObjClientConf(configFileName)
currentStatusSync = self.getSyncStatus(self.homeDir)
# get local date and statusSync
# write into config status "process"
self.setVarToConfig("main", {"status_sync":"process"}, configFileName)
@ -1348,6 +1398,7 @@ class Client(commandServer, encrypt):
# remote link to Moved in home directory
if os.path.islink(movedLink) and not os.path.exists(movedPath):
os.unlink(movedLink)
os.chdir(pathProg)
return True
if not os.path.exists(movedPath):
os.mkdir(movedPath)
@ -1366,11 +1417,13 @@ class Client(commandServer, encrypt):
textLine = self.execProg(execStr)
if textLine is False:
self.printERROR(_("Failed to execute") + " " + str(execStr))
os.chdir(pathProg)
return False
execStr = "rm -rf '%s'" %fd
textLine = self.execProg(execStr)
if textLine is False:
self.printERROR(_("Failed to execute") + " " + str(execStr))
os.chdir(pathProg)
return False
os.chdir(pathProg)
return True
@ -1684,11 +1737,12 @@ class Client(commandServer, encrypt):
dirStart, dirEnd = os.path.split(homeDir)
mountTemplateDir = os.path.join(dirStart, ".%s" %dirEnd)
mountRemoteTemplateDir = os.path.join(dirStart, ".%s.remote" %dirEnd)
return filter(lambda x: x.startswith(homeDir) or\
x.startswith(mountTemplateDir) or\
x.startswith(mountRemoteTemplateDir),
map(lambda x: x.split(" ")[1],\
open("/proc/mounts").readlines()))
return filter(lambda x:x != homeDir,
filter(lambda x: (x.startswith(homeDir) or
x.startswith(mountTemplateDir) or
x.startswith(mountRemoteTemplateDir)),
map(lambda x: x.split(" ")[1],
readLinesFile('/proc/mounts'))))
def execProg(self, cmdStrProg, inStr=False, envProg={}):
"""
@ -2216,6 +2270,13 @@ class Client(commandServer, encrypt):
if not self.setServerCommand(["passwd_samba"], varsConfig, fileConfig,
self.uid,self.gid):
raise ClientError(_("Failed to change password"))
if self.clVars.Get('ur_home_crypt_set') == 'on':
passphraseFile = path.join('/home/.ecryptfs',
self.clVars.Get('ur_login'),".ecryptfs/wrapped-passphrase")
p = process('/usr/bin/ecryptfs-rewrap-passphrase',passphraseFile, "-",stderr=STDOUT)
p.write("%s\n%s"%(curPassword,password))
if p.failed():
raise ClientError(p.read()+_("Failed to rewrap passphrase"))
self.printSUCCESS(_("%s's password changed")%
self.clVars.Get('ur_login'))
self.printSUCCESS(_("The password will be changed when you log "

@ -15,7 +15,7 @@
# limitations under the License.
__app__ = 'calculate-client'
__version__ = '3.1.4'
__version__ = '3.1.6'
import os
import sys

@ -1,59 +0,0 @@
// Copyright 2007-2010 Calculate Ltd. http://www.calculate-linux.org
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <stdio.h>
// для пароля
#include <sys/types.h>
// для strcpy strlen
#include <string.h>
// для работы с ключами
#include <keyutils.h>
char* getKey(char *login)
{
char buffer[255];
memset(buffer,0,sizeof(buffer));
int ret;
// ищем номер пользовательского ключа
ret = request_key("user", login, NULL, 0);
if (ret < 0)
{
// printf ("id_key not found\n");
return "";
};
// Возвращаем значение ключа
ret = keyctl_read(ret, buffer, sizeof(buffer));
if (ret < 0)
{
// printf("error keyctl_read\n");
return "";
};
return buffer;
};
int clearKey(char *login)
{
char *buffer;
buffer = "XXXXXXXX";
key_serial_t dest;
dest = KEY_SPEC_USER_SESSION_KEYRING;
if (add_key("user", login, buffer, strlen(buffer), dest)!=-1)
return 0;
else
return 1;
};

@ -1,7 +0,0 @@
%module cl_keys
%inline %{
/* Put header files here or function declarations like below */
extern char* getKey(char*);
extern int clearKey(char*);
%}
%include cl_keys.c

@ -18,7 +18,7 @@
# limitations under the License.
__app__ = "calculate-client"
__version__ = "3.1.5"
__version__ = "3.1.6"
import os
import stat
@ -112,8 +112,4 @@ setup(
package_dir = {'calculate.client': "client"},
packages = ['calculate.client','calculate.client.variables'],
data_files = data_files,
ext_modules = [Extension('calculate.client._cl_keys',
library_dirs = ['/usr/lib'],
libraries = ['keyutils'],
sources = ['./lib/cl_keys.i', './lib/cl_keys.c'])],
cmdclass={'install_data': cl_install_data})

Loading…
Cancel
Save