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

Настройка профиля пользователя при каждом входе в сеанс, в зависимости
от main.elog.
Добавлен скрипт отключения домашней директории при выходе из сеанса.
Библиотека _cl_keys перемещена из calculate-client.
В _cl_keys исправлен алгоритм удаления ключа.
master3.3 3.1.6
parent 703bdcac06
commit a3a2891799

@ -22,20 +22,14 @@ then
# skip desktop configure if user not domain and it already has home dir
# with not /etc/skel contents
userHome=`getent passwd $USER | awk -F: '{ print( $6 ); }'`
if [[ "${DOMAIN_USER}" == "on" ]] ||
! [[ -d "${userHome}" ]] ||
[[ -z "`ls ${userHome}`" ]] ||
diff -uq <(ls -A1 /etc/skel | wc) <(ls -A1 ${userHome} | sort) &>/dev/null
ERRORLOG=`/usr/sbin/cl-desktop --gui-progress $USER 2>&1`
# raise xmessage error if cl-desktop failed
if [ "$?" -gt "0" ];
then
ERRORLOG=`/usr/sbin/cl-desktop --gui-progress $USER 2>&1`
# raise xmessage error if cl-desktop failed
if [ "$?" -gt "0" ];
then
# write error message to logfile
echo "$ERRORLOG" >> $FILE_LOG
# display error by xmessage
exit 1
fi
# write error message to logfile
echo "$ERRORLOG" >> $FILE_LOG
# display error by xmessage
exit 1
fi
fi
exit 0

@ -0,0 +1,4 @@
#!/bin/bash
umount -l /home/$USER
exit 0

@ -22,13 +22,16 @@ import pwd
import time
import traceback
from calculate.desktop._cl_keys import getKey, clearKey
from datavars import DataVarsDesktop, DataVars, __version__,__app__
from calculate.lib.cl_template import Template, ProgressTemplate,TemplatesError
from calculate.lib.cl_template import (Template, ProgressTemplate,
TemplatesError,templateFunction,iniParser)
from calculate.lib.utils.files import runOsCommand, isMount,process, \
getRunCommands
getRunCommands,STDOUT
from calculate.lib.utils.common import getpathenv,appendProgramToEnvFile, \
removeProgramToEnvFile
removeProgramToEnvFile,mountEcryptfs, \
CommonError
from calculate.core.server.func import safetyWrapper
from calculate.lib.cl_lang import setLocalTranslate,getLazyLocalTranslate
@ -54,7 +57,31 @@ class Desktop:
self.clTempl = None
self.clVars = None
def createUserDir(self, uid, gid, userDir, mode=0700):
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 ecrypt"))
except CommonError as e:
raise DesktopError(_("Failed to mount ecrypt")+": \"%s\""%str(e))
else:
e = process('/usr/bin/ecryptfs-setup-private','-u',userName,'-b','-l',userPwd,stderr=STDOUT)
if e.failed():
raise DesktopError(e.read()+
_("Failed to create encrypt user profile"))
def createUserDir(self, userName, uid, gid, userDir, mode=0700):
"""
Create user directory with need uid and gid
"""
@ -135,7 +162,7 @@ class Desktop:
break
return ret
@safetyWrapper(native_errors=(TemplatesError,DesktopError),
@safetyWrapper(native_errors=(TemplatesError,DesktopError,CommonError),
man_int=__("Configuration manually interrupted"),
post_action=umountUserRes)
def createHome(self, datavars=None):
@ -171,17 +198,28 @@ class Desktop:
self.homeDir = path.join(rootPath, self.homeDir[1:])
if not path.exists(self.homeDir):
self.startTask(_("Creating the home directory for %s")%self.homeDir)
self.createUserDir(uid,gid,self.homeDir)
self.createUserDir(userName,uid,gid,self.homeDir)
self.endTask()
if self.clVars.Get('ur_home_crypt_set') == 'on':
self.createCryptDir(userName,uid,gid,self.homeDir)
domainUser = self.clVars.Get('ur_domain_set') == 'on'
lastTimestamp = templateFunction.getLastElog()
iniEnv = path.join(self.homeDir,'.calculate/ini.env')
userIni = iniParser(iniEnv)
userTimestamp = userIni.getVar('main','elog').encode('utf-8')
if (domainUser or not path.exists(iniEnv) or
userTimestamp != lastTimestamp):
# action - "user profile configuration"
self.clVars.Set("cl_action", "desktop", True)
# apply user profiles
self.startTask(_("Setting up the user profile"),progress=True)
dirsAndFiles = self.applyTemplatesFromUser()
self.endTask()
# action - "user profile configuration"
self.clVars.Set("cl_action", "desktop", True)
# apply user profiles
self.startTask(_("Setting up the user profile"),progress=True)
dirsAndFiles = self.applyTemplatesFromUser()
self.endTask()
if not dirsAndFiles:
raise DesktopError(_("Failed to apply user profile templates"))
self.printSUCCESS(_("User account %s is configured")%userName + " ...")
if not dirsAndFiles:
raise DesktopError(_("Failed to apply user profile templates"))
self.printSUCCESS(_("User account %s is configured")%userName + " ...")
return True
def getMountUserPaths(self, homeDir=False):

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

@ -0,0 +1,66 @@
// 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)
{
return "";
};
// Возвращаем значение ключа
ret = keyctl_read(ret, buffer, sizeof(buffer));
if (ret < 0)
{
return "";
};
return buffer;
};
int clearKey(char *login)
{
int ret;
key_serial_t dest;
dest = KEY_SPEC_USER_SESSION_KEYRING;
// ищем номер пользовательского ключа
ret = request_key("user", login, NULL, 0);
if (ret < 0)
{
return 1;
};
// удаляем ключ
ret = keyctl_unlink(ret, dest);
if (ret < 0)
{
return 1;
};
return 0;
};

@ -0,0 +1,7 @@
%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-desktop"
__version__ = "3.1.4"
__version__ = "3.1.6"
import os
import stat
@ -41,7 +41,8 @@ data_files += [('/usr/share/calculate/xdm', ['data/cmd_login',
'data/login.d/20desktop',
'data/login.d/99final'])] + \
[('/usr/share/calculate/xdm/logout.d',
['data/logout.d/00init'])]
['data/logout.d/00init',
'data/logout.d/98umount'])]
def __scanDir(scanDir, prefix, replace_dirname, dirData, flagDir=False):
"""Scan directory"""
@ -105,7 +106,7 @@ class cl_install_data(install_data):
setup(
name = 'calculate-desktop',
version = "3.0.0_alpha1",
version = "3.1.6",
description = "Create and configure user profile",
author = "Calculate Ltd.",
author_email = "support@calculate.ru",
@ -114,4 +115,8 @@ setup(
package_dir = {'calculate.desktop': "desktop"},
packages = ['calculate.desktop','calculate.desktop.variables'],
data_files = data_files,
ext_modules = [Extension('calculate.desktop._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