Fix for defect 242393 (section 4.2.1 of security audit report) - This
fix makes the .miCASA* files to be owned by the user instead of root.
This commit is contained in:
parent
f3105f7d76
commit
810c767431
@ -70,6 +70,7 @@ CSFILES=$(srcdir)/AssemblyInfo.cs \
|
||||
$(srcdir)/common/UnixUserIdentifier.cs \
|
||||
$(srcdir)/common/Constants.cs \
|
||||
$(srcdir)/common/CSSSLogger.cs \
|
||||
$(srcdir)/common/CSSSUtils.cs \
|
||||
$(srcdir)/common/CSSSException.cs \
|
||||
$(srcdir)/communication/IPCChannel.cs \
|
||||
$(srcdir)/communication/CommunicationFactory.cs \
|
||||
|
9
CASA/micasad/cache/MPFileWatcher.cs
vendored
9
CASA/micasad/cache/MPFileWatcher.cs
vendored
@ -8,7 +8,7 @@ namespace sscs.cache
|
||||
/// <summary>
|
||||
/// Summary description for MPFileWatcher.
|
||||
/// </summary>
|
||||
public class MPFileWatcher
|
||||
class MPFileWatcher
|
||||
{
|
||||
FileSystemWatcher fwatcher;
|
||||
private string m_dir = null;
|
||||
@ -17,9 +17,11 @@ namespace sscs.cache
|
||||
private byte[] m_baMPIV = new byte[32];
|
||||
private byte[] m_baMPSalt = null;
|
||||
private bool m_bIgnoreFileDeletes = false;
|
||||
private SecretStore m_store = null;
|
||||
|
||||
public MPFileWatcher(string MPFilePath, string MPFileName)
|
||||
public MPFileWatcher(SecretStore store, string MPFilePath, string MPFileName)
|
||||
{
|
||||
m_store = store;
|
||||
m_dir = MPFilePath;
|
||||
m_filename = MPFileName;
|
||||
|
||||
@ -120,6 +122,7 @@ namespace sscs.cache
|
||||
fs.Close();
|
||||
|
||||
File.SetAttributes(m_dir + m_filename, FileAttributes.Hidden);
|
||||
CSSSUtils.SetSocketUserAsOwner(m_dir + m_filename, m_store.user.UserIdentifier);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@ -134,6 +137,7 @@ namespace sscs.cache
|
||||
fs.Close();
|
||||
|
||||
File.SetAttributes(m_dir + m_filename + ".IV", FileAttributes.Hidden);
|
||||
CSSSUtils.SetSocketUserAsOwner(m_dir + m_filename + ".IV", m_store.user.UserIdentifier);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@ -151,6 +155,7 @@ namespace sscs.cache
|
||||
fs.Close();
|
||||
|
||||
File.SetAttributes(m_dir + m_filename + ".salt", FileAttributes.Hidden);
|
||||
CSSSUtils.SetSocketUserAsOwner(m_dir + m_filename + ".salt", m_store.user.UserIdentifier);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
157
CASA/micasad/cache/SecretStore.cs
vendored
157
CASA/micasad/cache/SecretStore.cs
vendored
@ -116,7 +116,7 @@ namespace sscs.cache
|
||||
String sPersistentDir = GetPersistenceDirectory();
|
||||
if (sPersistentDir != null && sPersistentDir.Length > 0)
|
||||
{
|
||||
mpWatcher = new MPFileWatcher(GetPersistenceDirectory(), ConstStrings.MICASA_PASSCODE_BY_MASTERPASSWD_FILE);
|
||||
mpWatcher = new MPFileWatcher(this, GetPersistenceDirectory(), ConstStrings.MICASA_PASSCODE_BY_MASTERPASSWD_FILE);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -176,15 +176,15 @@ namespace sscs.cache
|
||||
{
|
||||
try
|
||||
{
|
||||
byte[] baPasscode = CASACrypto.GetMasterPasscodeUsingDesktopPasswd(sDesktopPassword, GetPasscodeByDesktopFilePath(), false);
|
||||
if (CASACrypto.ValidatePasscode(baPasscode, GetValidationFilePath()))
|
||||
byte[] baPasscode = CASACrypto.GetMasterPasscodeUsingDesktopPasswd(sDesktopPassword, GetPasscodeByDesktopFilePath(), false, user.UserIdentifier);
|
||||
if (CASACrypto.ValidatePasscode(baPasscode, GetValidationFilePath(), user.UserIdentifier))
|
||||
{
|
||||
ReEncryptPasscodeUsingRandomSalt(baPasscode, sDesktopPassword, GetPasscodeByDesktopFilePath());
|
||||
return true;
|
||||
}
|
||||
// try old salt
|
||||
baPasscode = CASACrypto.GetMasterPasscodeUsingDesktopPasswd(sDesktopPassword, GetPasscodeByDesktopFilePath(), true);
|
||||
if (CASACrypto.ValidatePasscode(baPasscode, GetValidationFilePath()))
|
||||
baPasscode = CASACrypto.GetMasterPasscodeUsingDesktopPasswd(sDesktopPassword, GetPasscodeByDesktopFilePath(), true, user.UserIdentifier);
|
||||
if (CASACrypto.ValidatePasscode(baPasscode, GetValidationFilePath(), user.UserIdentifier))
|
||||
{
|
||||
ReEncryptPasscodeUsingRandomSalt(baPasscode, sDesktopPassword, GetPasscodeByDesktopFilePath());
|
||||
return true;
|
||||
@ -230,7 +230,8 @@ namespace sscs.cache
|
||||
*/
|
||||
baPasscode = CASACrypto.GenerateServerMasterPasscode(
|
||||
GetServerPasscodeBySystemKeyFilePath(),
|
||||
GetServerValidationFilePath());
|
||||
GetServerValidationFilePath(),
|
||||
user.UserIdentifier);
|
||||
|
||||
if (null == baPasscode)
|
||||
{
|
||||
@ -246,8 +247,8 @@ namespace sscs.cache
|
||||
}
|
||||
}
|
||||
|
||||
baPasscode = CASACrypto.GetServerMasterPasscodeUsingSystemKey(GetServerPasscodeBySystemKeyFilePath());
|
||||
if (CASACrypto.ValidatePasscode(baPasscode, GetServerValidationFilePath()))
|
||||
baPasscode = CASACrypto.GetServerMasterPasscodeUsingSystemKey(GetServerPasscodeBySystemKeyFilePath(), user.UserIdentifier);
|
||||
if (CASACrypto.ValidatePasscode(baPasscode, GetServerValidationFilePath(), user.UserIdentifier))
|
||||
{
|
||||
slss = new LocalStorage(this, baPasscode, true);
|
||||
bIsServerStorePersistent = true;
|
||||
@ -335,8 +336,8 @@ namespace sscs.cache
|
||||
}
|
||||
|
||||
}
|
||||
baPasscode = CASACrypto.GetMasterPasscodeUsingDesktopPasswd(desktopPasswd, GetPasscodeByDesktopFilePath(), false);
|
||||
if (CASACrypto.ValidatePasscode(baPasscode, GetValidationFilePath()))
|
||||
baPasscode = CASACrypto.GetMasterPasscodeUsingDesktopPasswd(desktopPasswd, GetPasscodeByDesktopFilePath(), false, user.UserIdentifier);
|
||||
if (CASACrypto.ValidatePasscode(baPasscode, GetValidationFilePath(), user.UserIdentifier))
|
||||
{
|
||||
lss = new LocalStorage(this, baPasscode);
|
||||
bIsStorePersistent = true;
|
||||
@ -346,12 +347,12 @@ namespace sscs.cache
|
||||
else
|
||||
{
|
||||
// try old encryption method
|
||||
baPasscode = CASACrypto.GetMasterPasscodeUsingDesktopPasswd(desktopPasswd, GetPasscodeByDesktopFilePath(), true);
|
||||
if (CASACrypto.ValidatePasscode(baPasscode, GetValidationFilePath()))
|
||||
baPasscode = CASACrypto.GetMasterPasscodeUsingDesktopPasswd(desktopPasswd, GetPasscodeByDesktopFilePath(), true, user.UserIdentifier);
|
||||
if (CASACrypto.ValidatePasscode(baPasscode, GetValidationFilePath(), user.UserIdentifier))
|
||||
{
|
||||
// rewrite file using new encryption
|
||||
ReEncryptPasscodeUsingRandomSalt(baPasscode, desktopPasswd, GetPasscodeByDesktopFilePath());
|
||||
//CASACrypto.EncryptAndStoreMasterPasscodeUsingString(baPasscode, desktopPasswd, GetPasscodeByDesktopFilePath());
|
||||
//CASACrypto.EncryptAndStoreMasterPasscodeUsingString(baPasscode, desktopPasswd, GetPasscodeByDesktopFilePath(), user.UserIdentifier);
|
||||
lss = new LocalStorage(this, baPasscode);
|
||||
bIsStorePersistent = true;
|
||||
return true;
|
||||
@ -381,7 +382,7 @@ namespace sscs.cache
|
||||
myRijndael.GenerateKey();
|
||||
key = myRijndael.Key;
|
||||
|
||||
CASACrypto.StoreKeySetUsingMasterPasscode(key, IV, baPasscode, fileName);
|
||||
CASACrypto.StoreKeySetUsingMasterPasscode(key, IV, baPasscode, fileName, user.UserIdentifier);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
@ -410,10 +411,10 @@ namespace sscs.cache
|
||||
*/
|
||||
if (desktopPasswd != null)
|
||||
{
|
||||
baPasscode = CASACrypto.GetMasterPasscodeUsingDesktopPasswd(desktopPasswd, GetPasscodeByDesktopFilePath(), false);
|
||||
if (CASACrypto.ValidatePasscode(baPasscode, GetValidationFilePath()))
|
||||
baPasscode = CASACrypto.GetMasterPasscodeUsingDesktopPasswd(desktopPasswd, GetPasscodeByDesktopFilePath(), false, user.UserIdentifier);
|
||||
if (CASACrypto.ValidatePasscode(baPasscode, GetValidationFilePath(), user.UserIdentifier))
|
||||
{
|
||||
CASACrypto.EncryptAndStoreMasterPasscodeUsingString(baPasscode, mPasswd, GetPasscodeByMasterPasswdFilePath());
|
||||
CASACrypto.EncryptAndStoreMasterPasscodeUsingString(baPasscode, mPasswd, GetPasscodeByMasterPasswdFilePath(), user.UserIdentifier);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
@ -422,20 +423,23 @@ namespace sscs.cache
|
||||
baPasscode = CASACrypto.GetMasterPasscodeUsingDesktopPasswd(
|
||||
desktopPasswd,
|
||||
GetPasscodeByDesktopFilePath(),
|
||||
true);
|
||||
true,
|
||||
user.UserIdentifier);
|
||||
|
||||
if (CASACrypto.ValidatePasscode(baPasscode, GetValidationFilePath()))
|
||||
if (CASACrypto.ValidatePasscode(baPasscode, GetValidationFilePath(), user.UserIdentifier))
|
||||
{
|
||||
// rewrite file using new method
|
||||
CASACrypto.EncryptAndStoreMasterPasscodeUsingString(
|
||||
baPasscode,
|
||||
desktopPasswd,
|
||||
GetPasscodeByDesktopFilePath());
|
||||
GetPasscodeByDesktopFilePath(),
|
||||
user.UserIdentifier);
|
||||
|
||||
CASACrypto.EncryptAndStoreMasterPasscodeUsingString(
|
||||
baPasscode,
|
||||
mPasswd,
|
||||
GetPasscodeByMasterPasswdFilePath());
|
||||
GetPasscodeByMasterPasswdFilePath(),
|
||||
user.UserIdentifier);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
@ -447,8 +451,8 @@ namespace sscs.cache
|
||||
baPasscode = CASACrypto.GenerateMasterPasscodeUsingString(mPasswd, GetPasscodeByMasterPasswdFilePath(), GetValidationFilePath(), user.UserIdentifier);
|
||||
if (baPasscode != null)
|
||||
{
|
||||
CASACrypto.EncryptAndStoreMasterPasscodeUsingString(baPasscode, mPasswd, GetPasscodeByMasterPasswdFilePath());
|
||||
CASACrypto.EncryptAndStoreMasterPasscodeUsingString(baPasscode, desktopPasswd, GetPasscodeByDesktopFilePath());
|
||||
CASACrypto.EncryptAndStoreMasterPasscodeUsingString(baPasscode, mPasswd, GetPasscodeByMasterPasswdFilePath(), user.UserIdentifier);
|
||||
CASACrypto.EncryptAndStoreMasterPasscodeUsingString(baPasscode, desktopPasswd, GetPasscodeByDesktopFilePath(), user.UserIdentifier);
|
||||
if (File.Exists(GetPersistenceFilePath()))
|
||||
{
|
||||
File.Delete(GetPersistenceFilePath());
|
||||
@ -493,7 +497,7 @@ namespace sscs.cache
|
||||
GenerateAndStoreEncryptionKey(baPasscode, GetKeyFilePath());
|
||||
}
|
||||
|
||||
CASACrypto.EncryptAndStoreMasterPasscodeUsingString(baPasscode, mPasswd, GetPasscodeByMasterPasswdFilePath());
|
||||
CASACrypto.EncryptAndStoreMasterPasscodeUsingString(baPasscode, mPasswd, GetPasscodeByMasterPasswdFilePath(), user.UserIdentifier);
|
||||
if (bIsStorePersistent == false)
|
||||
{
|
||||
lss = new LocalStorage(this, baPasscode);
|
||||
@ -514,8 +518,8 @@ namespace sscs.cache
|
||||
//If validation succeeds,start persistence.
|
||||
if (desktopPasswd == null)
|
||||
{
|
||||
baPasscode = CASACrypto.DecryptMasterPasscodeUsingString(mPasswd, GetPasscodeByMasterPasswdFilePath(), false);
|
||||
if (CASACrypto.ValidatePasscode(baPasscode, GetValidationFilePath()))
|
||||
baPasscode = CASACrypto.DecryptMasterPasscodeUsingString(mPasswd, GetPasscodeByMasterPasswdFilePath(), false, user.UserIdentifier);
|
||||
if (CASACrypto.ValidatePasscode(baPasscode, GetValidationFilePath(), user.UserIdentifier))
|
||||
{
|
||||
if (bIsStorePersistent == false)
|
||||
{
|
||||
@ -528,11 +532,11 @@ namespace sscs.cache
|
||||
else
|
||||
{
|
||||
// try validation, if it fails, try decryption using the old method
|
||||
baPasscode = CASACrypto.DecryptMasterPasscodeUsingString(mPasswd, GetPasscodeByMasterPasswdFilePath(), true);
|
||||
if (CASACrypto.ValidatePasscode(baPasscode, GetValidationFilePath()))
|
||||
baPasscode = CASACrypto.DecryptMasterPasscodeUsingString(mPasswd, GetPasscodeByMasterPasswdFilePath(), true, user.UserIdentifier);
|
||||
if (CASACrypto.ValidatePasscode(baPasscode, GetValidationFilePath(), user.UserIdentifier))
|
||||
{
|
||||
// rewrite file
|
||||
CASACrypto.EncryptAndStoreMasterPasscodeUsingString(baPasscode, mPasswd, GetPasscodeByMasterPasswdFilePath());
|
||||
CASACrypto.EncryptAndStoreMasterPasscodeUsingString(baPasscode, mPasswd, GetPasscodeByMasterPasswdFilePath(), user.UserIdentifier);
|
||||
if (bIsStorePersistent == false)
|
||||
{
|
||||
lss = new LocalStorage(this, baPasscode);
|
||||
@ -549,8 +553,8 @@ namespace sscs.cache
|
||||
else
|
||||
{ //There are 2 cases - either desktop passwd has changed
|
||||
//or it hasnt.
|
||||
baPasscode = CASACrypto.GetMasterPasscodeUsingMasterPasswd(mPasswd, GetPasscodeByMasterPasswdFilePath(), false);
|
||||
if (CASACrypto.ValidatePasscode(baPasscode, GetValidationFilePath()))
|
||||
baPasscode = CASACrypto.GetMasterPasscodeUsingMasterPasswd(mPasswd, GetPasscodeByMasterPasswdFilePath(), false, user.UserIdentifier);
|
||||
if (CASACrypto.ValidatePasscode(baPasscode, GetValidationFilePath(), user.UserIdentifier))
|
||||
{
|
||||
RewriteDesktopPasswdFile(baPasscode, desktopPasswd);
|
||||
if (bIsStorePersistent == false)
|
||||
@ -563,8 +567,8 @@ namespace sscs.cache
|
||||
}
|
||||
else
|
||||
{
|
||||
baPasscode = CASACrypto.GetMasterPasscodeUsingMasterPasswd(mPasswd, GetPasscodeByMasterPasswdFilePath(), true);
|
||||
if (CASACrypto.ValidatePasscode(baPasscode, GetValidationFilePath()))
|
||||
baPasscode = CASACrypto.GetMasterPasscodeUsingMasterPasswd(mPasswd, GetPasscodeByMasterPasswdFilePath(), true, user.UserIdentifier);
|
||||
if (CASACrypto.ValidatePasscode(baPasscode, GetValidationFilePath(), user.UserIdentifier))
|
||||
{
|
||||
RewriteDesktopPasswdFile(baPasscode, desktopPasswd);
|
||||
if (bIsStorePersistent == false)
|
||||
@ -592,7 +596,7 @@ namespace sscs.cache
|
||||
{
|
||||
try
|
||||
{
|
||||
CASACrypto.EncryptAndStoreMasterPasscodeUsingString(baPasscode, desktopPasswd, GetPasscodeByDesktopFilePath());
|
||||
CASACrypto.EncryptAndStoreMasterPasscodeUsingString(baPasscode, desktopPasswd, GetPasscodeByDesktopFilePath(), user.UserIdentifier);
|
||||
CSSSLogger.DbgLog("Re-encryted passcode with desktop passwd");
|
||||
}
|
||||
catch (Exception e)
|
||||
@ -606,8 +610,8 @@ namespace sscs.cache
|
||||
{
|
||||
try
|
||||
{
|
||||
byte[] baPasscode = CASACrypto.GetMasterPasscodeUsingDesktopPasswd(oldDesktopPasswd, GetPasscodeByDesktopFilePath(), false);
|
||||
if (CASACrypto.ValidatePasscode(baPasscode, GetValidationFilePath()))
|
||||
byte[] baPasscode = CASACrypto.GetMasterPasscodeUsingDesktopPasswd(oldDesktopPasswd, GetPasscodeByDesktopFilePath(), false, user.UserIdentifier);
|
||||
if (CASACrypto.ValidatePasscode(baPasscode, GetValidationFilePath(), user.UserIdentifier))
|
||||
{
|
||||
ReEncryptPasscodeUsingRandomSalt(baPasscode, oldDesktopPasswd, GetPasscodeByDesktopFilePath());
|
||||
return baPasscode;
|
||||
@ -615,11 +619,11 @@ namespace sscs.cache
|
||||
else
|
||||
{
|
||||
// try old method
|
||||
baPasscode = CASACrypto.GetMasterPasscodeUsingDesktopPasswd(oldDesktopPasswd, GetPasscodeByDesktopFilePath(), true);
|
||||
if (CASACrypto.ValidatePasscode(baPasscode, GetValidationFilePath()))
|
||||
baPasscode = CASACrypto.GetMasterPasscodeUsingDesktopPasswd(oldDesktopPasswd, GetPasscodeByDesktopFilePath(), true, user.UserIdentifier);
|
||||
if (CASACrypto.ValidatePasscode(baPasscode, GetValidationFilePath(), user.UserIdentifier))
|
||||
{
|
||||
// rewrite file now
|
||||
CASACrypto.EncryptAndStoreMasterPasscodeUsingString(baPasscode, oldDesktopPasswd, GetPasscodeByDesktopFilePath());
|
||||
CASACrypto.EncryptAndStoreMasterPasscodeUsingString(baPasscode, oldDesktopPasswd, GetPasscodeByDesktopFilePath(), user.UserIdentifier);
|
||||
return baPasscode;
|
||||
}
|
||||
|
||||
@ -652,9 +656,9 @@ namespace sscs.cache
|
||||
//Create a new key and initialization vector.
|
||||
myRijndael.GenerateKey();
|
||||
key = myRijndael.Key;
|
||||
CASACrypto.StoreKeySetUsingMasterPasscode(key,IV,sMasterPasscode,GetKeyFilePath());
|
||||
CASACrypto.StoreKeySetUsingMasterPasscode(key,IV,sMasterPasscode,GetKeyFilePath(), user.UserIdentifier);
|
||||
//Store the master passcode encrypted with the desktopPasswd
|
||||
CASACrypto.EncryptAndStoreMasterPasscodeUsingString(sMasterPasscode, desktopPasswd, GetPasswdFilePath());
|
||||
CASACrypto.EncryptAndStoreMasterPasscodeUsingString(sMasterPasscode, desktopPasswd, GetPasswdFilePath(), user.UserIdentifier);
|
||||
lss = new LocalStorage(this,sMasterPasscode);
|
||||
bIsStorePersistent = true;
|
||||
bRet = true;
|
||||
@ -857,11 +861,11 @@ namespace sscs.cache
|
||||
internal bool ChangeMasterPassword(string sCurrentPWD, string sNewPWD)
|
||||
{
|
||||
string sMasterFilePath = GetPasscodeByMasterPasswdFilePath();
|
||||
byte[] baPasscode = CASACrypto.GetMasterPasscodeUsingMasterPasswd(sCurrentPWD, sMasterFilePath, false);
|
||||
byte[] baPasscode = CASACrypto.GetMasterPasscodeUsingMasterPasswd(sCurrentPWD, sMasterFilePath, false, user.UserIdentifier);
|
||||
if (baPasscode != null)
|
||||
{
|
||||
PauseFileWatcher();
|
||||
CASACrypto.EncryptAndStoreMasterPasscodeUsingString(baPasscode, sNewPWD, sMasterFilePath);
|
||||
CASACrypto.EncryptAndStoreMasterPasscodeUsingString(baPasscode, sNewPWD, sMasterFilePath, user.UserIdentifier);
|
||||
ResumeFileWatcher();
|
||||
return true;
|
||||
}
|
||||
@ -907,6 +911,11 @@ namespace sscs.cache
|
||||
return user.GetUserName();
|
||||
}
|
||||
|
||||
internal UserIdentifier GetUserIdentifier()
|
||||
{
|
||||
return user.UserIdentifier;
|
||||
}
|
||||
|
||||
internal string GetPersistenceDirectory()
|
||||
{
|
||||
if (m_persistenceDirectory != null)
|
||||
@ -922,7 +931,6 @@ namespace sscs.cache
|
||||
string sUserHomeDir = GetUserHomeDirectory();
|
||||
if (sUserHomeDir != null)
|
||||
{
|
||||
|
||||
// the user might have set a different one
|
||||
// load the policy file and check.
|
||||
UIPol uiPolicy = (UIPol)ICASAPol.GetPolicy(CASAPolType.UI_POL, sUserHomeDir, GetUserName());
|
||||
@ -932,8 +940,17 @@ namespace sscs.cache
|
||||
if ((sDir != null) && (sDir.Length > 0))
|
||||
{
|
||||
m_persistenceDirectory = sDir;
|
||||
if (IsDirectoryOwnedByUser(sDir))
|
||||
{
|
||||
ChangeFileOwnershipForMiCasaFiles(sDir);
|
||||
return m_persistenceDirectory;
|
||||
}
|
||||
else
|
||||
{
|
||||
CSSSLogger.log(true, "CASA Warning: " + GetUserName() + " has persistent directory set to " + sDir);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -944,6 +961,7 @@ namespace sscs.cache
|
||||
}
|
||||
|
||||
m_persistenceDirectory = MigrateMiCasaFiles();
|
||||
ChangeFileOwnershipForMiCasaFiles(null);
|
||||
return m_persistenceDirectory;
|
||||
}
|
||||
|
||||
@ -991,6 +1009,48 @@ namespace sscs.cache
|
||||
return (sNewPath);
|
||||
}
|
||||
|
||||
internal void ChangeFileOwnershipForMiCasaFiles(string sDir)
|
||||
{
|
||||
#if LINUX
|
||||
string sSeperator = "/";
|
||||
string sNewPath;
|
||||
if (sDir != null)
|
||||
{
|
||||
sNewPath = sDir;
|
||||
}
|
||||
else
|
||||
{
|
||||
sNewPath = POLICY_DIRECTORY + "/" + user.GetUserName();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (CSSSUtils.IsFileOwnedByRoot(sNewPath + sSeperator + ".miCASA"))
|
||||
{
|
||||
if(CSSSUtils.CompareSocketAndFileUserIds(sNewPath + sSeperator + ".miCASA", user.UserIdentifier))
|
||||
return;
|
||||
else
|
||||
{
|
||||
String[] miCASAFiles = Directory.GetFiles(sNewPath, ".miCASA*");
|
||||
|
||||
if ((miCASAFiles != null) && (miCASAFiles.Length > 0))
|
||||
{
|
||||
for (int i = 0; i < miCASAFiles.Length; i++)
|
||||
{
|
||||
string sFileName = miCASAFiles[i].Substring(miCASAFiles[i].LastIndexOf(sSeperator));
|
||||
CSSSUtils.SetSocketUserAsOwner(sNewPath + sFileName, user.UserIdentifier);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
CSSSLogger.DbgLog(e.ToString());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
internal bool SetPeristenceDirectory(string sNewDirectory)
|
||||
{
|
||||
if (Directory.Exists(sNewDirectory))
|
||||
@ -999,11 +1059,12 @@ namespace sscs.cache
|
||||
if (mpWatcher != null)
|
||||
{
|
||||
mpWatcher.pauseWatcher();
|
||||
mpWatcher = new MPFileWatcher(sNewDirectory, ConstStrings.MICASA_PASSCODE_BY_MASTERPASSWD_FILE);
|
||||
mpWatcher = new MPFileWatcher(this, sNewDirectory, ConstStrings.MICASA_PASSCODE_BY_MASTERPASSWD_FILE);
|
||||
mpWatcher.resumeWatcher();
|
||||
}
|
||||
|
||||
m_persistenceDirectory = sNewDirectory;
|
||||
ChangeFileOwnershipForMiCasaFiles(m_persistenceDirectory);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1097,7 +1158,7 @@ namespace sscs.cache
|
||||
// encrypt if an encryptionstring was passed
|
||||
if ((sEncryptionString != null) && (sEncryptionString.Length > 0))
|
||||
{
|
||||
byte[] baKey = sscs.crypto.CASACrypto.Generate16ByteKeyFromString(sEncryptionString, null, false, false);
|
||||
byte[] baKey = sscs.crypto.CASACrypto.Generate16ByteKeyFromString(sEncryptionString, null, false, false, user.UserIdentifier);
|
||||
|
||||
// now encypt it.
|
||||
baSecrets = sscs.crypto.CASACrypto.EncryptData(baSecrets, baKey, ref baIV);
|
||||
@ -1115,7 +1176,7 @@ namespace sscs.cache
|
||||
if (sEncryptionString != null)
|
||||
{
|
||||
// decrypt the buffer using the string passed in.
|
||||
byte[] baKey = sscs.crypto.CASACrypto.Generate16ByteKeyFromString(sEncryptionString, null, false, false);
|
||||
byte[] baKey = sscs.crypto.CASACrypto.Generate16ByteKeyFromString(sEncryptionString, null, false, false, user.UserIdentifier);
|
||||
byte[] baBuffer = sscs.crypto.CASACrypto.DecryptData(encryptedXmlSecrets, baKey, baIV);
|
||||
MergeXMLSecrets(baBuffer);
|
||||
}
|
||||
@ -1133,7 +1194,7 @@ namespace sscs.cache
|
||||
{
|
||||
if (!File.Exists(sFilepath + ".salt"))
|
||||
{
|
||||
CASACrypto.EncryptAndStoreMasterPasscodeUsingString(baPasscode, sPassword, sFilepath);
|
||||
CASACrypto.EncryptAndStoreMasterPasscodeUsingString(baPasscode, sPassword, sFilepath, user.UserIdentifier);
|
||||
}
|
||||
}
|
||||
|
||||
|
162
CASA/micasad/common/CSSSUtils.cs
Normal file
162
CASA/micasad/common/CSSSUtils.cs
Normal file
@ -0,0 +1,162 @@
|
||||
/***********************************************************************
|
||||
*
|
||||
* Copyright (C) 2005-2006 Novell, Inc. All Rights Reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* This library 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
|
||||
* Library Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, Novell, Inc.
|
||||
*
|
||||
* To contact Novell about this file by physical or electronic mail,
|
||||
* you may find current contact information at www.novell.com.
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
#if LINUX
|
||||
using Mono.Unix;
|
||||
using Mono.Unix.Native;
|
||||
#endif
|
||||
using sscs.common;
|
||||
using sscs.constants;
|
||||
|
||||
namespace sscs.common
|
||||
{
|
||||
class CSSSUtils
|
||||
{
|
||||
public static bool IsFileOwnedByRoot(string filePath)
|
||||
{
|
||||
#if LINUX
|
||||
try
|
||||
{
|
||||
int retVal = -1;
|
||||
int fd = -1;
|
||||
Stat fStatus;
|
||||
|
||||
fd = Syscall.open(filePath, OpenFlags.O_NOFOLLOW);
|
||||
|
||||
retVal = Syscall.fstat(fd, out fStatus);
|
||||
if ( retVal < 0 )
|
||||
{
|
||||
CSSSLogger.DbgLog("fstat() failed...");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(fStatus.st_uid != 0)
|
||||
{
|
||||
CSSSLogger.DbgLog("File not owned by root: {0}");
|
||||
return false;
|
||||
}
|
||||
|
||||
retVal = Syscall.close(fd);
|
||||
if ( retVal < 0 )
|
||||
{
|
||||
CSSSLogger.DbgLog("close() failed...");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
CSSSLogger.ExpLog(e.ToString());
|
||||
CSSSLogger.DbgLog("Failed while checking whether the file is owned by root or not");
|
||||
}
|
||||
return false;
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
public static bool SetSocketUserAsOwner(string filePath, UserIdentifier userID)
|
||||
{
|
||||
#if LINUX
|
||||
try
|
||||
{
|
||||
int retVal = -1;
|
||||
int fd = -1;
|
||||
|
||||
fd = Syscall.open(filePath, OpenFlags.O_NOFOLLOW);
|
||||
|
||||
UnixUserInfo uui = new UnixUserInfo(userID.GetUID());
|
||||
|
||||
retVal = Syscall.fchown(fd, (uint) uui.UserId, (uint) uui.GroupId);
|
||||
if ( retVal < 0 )
|
||||
{
|
||||
CSSSLogger.DbgLog("fchown() failed...");
|
||||
return false;
|
||||
}
|
||||
|
||||
retVal = Syscall.close(fd);
|
||||
if ( retVal < 0 )
|
||||
{
|
||||
CSSSLogger.DbgLog("close() failed...");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
CSSSLogger.ExpLog(e.ToString());
|
||||
CSSSLogger.DbgLog("Unable to set the owner of the file to the socket user");
|
||||
}
|
||||
return false;
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
public static bool CompareSocketAndFileUserIds(string filePath, UserIdentifier userID)
|
||||
{
|
||||
#if LINUX
|
||||
try
|
||||
{
|
||||
int retVal = -1;
|
||||
int fd = -1;
|
||||
Stat fStatus;
|
||||
|
||||
fd = Syscall.open(filePath, OpenFlags.O_NOFOLLOW);
|
||||
|
||||
retVal = Syscall.fstat(fd, out fStatus);
|
||||
if ( retVal < 0 )
|
||||
{
|
||||
CSSSLogger.DbgLog("fstat() failed...");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(fStatus.st_uid != userID.GetUID())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
retVal = Syscall.close(fd);
|
||||
if ( retVal < 0 )
|
||||
{
|
||||
CSSSLogger.DbgLog("close() failed...");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
CSSSLogger.ExpLog(e.ToString());
|
||||
CSSSLogger.DbgLog("Failed during the comparision of the user ids on the file and socket");
|
||||
}
|
||||
return false;
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
@ -26,6 +26,7 @@ using System.Text;
|
||||
using System.Security.Cryptography;
|
||||
#if LINUX
|
||||
using Mono.Unix;
|
||||
using Mono.Unix.Native;
|
||||
#endif
|
||||
using sscs.common;
|
||||
using sscs.constants;
|
||||
@ -40,12 +41,12 @@ namespace sscs.crypto
|
||||
private const int HASH_SIZE = 32;
|
||||
private const uint MAX_FILE_SIZE = 16 * 1024 * 1024; //16 MB
|
||||
|
||||
internal static byte[] Generate16ByteKeyFromString(string sTheString, string sFilepath, bool bUseOldMethod, bool bGenerateRandomSalt)
|
||||
internal static byte[] Generate16ByteKeyFromString(string sTheString, string sFilepath, bool bUseOldMethod, bool bGenerateRandomSalt, UserIdentifier userID)
|
||||
{
|
||||
byte[] baKey = new byte[16]; //return value
|
||||
try
|
||||
{
|
||||
Rfc2898DeriveBytes pkcs5 = new Rfc2898DeriveBytes(sTheString, SALTSIZE, ITERATION_COUNT, bUseOldMethod, sFilepath, bGenerateRandomSalt);
|
||||
Rfc2898DeriveBytes pkcs5 = new Rfc2898DeriveBytes(sTheString, SALTSIZE, ITERATION_COUNT, bUseOldMethod, sFilepath, bGenerateRandomSalt, userID);
|
||||
baKey = pkcs5.GetBytes(16);
|
||||
}
|
||||
catch(Exception e)
|
||||
@ -58,7 +59,7 @@ namespace sscs.crypto
|
||||
}
|
||||
|
||||
internal static bool StoreKeySetUsingMasterPasscode(byte[] key,
|
||||
byte[] IV, byte[] baMasterPasscode, string fileName)
|
||||
byte[] IV, byte[] baMasterPasscode, string fileName, UserIdentifier userID)
|
||||
{
|
||||
bool bRet = false;
|
||||
FileStream fsEncrypt = null;
|
||||
@ -69,7 +70,7 @@ namespace sscs.crypto
|
||||
//Get an encryptor.
|
||||
RijndaelManaged myRijndael = new RijndaelManaged();
|
||||
ICryptoTransform encryptor;
|
||||
encryptor = myRijndael.CreateEncryptor(baMasterPasscode, GenerateAndSaveIV(fileName, myRijndael));
|
||||
encryptor = myRijndael.CreateEncryptor(baMasterPasscode, GenerateAndSaveIV(fileName, myRijndael, userID));
|
||||
|
||||
//Encrypt the data to a file
|
||||
fsEncrypt = new FileStream(fileName, FileMode.Create);
|
||||
@ -88,6 +89,15 @@ namespace sscs.crypto
|
||||
//Write all data to the crypto stream and flush it.
|
||||
csEncrypt.Write(key, 0, key.Length);
|
||||
csEncrypt.FlushFinalBlock();
|
||||
|
||||
csEncrypt.Close();
|
||||
fsEncrypt.Close();
|
||||
|
||||
if (!CSSSUtils.SetSocketUserAsOwner(fileName, userID))
|
||||
{
|
||||
CSSSLogger.DbgLog("Unable to set the owner of the key file to the socket user");
|
||||
}
|
||||
|
||||
bRet = true;
|
||||
}
|
||||
catch(Exception e)
|
||||
@ -100,11 +110,12 @@ namespace sscs.crypto
|
||||
csEncrypt.Close();
|
||||
if( fsEncrypt != null )
|
||||
fsEncrypt.Close();
|
||||
|
||||
return bRet;
|
||||
}
|
||||
|
||||
internal static byte[] GetKeySetFromFile(byte[] baMasterPasscode,
|
||||
string fileName )
|
||||
string fileName, UserIdentifier userID )
|
||||
{
|
||||
byte[] baSavedKey = null;
|
||||
FileStream fsDecrypt = null;
|
||||
@ -114,7 +125,7 @@ namespace sscs.crypto
|
||||
{
|
||||
#if LINUX
|
||||
UnixFileInfo fsTest = new UnixFileInfo (fileName);
|
||||
if((fsTest == null) || !(fsTest.Exists) || fsTest.IsSymbolicLink)
|
||||
if((fsTest == null) || !(fsTest.Exists) || fsTest.IsSymbolicLink || !CSSSUtils.CompareSocketAndFileUserIds(fileName, userID))
|
||||
#else
|
||||
if(!File.Exists(fileName))
|
||||
#endif
|
||||
@ -127,7 +138,7 @@ namespace sscs.crypto
|
||||
*/
|
||||
|
||||
RijndaelManaged myRijndael = new RijndaelManaged();
|
||||
ICryptoTransform decryptor = myRijndael.CreateDecryptor(baMasterPasscode, RetrieveIV(fileName, baMasterPasscode));
|
||||
ICryptoTransform decryptor = myRijndael.CreateDecryptor(baMasterPasscode, RetrieveIV(fileName, baMasterPasscode, userID));
|
||||
//Now decrypt
|
||||
fsDecrypt = new FileStream(fileName, FileMode.Open);
|
||||
|
||||
@ -233,7 +244,7 @@ namespace sscs.crypto
|
||||
|
||||
|
||||
internal static void EncryptDataAndWriteToFile(byte[] xmlData,
|
||||
byte[] key, string fileName)
|
||||
byte[] key, string fileName, UserIdentifier userID)
|
||||
{
|
||||
FileStream fsEncrypt = null;
|
||||
CryptoStream csEncrypt = null;
|
||||
@ -241,7 +252,7 @@ namespace sscs.crypto
|
||||
{
|
||||
//Get an encryptor.
|
||||
RijndaelManaged myRijndael = new RijndaelManaged();
|
||||
byte[] baIV = GenerateAndSaveIV(fileName, myRijndael);
|
||||
byte[] baIV = GenerateAndSaveIV(fileName, myRijndael, userID);
|
||||
|
||||
|
||||
ICryptoTransform encryptor = myRijndael.CreateEncryptor(key, baIV);
|
||||
@ -266,15 +277,21 @@ namespace sscs.crypto
|
||||
fsClear.Write(dup, 0, dup.Length);
|
||||
fsClear.Flush();
|
||||
fsClear.Close();
|
||||
CSSSUtils.SetSocketUserAsOwner(fileName + ".xml", userID);
|
||||
#endif
|
||||
|
||||
|
||||
csEncrypt = new CryptoStream(fsEncrypt, encryptor, CryptoStreamMode.Write);
|
||||
|
||||
//Write all data to the crypto stream and flush it.
|
||||
csEncrypt.Write(xmlData, 0, xmlData.Length);
|
||||
csEncrypt.FlushFinalBlock();
|
||||
|
||||
csEncrypt.Close();
|
||||
fsEncrypt.Close();
|
||||
|
||||
if (!CSSSUtils.SetSocketUserAsOwner(fileName, userID)) {
|
||||
CSSSLogger.DbgLog("Unable to set the owner of the encrypted file to the socket user");
|
||||
}
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
@ -287,7 +304,7 @@ namespace sscs.crypto
|
||||
fsEncrypt.Close();
|
||||
}
|
||||
|
||||
internal static void ComputeHashAndWriteToFile(byte[] baPasscode, string fileName)
|
||||
internal static void ComputeHashAndWriteToFile(byte[] baPasscode, string fileName, UserIdentifier userID)
|
||||
{
|
||||
|
||||
FileStream fsHash = null;
|
||||
@ -303,6 +320,13 @@ namespace sscs.crypto
|
||||
|
||||
fsHash.Write(hash, 0, hash.Length);
|
||||
fsHash.Flush();
|
||||
|
||||
fsHash.Close();
|
||||
|
||||
if (!CSSSUtils.SetSocketUserAsOwner(fileName, userID))
|
||||
{
|
||||
CSSSLogger.DbgLog("Unable to set the owner of the hash file to the socket user");
|
||||
}
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
@ -315,7 +339,7 @@ namespace sscs.crypto
|
||||
}
|
||||
|
||||
internal static byte[] ReadFileAndDecryptData(byte[] key,
|
||||
string fileName)
|
||||
string fileName, UserIdentifier userID)
|
||||
{
|
||||
FileStream fsDecrypt = null;
|
||||
CryptoStream csDecrypt = null;
|
||||
@ -328,12 +352,12 @@ namespace sscs.crypto
|
||||
//Get a decryptor that uses the same key and IV as the encryptor.
|
||||
RijndaelManaged myRijndael = new RijndaelManaged();
|
||||
|
||||
byte[] baIV = RetrieveIV(fileName, IV);
|
||||
byte[] baIV = RetrieveIV(fileName, IV, userID);
|
||||
|
||||
ICryptoTransform decryptor = myRijndael.CreateDecryptor(key, baIV);
|
||||
#if LINUX
|
||||
UnixFileInfo fsTest = new UnixFileInfo (fileName);
|
||||
if((fsTest == null) || !(fsTest.Exists) || fsTest.IsSymbolicLink)
|
||||
if((fsTest == null) || !(fsTest.Exists) || fsTest.IsSymbolicLink || !CSSSUtils.CompareSocketAndFileUserIds(fileName, userID))
|
||||
#else
|
||||
if(!File.Exists(fileName))
|
||||
#endif
|
||||
@ -508,9 +532,9 @@ namespace sscs.crypto
|
||||
return (File.Exists(fileName));
|
||||
}
|
||||
|
||||
internal static byte[] GetMasterPasscode(string desktopPasswd, string fileName)
|
||||
internal static byte[] GetMasterPasscode(string desktopPasswd, string fileName, UserIdentifier userID)
|
||||
{
|
||||
byte[] mp = DecryptMasterPasscodeUsingString(desktopPasswd, fileName, false);
|
||||
byte[] mp = DecryptMasterPasscodeUsingString(desktopPasswd, fileName, false, userID);
|
||||
return mp;
|
||||
}
|
||||
|
||||
@ -523,7 +547,8 @@ namespace sscs.crypto
|
||||
internal static void EncryptAndStoreMasterPasscodeUsingString(
|
||||
byte[] baMasterPasscode,
|
||||
string passwd,
|
||||
string fileName)
|
||||
string fileName,
|
||||
UserIdentifier userID)
|
||||
{
|
||||
FileStream fsEncrypt = null;
|
||||
CryptoStream csEncrypt = null;
|
||||
@ -532,13 +557,13 @@ namespace sscs.crypto
|
||||
if(File.Exists(fileName))
|
||||
File.Delete(fileName);
|
||||
|
||||
byte[] baKey = Generate16ByteKeyFromString(passwd, fileName, false, true);
|
||||
byte[] baKey = Generate16ByteKeyFromString(passwd, fileName, false, true, userID);
|
||||
|
||||
//Get an encryptor.
|
||||
RijndaelManaged myRijndael = new RijndaelManaged();
|
||||
ICryptoTransform encryptor;
|
||||
|
||||
encryptor = myRijndael.CreateEncryptor(baKey, GenerateAndSaveIV(fileName, myRijndael));
|
||||
encryptor = myRijndael.CreateEncryptor(baKey, GenerateAndSaveIV(fileName, myRijndael, userID));
|
||||
|
||||
//Encrypt the data to a file
|
||||
fsEncrypt = new FileStream(fileName,FileMode.Create);
|
||||
@ -555,6 +580,10 @@ namespace sscs.crypto
|
||||
// make hidden
|
||||
File.SetAttributes(fileName, FileAttributes.Hidden);
|
||||
|
||||
if (!CSSSUtils.SetSocketUserAsOwner(fileName, userID))
|
||||
{
|
||||
CSSSLogger.DbgLog("Unable to set the owner of the MPC file to the socket user");
|
||||
}
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
@ -568,11 +597,10 @@ namespace sscs.crypto
|
||||
{
|
||||
fsEncrypt.Close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static byte[] DecryptMasterPasscodeUsingString(string passwd,
|
||||
string fileName, bool bTryOldMethod)
|
||||
string fileName, bool bTryOldMethod, UserIdentifier userID)
|
||||
{
|
||||
FileStream fsDecrypt = null;
|
||||
CryptoStream csDecrypt = null;
|
||||
@ -580,17 +608,17 @@ namespace sscs.crypto
|
||||
|
||||
try
|
||||
{
|
||||
byte[] baKey = Generate16ByteKeyFromString(passwd, fileName, bTryOldMethod, false);
|
||||
byte[] baKey = Generate16ByteKeyFromString(passwd, fileName, bTryOldMethod, false, userID);
|
||||
|
||||
/* Get a decryptor that uses the same key and
|
||||
* IV as the encryptor.
|
||||
*/
|
||||
RijndaelManaged myRijndael = new RijndaelManaged();
|
||||
ICryptoTransform decryptor = myRijndael.CreateDecryptor(baKey, RetrieveIV(fileName, baKey));
|
||||
ICryptoTransform decryptor = myRijndael.CreateDecryptor(baKey, RetrieveIV(fileName, baKey, userID));
|
||||
//Now decrypt
|
||||
#if LINUX
|
||||
UnixFileInfo fsTest = new UnixFileInfo (fileName);
|
||||
if((fsTest == null) || !(fsTest.Exists) || fsTest.IsSymbolicLink)
|
||||
if((fsTest == null) || !(fsTest.Exists) || fsTest.IsSymbolicLink || !CSSSUtils.CompareSocketAndFileUserIds(fileName, userID))
|
||||
#else
|
||||
if (!File.Exists(fileName))
|
||||
#endif
|
||||
@ -599,8 +627,7 @@ namespace sscs.crypto
|
||||
}
|
||||
|
||||
fsDecrypt = new FileStream(fileName, FileMode.Open);
|
||||
csDecrypt = new CryptoStream(fsDecrypt, decryptor,
|
||||
CryptoStreamMode.Read);
|
||||
csDecrypt = new CryptoStream(fsDecrypt, decryptor, CryptoStreamMode.Read);
|
||||
baSavedMasterPasscode = new byte[16];
|
||||
|
||||
//Read the data out of the crypto stream.
|
||||
@ -633,7 +660,8 @@ namespace sscs.crypto
|
||||
internal static byte[] GetMasterPasscodeUsingMasterPasswd(
|
||||
string mPasswd,
|
||||
string fileName,
|
||||
bool bUseOldMethod)
|
||||
bool bUseOldMethod,
|
||||
UserIdentifier userID)
|
||||
{
|
||||
byte[] baMasterPasscode;
|
||||
try
|
||||
@ -643,7 +671,7 @@ namespace sscs.crypto
|
||||
/* Decrypt the passcode from the file using master passwd.
|
||||
* and return the decrypted passcode.
|
||||
*/
|
||||
baMasterPasscode = DecryptMasterPasscodeUsingString(mPasswd, fileName, bUseOldMethod);
|
||||
baMasterPasscode = DecryptMasterPasscodeUsingString(mPasswd, fileName, bUseOldMethod, userID);
|
||||
return baMasterPasscode;
|
||||
}
|
||||
else
|
||||
@ -660,7 +688,8 @@ namespace sscs.crypto
|
||||
internal static byte[] GetMasterPasscodeUsingDesktopPasswd(
|
||||
string desktopPasswd,
|
||||
string fileName,
|
||||
bool bUseOldMethod)
|
||||
bool bUseOldMethod,
|
||||
UserIdentifier userID)
|
||||
{
|
||||
byte[] passcode;
|
||||
try
|
||||
@ -671,7 +700,7 @@ namespace sscs.crypto
|
||||
* and return the decrypted passcode.
|
||||
*/
|
||||
passcode = DecryptMasterPasscodeUsingString(desktopPasswd,
|
||||
fileName, bUseOldMethod);
|
||||
fileName, bUseOldMethod, userID);
|
||||
return passcode;
|
||||
|
||||
}
|
||||
@ -689,12 +718,13 @@ namespace sscs.crypto
|
||||
internal static byte[] GetServerMasterPasscodeUsingMasterPasswd(
|
||||
string mPasswd,
|
||||
string fileName,
|
||||
bool bUseOldMethod)
|
||||
bool bUseOldMethod,
|
||||
UserIdentifier userID)
|
||||
{
|
||||
return GetMasterPasscodeUsingMasterPasswd ( mPasswd, fileName, bUseOldMethod);
|
||||
return GetMasterPasscodeUsingMasterPasswd ( mPasswd, fileName, bUseOldMethod, userID);
|
||||
}
|
||||
|
||||
internal static byte[] GetServerMasterPasscodeUsingSystemKey(string fileName)
|
||||
internal static byte[] GetServerMasterPasscodeUsingSystemKey(string fileName, UserIdentifier userID)
|
||||
{
|
||||
byte[] baSavedMasterPasscode = null;
|
||||
|
||||
@ -702,7 +732,7 @@ namespace sscs.crypto
|
||||
{
|
||||
#if LINUX
|
||||
UnixFileInfo fsTest = new UnixFileInfo (fileName);
|
||||
if((fsTest == null) || !(fsTest.Exists) || fsTest.IsSymbolicLink)
|
||||
if((fsTest == null) || !(fsTest.Exists) || fsTest.IsSymbolicLink || !CSSSUtils.CompareSocketAndFileUserIds(fileName, userID))
|
||||
#else
|
||||
if (!File.Exists(fileName))
|
||||
#endif
|
||||
@ -716,7 +746,7 @@ namespace sscs.crypto
|
||||
fs.Close();
|
||||
|
||||
baSavedMasterPasscode = new byte[16];
|
||||
baSavedMasterPasscode = ProtectedData.Unprotect( encryptedMasterPasscode, RetrieveIV(fileName, new byte[16]), DataProtectionScope.CurrentUser );
|
||||
baSavedMasterPasscode = ProtectedData.Unprotect( encryptedMasterPasscode, RetrieveIV(fileName, new byte[16], userID), DataProtectionScope.CurrentUser );
|
||||
}
|
||||
catch (CryptographicException e)
|
||||
{
|
||||
@ -732,7 +762,7 @@ namespace sscs.crypto
|
||||
string desktopPasswd,
|
||||
string fileName,
|
||||
string validationFile,
|
||||
UserIdentifier userId
|
||||
UserIdentifier userID
|
||||
)
|
||||
{
|
||||
try
|
||||
@ -747,9 +777,9 @@ namespace sscs.crypto
|
||||
|
||||
EncryptAndStoreMasterPasscodeUsingString(baPasscode,
|
||||
desktopPasswd,
|
||||
fileName);
|
||||
|
||||
ComputeHashAndWriteToFile(baPasscode, validationFile + "Hash"); //Hash of MPC is written to ".miCASAValidateHash" file
|
||||
fileName,
|
||||
userID);
|
||||
ComputeHashAndWriteToFile(baPasscode, validationFile + "Hash", userID); //Hash of MPC is written to ".miCASAValidateHash" file
|
||||
return baPasscode;
|
||||
}
|
||||
catch(Exception e)
|
||||
@ -762,7 +792,8 @@ namespace sscs.crypto
|
||||
|
||||
internal static byte[] GenerateServerMasterPasscode(
|
||||
string fileName,
|
||||
string validationFile
|
||||
string validationFile,
|
||||
UserIdentifier userID
|
||||
)
|
||||
{
|
||||
byte[] baPasscode = null;
|
||||
@ -775,14 +806,18 @@ namespace sscs.crypto
|
||||
myRijndael.GenerateKey();
|
||||
baPasscode = myRijndael.Key;
|
||||
|
||||
byte [] encryptedMasterPasscode = ProtectedData.Protect( baPasscode, GenerateAndSaveIV(fileName, null), DataProtectionScope.CurrentUser );
|
||||
byte [] encryptedMasterPasscode = ProtectedData.Protect( baPasscode, GenerateAndSaveIV(fileName, null, userID), DataProtectionScope.CurrentUser );
|
||||
FileStream fs = new FileStream(fileName, FileMode.Create);
|
||||
File.SetAttributes(fileName, FileAttributes.Hidden);
|
||||
fs.Write(encryptedMasterPasscode, 0, encryptedMasterPasscode.Length);
|
||||
fs.Flush();
|
||||
fs.Close();
|
||||
|
||||
ComputeHashAndWriteToFile(baPasscode, validationFile + "Hash"); //Hash of MPC is written to ".miCASASrvValidateHash" file
|
||||
if (!CSSSUtils.SetSocketUserAsOwner(fileName, userID))
|
||||
{
|
||||
CSSSLogger.DbgLog("Unable to set the owner of the server MPC file to the socket user");
|
||||
}
|
||||
ComputeHashAndWriteToFile(baPasscode, validationFile + "Hash", userID); //Hash of MPC is written to ".miCASASrvValidateHash" file
|
||||
|
||||
}
|
||||
catch(Exception e)
|
||||
@ -794,14 +829,14 @@ namespace sscs.crypto
|
||||
return baPasscode;
|
||||
}
|
||||
|
||||
public static bool CompareHashes(byte[] baPasscode, string fileName)
|
||||
public static bool CompareHashes(byte[] baPasscode, string fileName, UserIdentifier userID)
|
||||
{
|
||||
FileStream fsHash = null;
|
||||
try
|
||||
{
|
||||
#if LINUX
|
||||
UnixFileInfo fsTest = new UnixFileInfo (fileName);
|
||||
if((fsTest == null) || !(fsTest.Exists) || fsTest.IsSymbolicLink)
|
||||
if((fsTest == null) || !(fsTest.Exists) || fsTest.IsSymbolicLink || !CSSSUtils.CompareSocketAndFileUserIds(fileName, userID))
|
||||
#else
|
||||
if (!File.Exists(fileName))
|
||||
#endif
|
||||
@ -840,7 +875,7 @@ namespace sscs.crypto
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool ValidatePasscode(byte[] baPasscode, string fileName)
|
||||
public static bool ValidatePasscode(byte[] baPasscode, string fileName, UserIdentifier userID)
|
||||
{
|
||||
/* Here we decrpyt a well known string, throw exception
|
||||
* if not successful
|
||||
@ -854,7 +889,7 @@ namespace sscs.crypto
|
||||
|
||||
try
|
||||
{
|
||||
if(CompareHashes(baPasscode, fileName + "Hash"))
|
||||
if(CompareHashes(baPasscode, fileName + "Hash", userID))
|
||||
{
|
||||
CSSSLogger.DbgLog("Using the hash of MPC for validating the MPC");
|
||||
return true;
|
||||
@ -862,7 +897,7 @@ namespace sscs.crypto
|
||||
else
|
||||
{
|
||||
CSSSLogger.DbgLog("Using the validation string encrypted with MPC for validating the MPC");
|
||||
byte[] baString = ReadFileAndDecryptData(baPasscode, fileName);
|
||||
byte[] baString = ReadFileAndDecryptData(baPasscode, fileName, userID);
|
||||
string sString = Encoding.Default.GetString(baString);
|
||||
char[] trimChars = {'\0'};
|
||||
sString = sString.TrimEnd(trimChars);
|
||||
@ -887,7 +922,7 @@ namespace sscs.crypto
|
||||
}
|
||||
|
||||
|
||||
private static byte[] GenerateAndSaveIV(string sFileName, RijndaelManaged theRiManaged)
|
||||
private static byte[] GenerateAndSaveIV(string sFileName, RijndaelManaged theRiManaged, UserIdentifier userID)
|
||||
{
|
||||
byte[] baIV = null;
|
||||
if ( theRiManaged != null )
|
||||
@ -911,6 +946,11 @@ namespace sscs.crypto
|
||||
fs.Close();
|
||||
|
||||
File.SetAttributes(sFileName + ".IV", FileAttributes.Hidden);
|
||||
|
||||
if (!CSSSUtils.SetSocketUserAsOwner(sFileName + ".IV", userID))
|
||||
{
|
||||
CSSSLogger.DbgLog("Unable to set the owner of the IV file to the socket user");
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@ -920,13 +960,23 @@ namespace sscs.crypto
|
||||
return baIV;
|
||||
}
|
||||
|
||||
private static byte[] RetrieveIV(string sFileName, byte[] baOrigValue)
|
||||
private static byte[] RetrieveIV(string sFileName, byte[] baOrigValue, UserIdentifier userID)
|
||||
{
|
||||
|
||||
byte[] IV = new byte[16];
|
||||
// check for file existence
|
||||
try
|
||||
{
|
||||
#if LINUX
|
||||
UnixFileInfo fsTest = new UnixFileInfo (sFileName + ".IV");
|
||||
if((fsTest == null) || !(fsTest.Exists) || fsTest.IsSymbolicLink || !CSSSUtils.CompareSocketAndFileUserIds(sFileName + ".IV", userID))
|
||||
#else
|
||||
if (!File.Exists(sFileName + ".IV"))
|
||||
#endif
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
FileStream fs = new FileStream(sFileName + ".IV", FileMode.Open);
|
||||
fs.Read(IV, 0, 16);
|
||||
fs.Close();
|
||||
|
@ -165,72 +165,38 @@ namespace sscs.lss
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool IsOwnedByRoot(string fileName)
|
||||
{
|
||||
#if LINUX
|
||||
sockFileInfo = new Mono.Unix.UnixFileInfo(fileName);
|
||||
sockFileOwner = sockFileInfo.OwnerUser;
|
||||
if(0==sockFileOwner.UserId)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
private string GetDecryptedServerSecretsXml()
|
||||
{
|
||||
try
|
||||
{
|
||||
string fileName = userStore.GetServerSecretsPersistenceFilePath();
|
||||
string tempFile = fileName;
|
||||
int count = 0;
|
||||
if (!File.Exists(fileName))
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
// check for tmp file
|
||||
if (File.Exists(tempFile + ".tmp"))
|
||||
{
|
||||
if (IsOwnedByRoot(tempFile + ".tmp"))
|
||||
{
|
||||
File.Move(tempFile + ".tmp", fileName);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
count++;
|
||||
tempFile = fileName + count.ToString();
|
||||
}
|
||||
File.Delete(tempFile + ".tmp");
|
||||
}
|
||||
else
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
// delete tmp file if there
|
||||
if (File.Exists(tempFile + ".tmp"))
|
||||
{
|
||||
if (IsOwnedByRoot(tempFile + ".tmp"))
|
||||
File.Delete(tempFile + ".tmp");
|
||||
}
|
||||
}
|
||||
|
||||
byte[] baPasscode = null;
|
||||
if (null != m_baGeneratedKey)
|
||||
baPasscode = m_baGeneratedKey;
|
||||
else
|
||||
baPasscode = CASACrypto.GetServerMasterPasscodeUsingSystemKey(userStore.GetServerPasscodeBySystemKeyFilePath());
|
||||
baPasscode = CASACrypto.GetServerMasterPasscodeUsingSystemKey(userStore.GetServerPasscodeBySystemKeyFilePath(), userStore.GetUserIdentifier());
|
||||
|
||||
if (null == baPasscode)
|
||||
return null;
|
||||
|
||||
byte[] key = CASACrypto.GetKeySetFromFile(baPasscode, userStore.GetServerKeyFilePath());
|
||||
byte[] key = CASACrypto.GetKeySetFromFile(baPasscode, userStore.GetServerKeyFilePath(), userStore.GetUserIdentifier());
|
||||
if (null == key)
|
||||
return null;
|
||||
|
||||
byte[] decryptedBuffer = CASACrypto.ReadFileAndDecryptData(key, fileName);
|
||||
byte[] decryptedBuffer = CASACrypto.ReadFileAndDecryptData(key, fileName, userStore.GetUserIdentifier());
|
||||
|
||||
if (null == decryptedBuffer)
|
||||
return null;
|
||||
@ -253,52 +219,32 @@ namespace sscs.lss
|
||||
{
|
||||
string fileName = userStore.GetPersistenceFilePath();
|
||||
string tempFile = fileName;
|
||||
int count = 0;
|
||||
if (!File.Exists(fileName))
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
// check for tmp file
|
||||
if (File.Exists(tempFile + ".tmp"))
|
||||
{
|
||||
if (IsOwnedByRoot(tempFile + ".tmp"))
|
||||
{
|
||||
File.Move(tempFile + ".tmp", fileName);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
count++;
|
||||
tempFile = fileName + count.ToString();
|
||||
}
|
||||
File.Delete(tempFile + ".tmp");
|
||||
}
|
||||
else
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
// delete tmp file if there
|
||||
if (File.Exists(tempFile + ".tmp"))
|
||||
{
|
||||
if (IsOwnedByRoot(tempFile + ".tmp"))
|
||||
File.Delete(tempFile + ".tmp");
|
||||
}
|
||||
}
|
||||
|
||||
byte[] baPasscode = null;
|
||||
if (null != m_baGeneratedKey)
|
||||
baPasscode = m_baGeneratedKey;
|
||||
else
|
||||
baPasscode = CASACrypto.GetMasterPasscode(userStore.GetDesktopPasswd(), userStore.GetPasscodeByDesktopFilePath());
|
||||
baPasscode = CASACrypto.GetMasterPasscode(userStore.GetDesktopPasswd(), userStore.GetPasscodeByDesktopFilePath(), userStore.GetUserIdentifier());
|
||||
|
||||
if (null == baPasscode)
|
||||
return null;
|
||||
|
||||
byte[] key = CASACrypto.GetKeySetFromFile(baPasscode, userStore.GetKeyFilePath());
|
||||
byte[] key = CASACrypto.GetKeySetFromFile(baPasscode, userStore.GetKeyFilePath(), userStore.GetUserIdentifier());
|
||||
if (null == key)
|
||||
return null;
|
||||
|
||||
byte[] decryptedBuffer = CASACrypto.ReadFileAndDecryptData(key, fileName);
|
||||
byte[] decryptedBuffer = CASACrypto.ReadFileAndDecryptData(key, fileName, userStore.GetUserIdentifier());
|
||||
|
||||
if (null == decryptedBuffer)
|
||||
return null;
|
||||
@ -660,48 +606,31 @@ namespace sscs.lss
|
||||
|
||||
if (keyChainId == ConstStrings.SSCS_SESSION_KEY_CHAIN_ID)
|
||||
{
|
||||
key = CASACrypto.GetKeySetFromFile(m_baGeneratedKey, userStore.GetKeyFilePath());
|
||||
key = CASACrypto.GetKeySetFromFile(m_baGeneratedKey, userStore.GetKeyFilePath(), userStore.GetUserIdentifier());
|
||||
fileName = userStore.GetPersistenceFilePath();
|
||||
}
|
||||
else if (keyChainId == ConstStrings.SSCS_SERVER_KEY_CHAIN_ID)
|
||||
{
|
||||
key = CASACrypto.GetKeySetFromFile(m_baGeneratedKey, userStore.GetServerKeyFilePath());
|
||||
key = CASACrypto.GetKeySetFromFile(m_baGeneratedKey, userStore.GetServerKeyFilePath(), userStore.GetUserIdentifier());
|
||||
fileName = userStore.GetServerSecretsPersistenceFilePath();
|
||||
}
|
||||
|
||||
string tempFile = fileName;
|
||||
int count = 0;
|
||||
|
||||
// rename existing file
|
||||
if (File.Exists(fileName))
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
if (File.Exists(tempFile + ".tmp"))
|
||||
{
|
||||
if (IsOwnedByRoot(tempFile + ".tmp"))
|
||||
{
|
||||
File.Delete(tempFile + ".tmp");
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
count++;
|
||||
tempFile = fileName + count.ToString();
|
||||
}
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
File.Move(fileName, tempFile + ".tmp");
|
||||
}
|
||||
|
||||
CASACrypto.EncryptDataAndWriteToFile(ms1.ToArray(), key, fileName);
|
||||
CASACrypto.EncryptDataAndWriteToFile(ms1.ToArray(), key, fileName, userStore.GetUserIdentifier());
|
||||
|
||||
//remove temp
|
||||
if (File.Exists(tempFile + ".tmp"))
|
||||
{
|
||||
if (IsOwnedByRoot(tempFile + ".tmp"))
|
||||
File.Delete(tempFile + ".tmp");
|
||||
}
|
||||
}
|
||||
|
@ -107,11 +107,11 @@ namespace sscs.crypto {
|
||||
}
|
||||
|
||||
public Rfc2898DeriveBytes(string password, int saltSize, int iterations)
|
||||
: this (password, saltSize, iterations, false, null, false)
|
||||
: this (password, saltSize, iterations, false, null, false, null)
|
||||
{
|
||||
}
|
||||
|
||||
public Rfc2898DeriveBytes (string password, int saltSize, int iterations, bool bUseOldMethod, string sFilepath, bool bGenerateAndSaveRandomSalt)
|
||||
public Rfc2898DeriveBytes (string password, int saltSize, int iterations, bool bUseOldMethod, string sFilepath, bool bGenerateAndSaveRandomSalt, UserIdentifier userID)
|
||||
{
|
||||
if (password == null)
|
||||
throw new ArgumentNullException ("password");
|
||||
@ -126,14 +126,14 @@ namespace sscs.crypto {
|
||||
{
|
||||
if (bGenerateAndSaveRandomSalt)
|
||||
{
|
||||
Salt = GenerateAndSaveRandomSalt(saltSize, sFilepath);
|
||||
Salt = GenerateAndSaveRandomSalt(saltSize, sFilepath, userID);
|
||||
}
|
||||
else
|
||||
{
|
||||
// load saved salt if one was saved
|
||||
if ((sFilepath != null) && (File.Exists(sFilepath + ".salt")))
|
||||
{
|
||||
Salt = LoadSavedSalt(sFilepath);
|
||||
Salt = LoadSavedSalt(sFilepath, userID);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -146,7 +146,7 @@ namespace sscs.crypto {
|
||||
_hmac = new HMACSHA1 (Encoding.UTF8.GetBytes (password));
|
||||
}
|
||||
|
||||
private byte[] GenerateAndSaveRandomSalt(int saltSize, string sFilepath)
|
||||
private byte[] GenerateAndSaveRandomSalt(int saltSize, string sFilepath, UserIdentifier userID)
|
||||
{
|
||||
byte[] randomSalt = new byte[saltSize];
|
||||
FastRandom fr = new FastRandom();
|
||||
@ -163,6 +163,10 @@ namespace sscs.crypto {
|
||||
|
||||
File.SetAttributes(sFilepath + ".salt", FileAttributes.Hidden);
|
||||
|
||||
if (!CSSSUtils.SetSocketUserAsOwner(sFilepath + ".salt", userID))
|
||||
{
|
||||
CSSSLogger.DbgLog("Unable to set the owner of the file to the socket user");
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@ -172,12 +176,22 @@ namespace sscs.crypto {
|
||||
return randomSalt;
|
||||
}
|
||||
|
||||
private byte[] LoadSavedSalt(string sFilePath)
|
||||
private byte[] LoadSavedSalt(string sFilePath, UserIdentifier userID)
|
||||
{
|
||||
byte[] baSalt = null;
|
||||
|
||||
try
|
||||
{
|
||||
#if LINUX
|
||||
Mono.Unix.UnixFileInfo fsTest = new Mono.Unix.UnixFileInfo (sFilePath + ".salt");
|
||||
if((fsTest == null) || !(fsTest.Exists) || fsTest.IsSymbolicLink || !CSSSUtils.CompareSocketAndFileUserIds(sFilePath + ".salt", userID))
|
||||
#else
|
||||
if (!File.Exists(sFilePath + ".salt"))
|
||||
#endif
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
FileStream fs = new FileStream(sFilePath + ".salt", FileMode.Open);
|
||||
baSalt = new byte[fs.Length];
|
||||
fs.Read(baSalt, 0, (int)fs.Length);
|
||||
|
Loading…
Reference in New Issue
Block a user