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/UnixUserIdentifier.cs \
|
||||||
$(srcdir)/common/Constants.cs \
|
$(srcdir)/common/Constants.cs \
|
||||||
$(srcdir)/common/CSSSLogger.cs \
|
$(srcdir)/common/CSSSLogger.cs \
|
||||||
|
$(srcdir)/common/CSSSUtils.cs \
|
||||||
$(srcdir)/common/CSSSException.cs \
|
$(srcdir)/common/CSSSException.cs \
|
||||||
$(srcdir)/communication/IPCChannel.cs \
|
$(srcdir)/communication/IPCChannel.cs \
|
||||||
$(srcdir)/communication/CommunicationFactory.cs \
|
$(srcdir)/communication/CommunicationFactory.cs \
|
||||||
|
343
CASA/micasad/cache/MPFileWatcher.cs
vendored
343
CASA/micasad/cache/MPFileWatcher.cs
vendored
@ -1,169 +1,174 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
using sscs.common;
|
using sscs.common;
|
||||||
|
|
||||||
namespace sscs.cache
|
namespace sscs.cache
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Summary description for MPFileWatcher.
|
/// Summary description for MPFileWatcher.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class MPFileWatcher
|
class MPFileWatcher
|
||||||
{
|
{
|
||||||
FileSystemWatcher fwatcher;
|
FileSystemWatcher fwatcher;
|
||||||
private string m_dir = null;
|
private string m_dir = null;
|
||||||
private string m_filename = null;
|
private string m_filename = null;
|
||||||
private byte[] m_baMP = new byte[32];
|
private byte[] m_baMP = new byte[32];
|
||||||
private byte[] m_baMPIV = new byte[32];
|
private byte[] m_baMPIV = new byte[32];
|
||||||
private byte[] m_baMPSalt = null;
|
private byte[] m_baMPSalt = null;
|
||||||
private bool m_bIgnoreFileDeletes = false;
|
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_dir = MPFilePath;
|
{
|
||||||
m_filename = MPFileName;
|
m_store = store;
|
||||||
|
m_dir = MPFilePath;
|
||||||
if ((MPFilePath != null) && (MPFileName != null))
|
m_filename = MPFileName;
|
||||||
{
|
|
||||||
LogMessage("Starting MPFile watcher on " + MPFilePath + "/" + MPFileName.Substring(1));
|
if ((MPFilePath != null) && (MPFileName != null))
|
||||||
fwatcher = new FileSystemWatcher(MPFilePath);
|
{
|
||||||
fwatcher.Filter = MPFileName.Substring(1)+"*";
|
LogMessage("Starting MPFile watcher on " + MPFilePath + "/" + MPFileName.Substring(1));
|
||||||
fwatcher.Deleted += new FileSystemEventHandler(fwatcher_Deleted);
|
fwatcher = new FileSystemWatcher(MPFilePath);
|
||||||
fwatcher.Renamed += new RenamedEventHandler(fwatcher_Renamed);
|
fwatcher.Filter = MPFileName.Substring(1)+"*";
|
||||||
fwatcher.Changed += new FileSystemEventHandler(fwatcher_Changed);
|
fwatcher.Deleted += new FileSystemEventHandler(fwatcher_Deleted);
|
||||||
fwatcher.EnableRaisingEvents = true;
|
fwatcher.Renamed += new RenamedEventHandler(fwatcher_Renamed);
|
||||||
}
|
fwatcher.Changed += new FileSystemEventHandler(fwatcher_Changed);
|
||||||
|
fwatcher.EnableRaisingEvents = true;
|
||||||
if (File.Exists(MPFilePath + MPFileName))
|
}
|
||||||
{
|
|
||||||
LoadAndCacheMPFiles();
|
if (File.Exists(MPFilePath + MPFileName))
|
||||||
}
|
{
|
||||||
}
|
LoadAndCacheMPFiles();
|
||||||
|
}
|
||||||
~MPFileWatcher()
|
}
|
||||||
{
|
|
||||||
if (fwatcher != null)
|
~MPFileWatcher()
|
||||||
fwatcher.EnableRaisingEvents = false;
|
{
|
||||||
fwatcher = null;
|
if (fwatcher != null)
|
||||||
}
|
fwatcher.EnableRaisingEvents = false;
|
||||||
internal void pauseWatcher()
|
fwatcher = null;
|
||||||
{
|
}
|
||||||
m_bIgnoreFileDeletes = true;
|
internal void pauseWatcher()
|
||||||
}
|
{
|
||||||
|
m_bIgnoreFileDeletes = true;
|
||||||
internal void resumeWatcher()
|
}
|
||||||
{
|
|
||||||
m_bIgnoreFileDeletes = false;
|
internal void resumeWatcher()
|
||||||
}
|
{
|
||||||
|
m_bIgnoreFileDeletes = false;
|
||||||
private void fwatcher_Deleted(object sender, FileSystemEventArgs e)
|
}
|
||||||
{
|
|
||||||
if (!m_bIgnoreFileDeletes)
|
private void fwatcher_Deleted(object sender, FileSystemEventArgs e)
|
||||||
{
|
{
|
||||||
LogMessage("MP file deleted");
|
if (!m_bIgnoreFileDeletes)
|
||||||
ReWriteFiles();
|
{
|
||||||
}
|
LogMessage("MP file deleted");
|
||||||
}
|
ReWriteFiles();
|
||||||
|
}
|
||||||
private void fwatcher_Changed(object sender, FileSystemEventArgs e)
|
}
|
||||||
{
|
|
||||||
LogMessage("MP file Changed");
|
private void fwatcher_Changed(object sender, FileSystemEventArgs e)
|
||||||
LoadAndCacheMPFiles();
|
{
|
||||||
}
|
LogMessage("MP file Changed");
|
||||||
|
LoadAndCacheMPFiles();
|
||||||
private void fwatcher_Renamed(object sender, RenamedEventArgs e)
|
}
|
||||||
{
|
|
||||||
LogMessage("MP file renamed");
|
private void fwatcher_Renamed(object sender, RenamedEventArgs e)
|
||||||
fwatcher_Deleted(sender, e);
|
{
|
||||||
}
|
LogMessage("MP file renamed");
|
||||||
|
fwatcher_Deleted(sender, e);
|
||||||
private void LoadAndCacheMPFiles()
|
}
|
||||||
{
|
|
||||||
LogMessage("Loading and caching MP files");
|
private void LoadAndCacheMPFiles()
|
||||||
|
{
|
||||||
try
|
LogMessage("Loading and caching MP files");
|
||||||
{
|
|
||||||
FileStream fs = new FileStream(m_dir + m_filename, FileMode.Open, FileAccess.Read);
|
try
|
||||||
fs.Read(m_baMP, 0, m_baMP.Length);
|
{
|
||||||
fs.Flush();
|
FileStream fs = new FileStream(m_dir + m_filename, FileMode.Open, FileAccess.Read);
|
||||||
fs.Close();
|
fs.Read(m_baMP, 0, m_baMP.Length);
|
||||||
|
fs.Flush();
|
||||||
fs = new FileStream(m_dir + m_filename + ".IV", FileMode.Open, FileAccess.Read);
|
fs.Close();
|
||||||
fs.Read(m_baMPIV, 0, m_baMPIV.Length);
|
|
||||||
fs.Flush();
|
fs = new FileStream(m_dir + m_filename + ".IV", FileMode.Open, FileAccess.Read);
|
||||||
fs.Close();
|
fs.Read(m_baMPIV, 0, m_baMPIV.Length);
|
||||||
|
fs.Flush();
|
||||||
if (File.Exists(m_dir + m_filename + ".salt"))
|
fs.Close();
|
||||||
{
|
|
||||||
m_baMPSalt = new byte[64];
|
if (File.Exists(m_dir + m_filename + ".salt"))
|
||||||
fs = new FileStream(m_dir + m_filename + ".salt", FileMode.Open, FileAccess.Read);
|
{
|
||||||
fs.Read(m_baMPSalt, 0, m_baMPSalt.Length);
|
m_baMPSalt = new byte[64];
|
||||||
fs.Flush();
|
fs = new FileStream(m_dir + m_filename + ".salt", FileMode.Open, FileAccess.Read);
|
||||||
fs.Close();
|
fs.Read(m_baMPSalt, 0, m_baMPSalt.Length);
|
||||||
}
|
fs.Flush();
|
||||||
|
fs.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
catch (Exception e)
|
}
|
||||||
{
|
|
||||||
LogMessage(e.ToString());
|
catch (Exception e)
|
||||||
}
|
{
|
||||||
}
|
LogMessage(e.ToString());
|
||||||
|
}
|
||||||
private void ReWriteFiles()
|
}
|
||||||
{
|
|
||||||
try
|
private void ReWriteFiles()
|
||||||
{
|
{
|
||||||
FileStream fs = new FileStream(m_dir + m_filename, FileMode.Create);
|
try
|
||||||
fs.Write(m_baMP, 0, m_baMP.Length);
|
{
|
||||||
fs.Flush();
|
FileStream fs = new FileStream(m_dir + m_filename, FileMode.Create);
|
||||||
fs.Close();
|
fs.Write(m_baMP, 0, m_baMP.Length);
|
||||||
|
fs.Flush();
|
||||||
File.SetAttributes(m_dir + m_filename, FileAttributes.Hidden);
|
fs.Close();
|
||||||
}
|
|
||||||
catch (Exception e)
|
File.SetAttributes(m_dir + m_filename, FileAttributes.Hidden);
|
||||||
{
|
CSSSUtils.SetSocketUserAsOwner(m_dir + m_filename, m_store.user.UserIdentifier);
|
||||||
LogMessage(e.ToString());
|
}
|
||||||
}
|
catch (Exception e)
|
||||||
|
{
|
||||||
try
|
LogMessage(e.ToString());
|
||||||
{
|
}
|
||||||
FileStream fs = new FileStream(m_dir + m_filename + ".IV", FileMode.Create);
|
|
||||||
fs.Write(m_baMPIV, 0, m_baMPIV.Length);
|
try
|
||||||
fs.Flush();
|
{
|
||||||
fs.Close();
|
FileStream fs = new FileStream(m_dir + m_filename + ".IV", FileMode.Create);
|
||||||
|
fs.Write(m_baMPIV, 0, m_baMPIV.Length);
|
||||||
File.SetAttributes(m_dir + m_filename + ".IV", FileAttributes.Hidden);
|
fs.Flush();
|
||||||
}
|
fs.Close();
|
||||||
catch (Exception e)
|
|
||||||
{
|
File.SetAttributes(m_dir + m_filename + ".IV", FileAttributes.Hidden);
|
||||||
LogMessage(e.ToString());
|
CSSSUtils.SetSocketUserAsOwner(m_dir + m_filename + ".IV", m_store.user.UserIdentifier);
|
||||||
}
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
if (m_baMPSalt != null)
|
LogMessage(e.ToString());
|
||||||
{
|
}
|
||||||
try
|
|
||||||
{
|
|
||||||
FileStream fs = new FileStream(m_dir + m_filename + ".salt", FileMode.Create);
|
if (m_baMPSalt != null)
|
||||||
fs.Write(m_baMPSalt, 0, m_baMPSalt.Length);
|
{
|
||||||
fs.Flush();
|
try
|
||||||
fs.Close();
|
{
|
||||||
|
FileStream fs = new FileStream(m_dir + m_filename + ".salt", FileMode.Create);
|
||||||
File.SetAttributes(m_dir + m_filename + ".salt", FileAttributes.Hidden);
|
fs.Write(m_baMPSalt, 0, m_baMPSalt.Length);
|
||||||
}
|
fs.Flush();
|
||||||
catch (Exception e)
|
fs.Close();
|
||||||
{
|
|
||||||
LogMessage(e.ToString());
|
File.SetAttributes(m_dir + m_filename + ".salt", FileAttributes.Hidden);
|
||||||
}
|
CSSSUtils.SetSocketUserAsOwner(m_dir + m_filename + ".salt", m_store.user.UserIdentifier);
|
||||||
}
|
}
|
||||||
|
catch (Exception e)
|
||||||
}
|
{
|
||||||
|
LogMessage(e.ToString());
|
||||||
private void LogMessage(string message)
|
}
|
||||||
{
|
}
|
||||||
// Console.WriteLine(message);
|
|
||||||
CSSSLogger.DbgLog("MPFileWatcher:" + message);
|
}
|
||||||
}
|
|
||||||
}
|
private void LogMessage(string message)
|
||||||
}
|
{
|
||||||
|
// Console.WriteLine(message);
|
||||||
|
CSSSLogger.DbgLog("MPFileWatcher:" + message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
257
CASA/micasad/cache/SecretStore.cs
vendored
257
CASA/micasad/cache/SecretStore.cs
vendored
@ -116,7 +116,7 @@ namespace sscs.cache
|
|||||||
String sPersistentDir = GetPersistenceDirectory();
|
String sPersistentDir = GetPersistenceDirectory();
|
||||||
if (sPersistentDir != null && sPersistentDir.Length > 0)
|
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,16 +176,16 @@ namespace sscs.cache
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
byte[] baPasscode = CASACrypto.GetMasterPasscodeUsingDesktopPasswd(sDesktopPassword, GetPasscodeByDesktopFilePath(), false);
|
byte[] baPasscode = CASACrypto.GetMasterPasscodeUsingDesktopPasswd(sDesktopPassword, GetPasscodeByDesktopFilePath(), false, user.UserIdentifier);
|
||||||
if (CASACrypto.ValidatePasscode(baPasscode, GetValidationFilePath()))
|
if (CASACrypto.ValidatePasscode(baPasscode, GetValidationFilePath(), user.UserIdentifier))
|
||||||
{
|
{
|
||||||
ReEncryptPasscodeUsingRandomSalt(baPasscode, sDesktopPassword, GetPasscodeByDesktopFilePath());
|
ReEncryptPasscodeUsingRandomSalt(baPasscode, sDesktopPassword, GetPasscodeByDesktopFilePath());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// try old salt
|
// try old salt
|
||||||
baPasscode = CASACrypto.GetMasterPasscodeUsingDesktopPasswd(sDesktopPassword, GetPasscodeByDesktopFilePath(), true);
|
baPasscode = CASACrypto.GetMasterPasscodeUsingDesktopPasswd(sDesktopPassword, GetPasscodeByDesktopFilePath(), true, user.UserIdentifier);
|
||||||
if (CASACrypto.ValidatePasscode(baPasscode, GetValidationFilePath()))
|
if (CASACrypto.ValidatePasscode(baPasscode, GetValidationFilePath(), user.UserIdentifier))
|
||||||
{
|
{
|
||||||
ReEncryptPasscodeUsingRandomSalt(baPasscode, sDesktopPassword, GetPasscodeByDesktopFilePath());
|
ReEncryptPasscodeUsingRandomSalt(baPasscode, sDesktopPassword, GetPasscodeByDesktopFilePath());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -230,7 +230,8 @@ namespace sscs.cache
|
|||||||
*/
|
*/
|
||||||
baPasscode = CASACrypto.GenerateServerMasterPasscode(
|
baPasscode = CASACrypto.GenerateServerMasterPasscode(
|
||||||
GetServerPasscodeBySystemKeyFilePath(),
|
GetServerPasscodeBySystemKeyFilePath(),
|
||||||
GetServerValidationFilePath());
|
GetServerValidationFilePath(),
|
||||||
|
user.UserIdentifier);
|
||||||
|
|
||||||
if (null == baPasscode)
|
if (null == baPasscode)
|
||||||
{
|
{
|
||||||
@ -246,8 +247,8 @@ namespace sscs.cache
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
baPasscode = CASACrypto.GetServerMasterPasscodeUsingSystemKey(GetServerPasscodeBySystemKeyFilePath());
|
baPasscode = CASACrypto.GetServerMasterPasscodeUsingSystemKey(GetServerPasscodeBySystemKeyFilePath(), user.UserIdentifier);
|
||||||
if (CASACrypto.ValidatePasscode(baPasscode, GetServerValidationFilePath()))
|
if (CASACrypto.ValidatePasscode(baPasscode, GetServerValidationFilePath(), user.UserIdentifier))
|
||||||
{
|
{
|
||||||
slss = new LocalStorage(this, baPasscode, true);
|
slss = new LocalStorage(this, baPasscode, true);
|
||||||
bIsServerStorePersistent = true;
|
bIsServerStorePersistent = true;
|
||||||
@ -335,23 +336,23 @@ namespace sscs.cache
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
baPasscode = CASACrypto.GetMasterPasscodeUsingDesktopPasswd(desktopPasswd, GetPasscodeByDesktopFilePath(), false);
|
baPasscode = CASACrypto.GetMasterPasscodeUsingDesktopPasswd(desktopPasswd, GetPasscodeByDesktopFilePath(), false, user.UserIdentifier);
|
||||||
if (CASACrypto.ValidatePasscode(baPasscode, GetValidationFilePath()))
|
if (CASACrypto.ValidatePasscode(baPasscode, GetValidationFilePath(), user.UserIdentifier))
|
||||||
{
|
{
|
||||||
lss = new LocalStorage(this, baPasscode);
|
lss = new LocalStorage(this, baPasscode);
|
||||||
bIsStorePersistent = true;
|
bIsStorePersistent = true;
|
||||||
ReEncryptPasscodeUsingRandomSalt(baPasscode, desktopPasswd, GetPasscodeByDesktopFilePath());
|
ReEncryptPasscodeUsingRandomSalt(baPasscode, desktopPasswd, GetPasscodeByDesktopFilePath());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// try old encryption method
|
// try old encryption method
|
||||||
baPasscode = CASACrypto.GetMasterPasscodeUsingDesktopPasswd(desktopPasswd, GetPasscodeByDesktopFilePath(), true);
|
baPasscode = CASACrypto.GetMasterPasscodeUsingDesktopPasswd(desktopPasswd, GetPasscodeByDesktopFilePath(), true, user.UserIdentifier);
|
||||||
if (CASACrypto.ValidatePasscode(baPasscode, GetValidationFilePath()))
|
if (CASACrypto.ValidatePasscode(baPasscode, GetValidationFilePath(), user.UserIdentifier))
|
||||||
{
|
{
|
||||||
// rewrite file using new encryption
|
// rewrite file using new encryption
|
||||||
ReEncryptPasscodeUsingRandomSalt(baPasscode, desktopPasswd, GetPasscodeByDesktopFilePath());
|
ReEncryptPasscodeUsingRandomSalt(baPasscode, desktopPasswd, GetPasscodeByDesktopFilePath());
|
||||||
//CASACrypto.EncryptAndStoreMasterPasscodeUsingString(baPasscode, desktopPasswd, GetPasscodeByDesktopFilePath());
|
//CASACrypto.EncryptAndStoreMasterPasscodeUsingString(baPasscode, desktopPasswd, GetPasscodeByDesktopFilePath(), user.UserIdentifier);
|
||||||
lss = new LocalStorage(this, baPasscode);
|
lss = new LocalStorage(this, baPasscode);
|
||||||
bIsStorePersistent = true;
|
bIsStorePersistent = true;
|
||||||
return true;
|
return true;
|
||||||
@ -381,7 +382,7 @@ namespace sscs.cache
|
|||||||
myRijndael.GenerateKey();
|
myRijndael.GenerateKey();
|
||||||
key = myRijndael.Key;
|
key = myRijndael.Key;
|
||||||
|
|
||||||
CASACrypto.StoreKeySetUsingMasterPasscode(key, IV, baPasscode, fileName);
|
CASACrypto.StoreKeySetUsingMasterPasscode(key, IV, baPasscode, fileName, user.UserIdentifier);
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
@ -410,10 +411,10 @@ namespace sscs.cache
|
|||||||
*/
|
*/
|
||||||
if (desktopPasswd != null)
|
if (desktopPasswd != null)
|
||||||
{
|
{
|
||||||
baPasscode = CASACrypto.GetMasterPasscodeUsingDesktopPasswd(desktopPasswd, GetPasscodeByDesktopFilePath(), false);
|
baPasscode = CASACrypto.GetMasterPasscodeUsingDesktopPasswd(desktopPasswd, GetPasscodeByDesktopFilePath(), false, user.UserIdentifier);
|
||||||
if (CASACrypto.ValidatePasscode(baPasscode, GetValidationFilePath()))
|
if (CASACrypto.ValidatePasscode(baPasscode, GetValidationFilePath(), user.UserIdentifier))
|
||||||
{
|
{
|
||||||
CASACrypto.EncryptAndStoreMasterPasscodeUsingString(baPasscode, mPasswd, GetPasscodeByMasterPasswdFilePath());
|
CASACrypto.EncryptAndStoreMasterPasscodeUsingString(baPasscode, mPasswd, GetPasscodeByMasterPasswdFilePath(), user.UserIdentifier);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -422,20 +423,23 @@ namespace sscs.cache
|
|||||||
baPasscode = CASACrypto.GetMasterPasscodeUsingDesktopPasswd(
|
baPasscode = CASACrypto.GetMasterPasscodeUsingDesktopPasswd(
|
||||||
desktopPasswd,
|
desktopPasswd,
|
||||||
GetPasscodeByDesktopFilePath(),
|
GetPasscodeByDesktopFilePath(),
|
||||||
true);
|
true,
|
||||||
|
user.UserIdentifier);
|
||||||
|
|
||||||
if (CASACrypto.ValidatePasscode(baPasscode, GetValidationFilePath()))
|
if (CASACrypto.ValidatePasscode(baPasscode, GetValidationFilePath(), user.UserIdentifier))
|
||||||
{
|
{
|
||||||
// rewrite file using new method
|
// rewrite file using new method
|
||||||
CASACrypto.EncryptAndStoreMasterPasscodeUsingString(
|
CASACrypto.EncryptAndStoreMasterPasscodeUsingString(
|
||||||
baPasscode,
|
baPasscode,
|
||||||
desktopPasswd,
|
desktopPasswd,
|
||||||
GetPasscodeByDesktopFilePath());
|
GetPasscodeByDesktopFilePath(),
|
||||||
|
user.UserIdentifier);
|
||||||
|
|
||||||
CASACrypto.EncryptAndStoreMasterPasscodeUsingString(
|
CASACrypto.EncryptAndStoreMasterPasscodeUsingString(
|
||||||
baPasscode,
|
baPasscode,
|
||||||
mPasswd,
|
mPasswd,
|
||||||
GetPasscodeByMasterPasswdFilePath());
|
GetPasscodeByMasterPasswdFilePath(),
|
||||||
|
user.UserIdentifier);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -447,8 +451,8 @@ namespace sscs.cache
|
|||||||
baPasscode = CASACrypto.GenerateMasterPasscodeUsingString(mPasswd, GetPasscodeByMasterPasswdFilePath(), GetValidationFilePath(), user.UserIdentifier);
|
baPasscode = CASACrypto.GenerateMasterPasscodeUsingString(mPasswd, GetPasscodeByMasterPasswdFilePath(), GetValidationFilePath(), user.UserIdentifier);
|
||||||
if (baPasscode != null)
|
if (baPasscode != null)
|
||||||
{
|
{
|
||||||
CASACrypto.EncryptAndStoreMasterPasscodeUsingString(baPasscode, mPasswd, GetPasscodeByMasterPasswdFilePath());
|
CASACrypto.EncryptAndStoreMasterPasscodeUsingString(baPasscode, mPasswd, GetPasscodeByMasterPasswdFilePath(), user.UserIdentifier);
|
||||||
CASACrypto.EncryptAndStoreMasterPasscodeUsingString(baPasscode, desktopPasswd, GetPasscodeByDesktopFilePath());
|
CASACrypto.EncryptAndStoreMasterPasscodeUsingString(baPasscode, desktopPasswd, GetPasscodeByDesktopFilePath(), user.UserIdentifier);
|
||||||
if (File.Exists(GetPersistenceFilePath()))
|
if (File.Exists(GetPersistenceFilePath()))
|
||||||
{
|
{
|
||||||
File.Delete(GetPersistenceFilePath());
|
File.Delete(GetPersistenceFilePath());
|
||||||
@ -493,7 +497,7 @@ namespace sscs.cache
|
|||||||
GenerateAndStoreEncryptionKey(baPasscode, GetKeyFilePath());
|
GenerateAndStoreEncryptionKey(baPasscode, GetKeyFilePath());
|
||||||
}
|
}
|
||||||
|
|
||||||
CASACrypto.EncryptAndStoreMasterPasscodeUsingString(baPasscode, mPasswd, GetPasscodeByMasterPasswdFilePath());
|
CASACrypto.EncryptAndStoreMasterPasscodeUsingString(baPasscode, mPasswd, GetPasscodeByMasterPasswdFilePath(), user.UserIdentifier);
|
||||||
if (bIsStorePersistent == false)
|
if (bIsStorePersistent == false)
|
||||||
{
|
{
|
||||||
lss = new LocalStorage(this, baPasscode);
|
lss = new LocalStorage(this, baPasscode);
|
||||||
@ -514,12 +518,12 @@ namespace sscs.cache
|
|||||||
//If validation succeeds,start persistence.
|
//If validation succeeds,start persistence.
|
||||||
if (desktopPasswd == null)
|
if (desktopPasswd == null)
|
||||||
{
|
{
|
||||||
baPasscode = CASACrypto.DecryptMasterPasscodeUsingString(mPasswd, GetPasscodeByMasterPasswdFilePath(), false);
|
baPasscode = CASACrypto.DecryptMasterPasscodeUsingString(mPasswd, GetPasscodeByMasterPasswdFilePath(), false, user.UserIdentifier);
|
||||||
if (CASACrypto.ValidatePasscode(baPasscode, GetValidationFilePath()))
|
if (CASACrypto.ValidatePasscode(baPasscode, GetValidationFilePath(), user.UserIdentifier))
|
||||||
{
|
{
|
||||||
if (bIsStorePersistent == false)
|
if (bIsStorePersistent == false)
|
||||||
{
|
{
|
||||||
lss = new LocalStorage(this, baPasscode);
|
lss = new LocalStorage(this, baPasscode);
|
||||||
ReEncryptPasscodeUsingRandomSalt(baPasscode, mPasswd, GetPasscodeByMasterPasswdFilePath());
|
ReEncryptPasscodeUsingRandomSalt(baPasscode, mPasswd, GetPasscodeByMasterPasswdFilePath());
|
||||||
bIsStorePersistent = true;
|
bIsStorePersistent = true;
|
||||||
}
|
}
|
||||||
@ -528,11 +532,11 @@ namespace sscs.cache
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// try validation, if it fails, try decryption using the old method
|
// try validation, if it fails, try decryption using the old method
|
||||||
baPasscode = CASACrypto.DecryptMasterPasscodeUsingString(mPasswd, GetPasscodeByMasterPasswdFilePath(), true);
|
baPasscode = CASACrypto.DecryptMasterPasscodeUsingString(mPasswd, GetPasscodeByMasterPasswdFilePath(), true, user.UserIdentifier);
|
||||||
if (CASACrypto.ValidatePasscode(baPasscode, GetValidationFilePath()))
|
if (CASACrypto.ValidatePasscode(baPasscode, GetValidationFilePath(), user.UserIdentifier))
|
||||||
{
|
{
|
||||||
// rewrite file
|
// rewrite file
|
||||||
CASACrypto.EncryptAndStoreMasterPasscodeUsingString(baPasscode, mPasswd, GetPasscodeByMasterPasswdFilePath());
|
CASACrypto.EncryptAndStoreMasterPasscodeUsingString(baPasscode, mPasswd, GetPasscodeByMasterPasswdFilePath(), user.UserIdentifier);
|
||||||
if (bIsStorePersistent == false)
|
if (bIsStorePersistent == false)
|
||||||
{
|
{
|
||||||
lss = new LocalStorage(this, baPasscode);
|
lss = new LocalStorage(this, baPasscode);
|
||||||
@ -549,13 +553,13 @@ namespace sscs.cache
|
|||||||
else
|
else
|
||||||
{ //There are 2 cases - either desktop passwd has changed
|
{ //There are 2 cases - either desktop passwd has changed
|
||||||
//or it hasnt.
|
//or it hasnt.
|
||||||
baPasscode = CASACrypto.GetMasterPasscodeUsingMasterPasswd(mPasswd, GetPasscodeByMasterPasswdFilePath(), false);
|
baPasscode = CASACrypto.GetMasterPasscodeUsingMasterPasswd(mPasswd, GetPasscodeByMasterPasswdFilePath(), false, user.UserIdentifier);
|
||||||
if (CASACrypto.ValidatePasscode(baPasscode, GetValidationFilePath()))
|
if (CASACrypto.ValidatePasscode(baPasscode, GetValidationFilePath(), user.UserIdentifier))
|
||||||
{
|
{
|
||||||
RewriteDesktopPasswdFile(baPasscode, desktopPasswd);
|
RewriteDesktopPasswdFile(baPasscode, desktopPasswd);
|
||||||
if (bIsStorePersistent == false)
|
if (bIsStorePersistent == false)
|
||||||
{
|
{
|
||||||
lss = new LocalStorage(this, baPasscode);
|
lss = new LocalStorage(this, baPasscode);
|
||||||
ReEncryptPasscodeUsingRandomSalt(baPasscode, mPasswd, GetPasscodeByMasterPasswdFilePath());
|
ReEncryptPasscodeUsingRandomSalt(baPasscode, mPasswd, GetPasscodeByMasterPasswdFilePath());
|
||||||
bIsStorePersistent = true;
|
bIsStorePersistent = true;
|
||||||
}
|
}
|
||||||
@ -563,13 +567,13 @@ namespace sscs.cache
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
baPasscode = CASACrypto.GetMasterPasscodeUsingMasterPasswd(mPasswd, GetPasscodeByMasterPasswdFilePath(), true);
|
baPasscode = CASACrypto.GetMasterPasscodeUsingMasterPasswd(mPasswd, GetPasscodeByMasterPasswdFilePath(), true, user.UserIdentifier);
|
||||||
if (CASACrypto.ValidatePasscode(baPasscode, GetValidationFilePath()))
|
if (CASACrypto.ValidatePasscode(baPasscode, GetValidationFilePath(), user.UserIdentifier))
|
||||||
{
|
{
|
||||||
RewriteDesktopPasswdFile(baPasscode, desktopPasswd);
|
RewriteDesktopPasswdFile(baPasscode, desktopPasswd);
|
||||||
if (bIsStorePersistent == false)
|
if (bIsStorePersistent == false)
|
||||||
{
|
{
|
||||||
lss = new LocalStorage(this, baPasscode);
|
lss = new LocalStorage(this, baPasscode);
|
||||||
ReEncryptPasscodeUsingRandomSalt(baPasscode, mPasswd, GetPasscodeByMasterPasswdFilePath());
|
ReEncryptPasscodeUsingRandomSalt(baPasscode, mPasswd, GetPasscodeByMasterPasswdFilePath());
|
||||||
bIsStorePersistent = true;
|
bIsStorePersistent = true;
|
||||||
}
|
}
|
||||||
@ -592,7 +596,7 @@ namespace sscs.cache
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
CASACrypto.EncryptAndStoreMasterPasscodeUsingString(baPasscode, desktopPasswd, GetPasscodeByDesktopFilePath());
|
CASACrypto.EncryptAndStoreMasterPasscodeUsingString(baPasscode, desktopPasswd, GetPasscodeByDesktopFilePath(), user.UserIdentifier);
|
||||||
CSSSLogger.DbgLog("Re-encryted passcode with desktop passwd");
|
CSSSLogger.DbgLog("Re-encryted passcode with desktop passwd");
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
@ -606,20 +610,20 @@ namespace sscs.cache
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
byte[] baPasscode = CASACrypto.GetMasterPasscodeUsingDesktopPasswd(oldDesktopPasswd, GetPasscodeByDesktopFilePath(), false);
|
byte[] baPasscode = CASACrypto.GetMasterPasscodeUsingDesktopPasswd(oldDesktopPasswd, GetPasscodeByDesktopFilePath(), false, user.UserIdentifier);
|
||||||
if (CASACrypto.ValidatePasscode(baPasscode, GetValidationFilePath()))
|
if (CASACrypto.ValidatePasscode(baPasscode, GetValidationFilePath(), user.UserIdentifier))
|
||||||
{
|
{
|
||||||
ReEncryptPasscodeUsingRandomSalt(baPasscode, oldDesktopPasswd, GetPasscodeByDesktopFilePath());
|
ReEncryptPasscodeUsingRandomSalt(baPasscode, oldDesktopPasswd, GetPasscodeByDesktopFilePath());
|
||||||
return baPasscode;
|
return baPasscode;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// try old method
|
// try old method
|
||||||
baPasscode = CASACrypto.GetMasterPasscodeUsingDesktopPasswd(oldDesktopPasswd, GetPasscodeByDesktopFilePath(), true);
|
baPasscode = CASACrypto.GetMasterPasscodeUsingDesktopPasswd(oldDesktopPasswd, GetPasscodeByDesktopFilePath(), true, user.UserIdentifier);
|
||||||
if (CASACrypto.ValidatePasscode(baPasscode, GetValidationFilePath()))
|
if (CASACrypto.ValidatePasscode(baPasscode, GetValidationFilePath(), user.UserIdentifier))
|
||||||
{
|
{
|
||||||
// rewrite file now
|
// rewrite file now
|
||||||
CASACrypto.EncryptAndStoreMasterPasscodeUsingString(baPasscode, oldDesktopPasswd, GetPasscodeByDesktopFilePath());
|
CASACrypto.EncryptAndStoreMasterPasscodeUsingString(baPasscode, oldDesktopPasswd, GetPasscodeByDesktopFilePath(), user.UserIdentifier);
|
||||||
return baPasscode;
|
return baPasscode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -652,9 +656,9 @@ namespace sscs.cache
|
|||||||
//Create a new key and initialization vector.
|
//Create a new key and initialization vector.
|
||||||
myRijndael.GenerateKey();
|
myRijndael.GenerateKey();
|
||||||
key = myRijndael.Key;
|
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
|
//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);
|
lss = new LocalStorage(this,sMasterPasscode);
|
||||||
bIsStorePersistent = true;
|
bIsStorePersistent = true;
|
||||||
bRet = true;
|
bRet = true;
|
||||||
@ -857,11 +861,11 @@ namespace sscs.cache
|
|||||||
internal bool ChangeMasterPassword(string sCurrentPWD, string sNewPWD)
|
internal bool ChangeMasterPassword(string sCurrentPWD, string sNewPWD)
|
||||||
{
|
{
|
||||||
string sMasterFilePath = GetPasscodeByMasterPasswdFilePath();
|
string sMasterFilePath = GetPasscodeByMasterPasswdFilePath();
|
||||||
byte[] baPasscode = CASACrypto.GetMasterPasscodeUsingMasterPasswd(sCurrentPWD, sMasterFilePath, false);
|
byte[] baPasscode = CASACrypto.GetMasterPasscodeUsingMasterPasswd(sCurrentPWD, sMasterFilePath, false, user.UserIdentifier);
|
||||||
if (baPasscode != null)
|
if (baPasscode != null)
|
||||||
{
|
{
|
||||||
PauseFileWatcher();
|
PauseFileWatcher();
|
||||||
CASACrypto.EncryptAndStoreMasterPasscodeUsingString(baPasscode, sNewPWD, sMasterFilePath);
|
CASACrypto.EncryptAndStoreMasterPasscodeUsingString(baPasscode, sNewPWD, sMasterFilePath, user.UserIdentifier);
|
||||||
ResumeFileWatcher();
|
ResumeFileWatcher();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -907,6 +911,11 @@ namespace sscs.cache
|
|||||||
return user.GetUserName();
|
return user.GetUserName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal UserIdentifier GetUserIdentifier()
|
||||||
|
{
|
||||||
|
return user.UserIdentifier;
|
||||||
|
}
|
||||||
|
|
||||||
internal string GetPersistenceDirectory()
|
internal string GetPersistenceDirectory()
|
||||||
{
|
{
|
||||||
if (m_persistenceDirectory != null)
|
if (m_persistenceDirectory != null)
|
||||||
@ -917,53 +926,62 @@ namespace sscs.cache
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
||||||
string sUserHomeDir = GetUserHomeDirectory();
|
string sUserHomeDir = GetUserHomeDirectory();
|
||||||
if (sUserHomeDir != null)
|
if (sUserHomeDir != null)
|
||||||
{
|
{
|
||||||
|
// the user might have set a different one
|
||||||
// the user might have set a different one
|
// load the policy file and check.
|
||||||
// load the policy file and check.
|
UIPol uiPolicy = (UIPol)ICASAPol.GetPolicy(CASAPolType.UI_POL, sUserHomeDir, GetUserName());
|
||||||
UIPol uiPolicy = (UIPol)ICASAPol.GetPolicy(CASAPolType.UI_POL, sUserHomeDir, GetUserName());
|
if (uiPolicy != null)
|
||||||
if (uiPolicy != null)
|
{
|
||||||
{
|
string sDir = uiPolicy.GetConfigSetting(ConstStrings.CONFIG_PERSISTENT_DIRECTORY);
|
||||||
string sDir = uiPolicy.GetConfigSetting(ConstStrings.CONFIG_PERSISTENT_DIRECTORY);
|
if ((sDir != null) && (sDir.Length > 0))
|
||||||
if ((sDir != null) && (sDir.Length > 0))
|
{
|
||||||
{
|
m_persistenceDirectory = sDir;
|
||||||
m_persistenceDirectory = sDir;
|
if (IsDirectoryOwnedByUser(sDir))
|
||||||
return m_persistenceDirectory;
|
{
|
||||||
}
|
ChangeFileOwnershipForMiCasaFiles(sDir);
|
||||||
}
|
return m_persistenceDirectory;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// user not logged in yet
|
CSSSLogger.log(true, "CASA Warning: " + GetUserName() + " has persistent directory set to " + sDir);
|
||||||
return null;
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// user not logged in yet
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_persistenceDirectory = MigrateMiCasaFiles();
|
m_persistenceDirectory = MigrateMiCasaFiles();
|
||||||
return m_persistenceDirectory;
|
ChangeFileOwnershipForMiCasaFiles(null);
|
||||||
|
return m_persistenceDirectory;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal string MigrateMiCasaFiles()
|
internal string MigrateMiCasaFiles()
|
||||||
{
|
{
|
||||||
string sSeperator = "/";
|
string sSeperator = "/";
|
||||||
#if LINUX
|
#if LINUX
|
||||||
// for v1.7, we are storing MiCasa files in /home/.casa/[username]
|
// for v1.7, we are storing MiCasa files in /home/.casa/[username]
|
||||||
// let's migrate the files if needed
|
// let's migrate the files if needed
|
||||||
string sNewPath = POLICY_DIRECTORY + "/" + user.GetUserName();
|
string sNewPath = POLICY_DIRECTORY + "/" + user.GetUserName();
|
||||||
#else
|
#else
|
||||||
string sNewPath = GetUserHomeDirectory() + "\\CASA";
|
string sNewPath = GetUserHomeDirectory() + "\\CASA";
|
||||||
|
|
||||||
System.Diagnostics.Trace.WriteLine("Migrate files to " + sNewPath);
|
System.Diagnostics.Trace.WriteLine("Migrate files to " + sNewPath);
|
||||||
|
|
||||||
if (!Directory.Exists(sNewPath))
|
if (!Directory.Exists(sNewPath))
|
||||||
{
|
{
|
||||||
Directory.CreateDirectory(sNewPath);
|
Directory.CreateDirectory(sNewPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
sSeperator = "\\";
|
sSeperator = "\\";
|
||||||
#endif
|
#endif
|
||||||
try
|
try
|
||||||
@ -991,6 +1009,48 @@ namespace sscs.cache
|
|||||||
return (sNewPath);
|
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)
|
internal bool SetPeristenceDirectory(string sNewDirectory)
|
||||||
{
|
{
|
||||||
if (Directory.Exists(sNewDirectory))
|
if (Directory.Exists(sNewDirectory))
|
||||||
@ -999,11 +1059,12 @@ namespace sscs.cache
|
|||||||
if (mpWatcher != null)
|
if (mpWatcher != null)
|
||||||
{
|
{
|
||||||
mpWatcher.pauseWatcher();
|
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();
|
mpWatcher.resumeWatcher();
|
||||||
}
|
}
|
||||||
|
|
||||||
m_persistenceDirectory = sNewDirectory;
|
m_persistenceDirectory = sNewDirectory;
|
||||||
|
ChangeFileOwnershipForMiCasaFiles(m_persistenceDirectory);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1097,7 +1158,7 @@ namespace sscs.cache
|
|||||||
// encrypt if an encryptionstring was passed
|
// encrypt if an encryptionstring was passed
|
||||||
if ((sEncryptionString != null) && (sEncryptionString.Length > 0))
|
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.
|
// now encypt it.
|
||||||
baSecrets = sscs.crypto.CASACrypto.EncryptData(baSecrets, baKey, ref baIV);
|
baSecrets = sscs.crypto.CASACrypto.EncryptData(baSecrets, baKey, ref baIV);
|
||||||
@ -1115,7 +1176,7 @@ namespace sscs.cache
|
|||||||
if (sEncryptionString != null)
|
if (sEncryptionString != null)
|
||||||
{
|
{
|
||||||
// decrypt the buffer using the string passed in.
|
// 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);
|
byte[] baBuffer = sscs.crypto.CASACrypto.DecryptData(encryptedXmlSecrets, baKey, baIV);
|
||||||
MergeXMLSecrets(baBuffer);
|
MergeXMLSecrets(baBuffer);
|
||||||
}
|
}
|
||||||
@ -1127,14 +1188,14 @@ namespace sscs.cache
|
|||||||
String sXMLData = Encoding.ASCII.GetString(decryptedXmlSecrets);
|
String sXMLData = Encoding.ASCII.GetString(decryptedXmlSecrets);
|
||||||
doc.LoadXml(sXMLData);
|
doc.LoadXml(sXMLData);
|
||||||
LocalStorage.AddXMLSecretsToStore(this, doc);
|
LocalStorage.AddXMLSecretsToStore(this, doc);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ReEncryptPasscodeUsingRandomSalt(byte[] baPasscode, string sPassword, string sFilepath)
|
private void ReEncryptPasscodeUsingRandomSalt(byte[] baPasscode, string sPassword, string sFilepath)
|
||||||
{
|
{
|
||||||
if (!File.Exists(sFilepath + ".salt"))
|
if (!File.Exists(sFilepath + ".salt"))
|
||||||
{
|
{
|
||||||
CASACrypto.EncryptAndStoreMasterPasscodeUsingString(baPasscode, sPassword, sFilepath);
|
CASACrypto.EncryptAndStoreMasterPasscodeUsingString(baPasscode, sPassword, sFilepath, user.UserIdentifier);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void CreatePolicyDirectory()
|
internal void CreatePolicyDirectory()
|
||||||
|
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;
|
using System.Security.Cryptography;
|
||||||
#if LINUX
|
#if LINUX
|
||||||
using Mono.Unix;
|
using Mono.Unix;
|
||||||
|
using Mono.Unix.Native;
|
||||||
#endif
|
#endif
|
||||||
using sscs.common;
|
using sscs.common;
|
||||||
using sscs.constants;
|
using sscs.constants;
|
||||||
@ -40,12 +41,12 @@ namespace sscs.crypto
|
|||||||
private const int HASH_SIZE = 32;
|
private const int HASH_SIZE = 32;
|
||||||
private const uint MAX_FILE_SIZE = 16 * 1024 * 1024; //16 MB
|
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
|
byte[] baKey = new byte[16]; //return value
|
||||||
try
|
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);
|
baKey = pkcs5.GetBytes(16);
|
||||||
}
|
}
|
||||||
catch(Exception e)
|
catch(Exception e)
|
||||||
@ -58,7 +59,7 @@ namespace sscs.crypto
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal static bool StoreKeySetUsingMasterPasscode(byte[] key,
|
internal static bool StoreKeySetUsingMasterPasscode(byte[] key,
|
||||||
byte[] IV, byte[] baMasterPasscode, string fileName)
|
byte[] IV, byte[] baMasterPasscode, string fileName, UserIdentifier userID)
|
||||||
{
|
{
|
||||||
bool bRet = false;
|
bool bRet = false;
|
||||||
FileStream fsEncrypt = null;
|
FileStream fsEncrypt = null;
|
||||||
@ -69,7 +70,7 @@ namespace sscs.crypto
|
|||||||
//Get an encryptor.
|
//Get an encryptor.
|
||||||
RijndaelManaged myRijndael = new RijndaelManaged();
|
RijndaelManaged myRijndael = new RijndaelManaged();
|
||||||
ICryptoTransform encryptor;
|
ICryptoTransform encryptor;
|
||||||
encryptor = myRijndael.CreateEncryptor(baMasterPasscode, GenerateAndSaveIV(fileName, myRijndael));
|
encryptor = myRijndael.CreateEncryptor(baMasterPasscode, GenerateAndSaveIV(fileName, myRijndael, userID));
|
||||||
|
|
||||||
//Encrypt the data to a file
|
//Encrypt the data to a file
|
||||||
fsEncrypt = new FileStream(fileName, FileMode.Create);
|
fsEncrypt = new FileStream(fileName, FileMode.Create);
|
||||||
@ -88,6 +89,15 @@ namespace sscs.crypto
|
|||||||
//Write all data to the crypto stream and flush it.
|
//Write all data to the crypto stream and flush it.
|
||||||
csEncrypt.Write(key, 0, key.Length);
|
csEncrypt.Write(key, 0, key.Length);
|
||||||
csEncrypt.FlushFinalBlock();
|
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;
|
bRet = true;
|
||||||
}
|
}
|
||||||
catch(Exception e)
|
catch(Exception e)
|
||||||
@ -100,11 +110,12 @@ namespace sscs.crypto
|
|||||||
csEncrypt.Close();
|
csEncrypt.Close();
|
||||||
if( fsEncrypt != null )
|
if( fsEncrypt != null )
|
||||||
fsEncrypt.Close();
|
fsEncrypt.Close();
|
||||||
|
|
||||||
return bRet;
|
return bRet;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static byte[] GetKeySetFromFile(byte[] baMasterPasscode,
|
internal static byte[] GetKeySetFromFile(byte[] baMasterPasscode,
|
||||||
string fileName )
|
string fileName, UserIdentifier userID )
|
||||||
{
|
{
|
||||||
byte[] baSavedKey = null;
|
byte[] baSavedKey = null;
|
||||||
FileStream fsDecrypt = null;
|
FileStream fsDecrypt = null;
|
||||||
@ -114,7 +125,7 @@ namespace sscs.crypto
|
|||||||
{
|
{
|
||||||
#if LINUX
|
#if LINUX
|
||||||
UnixFileInfo fsTest = new UnixFileInfo (fileName);
|
UnixFileInfo fsTest = new UnixFileInfo (fileName);
|
||||||
if((fsTest == null) || !(fsTest.Exists) || fsTest.IsSymbolicLink)
|
if((fsTest == null) || !(fsTest.Exists) || fsTest.IsSymbolicLink || !CSSSUtils.CompareSocketAndFileUserIds(fileName, userID))
|
||||||
#else
|
#else
|
||||||
if(!File.Exists(fileName))
|
if(!File.Exists(fileName))
|
||||||
#endif
|
#endif
|
||||||
@ -127,7 +138,7 @@ namespace sscs.crypto
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
RijndaelManaged myRijndael = new RijndaelManaged();
|
RijndaelManaged myRijndael = new RijndaelManaged();
|
||||||
ICryptoTransform decryptor = myRijndael.CreateDecryptor(baMasterPasscode, RetrieveIV(fileName, baMasterPasscode));
|
ICryptoTransform decryptor = myRijndael.CreateDecryptor(baMasterPasscode, RetrieveIV(fileName, baMasterPasscode, userID));
|
||||||
//Now decrypt
|
//Now decrypt
|
||||||
fsDecrypt = new FileStream(fileName, FileMode.Open);
|
fsDecrypt = new FileStream(fileName, FileMode.Open);
|
||||||
|
|
||||||
@ -181,7 +192,7 @@ namespace sscs.crypto
|
|||||||
{
|
{
|
||||||
//Get an decryptor.
|
//Get an decryptor.
|
||||||
RijndaelManaged myRijndael = new RijndaelManaged();
|
RijndaelManaged myRijndael = new RijndaelManaged();
|
||||||
ICryptoTransform decryptor = myRijndael.CreateDecryptor(key, baIV);
|
ICryptoTransform decryptor = myRijndael.CreateDecryptor(key, baIV);
|
||||||
csDecrypt = new CryptoStream(ms, decryptor, CryptoStreamMode.Read);
|
csDecrypt = new CryptoStream(ms, decryptor, CryptoStreamMode.Read);
|
||||||
|
|
||||||
//Read all data to the crypto stream and flush it.
|
//Read all data to the crypto stream and flush it.
|
||||||
@ -233,7 +244,7 @@ namespace sscs.crypto
|
|||||||
|
|
||||||
|
|
||||||
internal static void EncryptDataAndWriteToFile(byte[] xmlData,
|
internal static void EncryptDataAndWriteToFile(byte[] xmlData,
|
||||||
byte[] key, string fileName)
|
byte[] key, string fileName, UserIdentifier userID)
|
||||||
{
|
{
|
||||||
FileStream fsEncrypt = null;
|
FileStream fsEncrypt = null;
|
||||||
CryptoStream csEncrypt = null;
|
CryptoStream csEncrypt = null;
|
||||||
@ -241,7 +252,7 @@ namespace sscs.crypto
|
|||||||
{
|
{
|
||||||
//Get an encryptor.
|
//Get an encryptor.
|
||||||
RijndaelManaged myRijndael = new RijndaelManaged();
|
RijndaelManaged myRijndael = new RijndaelManaged();
|
||||||
byte[] baIV = GenerateAndSaveIV(fileName, myRijndael);
|
byte[] baIV = GenerateAndSaveIV(fileName, myRijndael, userID);
|
||||||
|
|
||||||
|
|
||||||
ICryptoTransform encryptor = myRijndael.CreateEncryptor(key, baIV);
|
ICryptoTransform encryptor = myRijndael.CreateEncryptor(key, baIV);
|
||||||
@ -249,8 +260,8 @@ namespace sscs.crypto
|
|||||||
//Encrypt the data to a file
|
//Encrypt the data to a file
|
||||||
fsEncrypt = new FileStream(fileName, FileMode.Create);
|
fsEncrypt = new FileStream(fileName, FileMode.Create);
|
||||||
|
|
||||||
// make hidden
|
// make hidden
|
||||||
File.SetAttributes(fileName, FileAttributes.Hidden);
|
File.SetAttributes(fileName, FileAttributes.Hidden);
|
||||||
|
|
||||||
SHA256 sha = new SHA256Managed();
|
SHA256 sha = new SHA256Managed();
|
||||||
|
|
||||||
@ -266,15 +277,21 @@ namespace sscs.crypto
|
|||||||
fsClear.Write(dup, 0, dup.Length);
|
fsClear.Write(dup, 0, dup.Length);
|
||||||
fsClear.Flush();
|
fsClear.Flush();
|
||||||
fsClear.Close();
|
fsClear.Close();
|
||||||
|
CSSSUtils.SetSocketUserAsOwner(fileName + ".xml", userID);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
csEncrypt = new CryptoStream(fsEncrypt, encryptor, CryptoStreamMode.Write);
|
csEncrypt = new CryptoStream(fsEncrypt, encryptor, CryptoStreamMode.Write);
|
||||||
|
|
||||||
//Write all data to the crypto stream and flush it.
|
//Write all data to the crypto stream and flush it.
|
||||||
csEncrypt.Write(xmlData, 0, xmlData.Length);
|
csEncrypt.Write(xmlData, 0, xmlData.Length);
|
||||||
csEncrypt.FlushFinalBlock();
|
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)
|
catch(Exception e)
|
||||||
{
|
{
|
||||||
@ -287,7 +304,7 @@ namespace sscs.crypto
|
|||||||
fsEncrypt.Close();
|
fsEncrypt.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void ComputeHashAndWriteToFile(byte[] baPasscode, string fileName)
|
internal static void ComputeHashAndWriteToFile(byte[] baPasscode, string fileName, UserIdentifier userID)
|
||||||
{
|
{
|
||||||
|
|
||||||
FileStream fsHash = null;
|
FileStream fsHash = null;
|
||||||
@ -295,14 +312,21 @@ namespace sscs.crypto
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
SHA256 shaM = new SHA256Managed();
|
SHA256 shaM = new SHA256Managed();
|
||||||
hash = shaM.ComputeHash(baPasscode);
|
hash = shaM.ComputeHash(baPasscode);
|
||||||
|
|
||||||
fsHash = new FileStream(fileName, FileMode.Create);
|
fsHash = new FileStream(fileName, FileMode.Create);
|
||||||
File.SetAttributes(fileName, FileAttributes.Hidden);
|
File.SetAttributes(fileName, FileAttributes.Hidden);
|
||||||
|
|
||||||
fsHash.Write(hash, 0, hash.Length);
|
fsHash.Write(hash, 0, hash.Length);
|
||||||
fsHash.Flush();
|
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)
|
catch(Exception e)
|
||||||
{
|
{
|
||||||
@ -315,7 +339,7 @@ namespace sscs.crypto
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal static byte[] ReadFileAndDecryptData(byte[] key,
|
internal static byte[] ReadFileAndDecryptData(byte[] key,
|
||||||
string fileName)
|
string fileName, UserIdentifier userID)
|
||||||
{
|
{
|
||||||
FileStream fsDecrypt = null;
|
FileStream fsDecrypt = null;
|
||||||
CryptoStream csDecrypt = null;
|
CryptoStream csDecrypt = null;
|
||||||
@ -328,16 +352,16 @@ namespace sscs.crypto
|
|||||||
//Get a decryptor that uses the same key and IV as the encryptor.
|
//Get a decryptor that uses the same key and IV as the encryptor.
|
||||||
RijndaelManaged myRijndael = new RijndaelManaged();
|
RijndaelManaged myRijndael = new RijndaelManaged();
|
||||||
|
|
||||||
byte[] baIV = RetrieveIV(fileName, IV);
|
byte[] baIV = RetrieveIV(fileName, IV, userID);
|
||||||
|
|
||||||
ICryptoTransform decryptor = myRijndael.CreateDecryptor(key, baIV);
|
ICryptoTransform decryptor = myRijndael.CreateDecryptor(key, baIV);
|
||||||
#if LINUX
|
#if LINUX
|
||||||
UnixFileInfo fsTest = new UnixFileInfo (fileName);
|
UnixFileInfo fsTest = new UnixFileInfo (fileName);
|
||||||
if((fsTest == null) || !(fsTest.Exists) || fsTest.IsSymbolicLink)
|
if((fsTest == null) || !(fsTest.Exists) || fsTest.IsSymbolicLink || !CSSSUtils.CompareSocketAndFileUserIds(fileName, userID))
|
||||||
#else
|
#else
|
||||||
if(!File.Exists(fileName))
|
if(!File.Exists(fileName))
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -347,23 +371,23 @@ namespace sscs.crypto
|
|||||||
fsDecrypt.Read(storedHash,0,storedHash.Length);
|
fsDecrypt.Read(storedHash,0,storedHash.Length);
|
||||||
|
|
||||||
csDecrypt = new CryptoStream(fsDecrypt, decryptor, CryptoStreamMode.Read);
|
csDecrypt = new CryptoStream(fsDecrypt, decryptor, CryptoStreamMode.Read);
|
||||||
if(fsDecrypt.Length < HASH_SIZE )
|
if(fsDecrypt.Length < HASH_SIZE )
|
||||||
{
|
{
|
||||||
csDecrypt.Close();
|
csDecrypt.Close();
|
||||||
fsDecrypt.Close();
|
fsDecrypt.Close();
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(fsDecrypt.Length > MAX_FILE_SIZE )
|
if(fsDecrypt.Length > MAX_FILE_SIZE )
|
||||||
{
|
{
|
||||||
CSSSLogger.DbgLog("Size of the secret file exceeded the maximum allowed.");
|
CSSSLogger.DbgLog("Size of the secret file exceeded the maximum allowed.");
|
||||||
csDecrypt.Close();
|
csDecrypt.Close();
|
||||||
fsDecrypt.Close();
|
fsDecrypt.Close();
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
ulong fileLen = (ulong)(fsDecrypt.Length - HASH_SIZE);
|
ulong fileLen = (ulong)(fsDecrypt.Length - HASH_SIZE);
|
||||||
byte[] fromEncrypt = new byte[fileLen];
|
byte[] fromEncrypt = new byte[fileLen];
|
||||||
|
|
||||||
//Read the data out of the crypto stream.
|
//Read the data out of the crypto stream.
|
||||||
int bytesRead = csDecrypt.Read(fromEncrypt, 0, fromEncrypt.Length);
|
int bytesRead = csDecrypt.Read(fromEncrypt, 0, fromEncrypt.Length);
|
||||||
@ -407,24 +431,24 @@ namespace sscs.crypto
|
|||||||
|
|
||||||
if (csDecrypt != null)
|
if (csDecrypt != null)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
csDecrypt.Close();
|
csDecrypt.Close();
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( fsDecrypt != null )
|
if( fsDecrypt != null )
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
fsDecrypt.Close();
|
fsDecrypt.Close();
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -508,9 +532,9 @@ namespace sscs.crypto
|
|||||||
return (File.Exists(fileName));
|
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;
|
return mp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -523,24 +547,25 @@ namespace sscs.crypto
|
|||||||
internal static void EncryptAndStoreMasterPasscodeUsingString(
|
internal static void EncryptAndStoreMasterPasscodeUsingString(
|
||||||
byte[] baMasterPasscode,
|
byte[] baMasterPasscode,
|
||||||
string passwd,
|
string passwd,
|
||||||
string fileName)
|
string fileName,
|
||||||
|
UserIdentifier userID)
|
||||||
{
|
{
|
||||||
FileStream fsEncrypt = null;
|
FileStream fsEncrypt = null;
|
||||||
CryptoStream csEncrypt = null;
|
CryptoStream csEncrypt = null;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if(File.Exists(fileName))
|
if(File.Exists(fileName))
|
||||||
File.Delete(fileName);
|
File.Delete(fileName);
|
||||||
|
|
||||||
byte[] baKey = Generate16ByteKeyFromString(passwd, fileName, false, true);
|
byte[] baKey = Generate16ByteKeyFromString(passwd, fileName, false, true, userID);
|
||||||
|
|
||||||
//Get an encryptor.
|
//Get an encryptor.
|
||||||
RijndaelManaged myRijndael = new RijndaelManaged();
|
RijndaelManaged myRijndael = new RijndaelManaged();
|
||||||
ICryptoTransform encryptor;
|
ICryptoTransform encryptor;
|
||||||
|
|
||||||
encryptor = myRijndael.CreateEncryptor(baKey, GenerateAndSaveIV(fileName, myRijndael));
|
encryptor = myRijndael.CreateEncryptor(baKey, GenerateAndSaveIV(fileName, myRijndael, userID));
|
||||||
|
|
||||||
//Encrypt the data to a file
|
//Encrypt the data to a file
|
||||||
fsEncrypt = new FileStream(fileName,FileMode.Create);
|
fsEncrypt = new FileStream(fileName,FileMode.Create);
|
||||||
|
|
||||||
csEncrypt = new CryptoStream(fsEncrypt, encryptor,
|
csEncrypt = new CryptoStream(fsEncrypt, encryptor,
|
||||||
@ -552,9 +577,13 @@ namespace sscs.crypto
|
|||||||
csEncrypt.Close();
|
csEncrypt.Close();
|
||||||
fsEncrypt.Close();
|
fsEncrypt.Close();
|
||||||
|
|
||||||
// make hidden
|
// make hidden
|
||||||
File.SetAttributes(fileName, FileAttributes.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)
|
catch(Exception e)
|
||||||
{
|
{
|
||||||
@ -568,11 +597,10 @@ namespace sscs.crypto
|
|||||||
{
|
{
|
||||||
fsEncrypt.Close();
|
fsEncrypt.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static byte[] DecryptMasterPasscodeUsingString(string passwd,
|
public static byte[] DecryptMasterPasscodeUsingString(string passwd,
|
||||||
string fileName, bool bTryOldMethod)
|
string fileName, bool bTryOldMethod, UserIdentifier userID)
|
||||||
{
|
{
|
||||||
FileStream fsDecrypt = null;
|
FileStream fsDecrypt = null;
|
||||||
CryptoStream csDecrypt = null;
|
CryptoStream csDecrypt = null;
|
||||||
@ -580,27 +608,26 @@ namespace sscs.crypto
|
|||||||
|
|
||||||
try
|
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
|
/* Get a decryptor that uses the same key and
|
||||||
* IV as the encryptor.
|
* IV as the encryptor.
|
||||||
*/
|
*/
|
||||||
RijndaelManaged myRijndael = new RijndaelManaged();
|
RijndaelManaged myRijndael = new RijndaelManaged();
|
||||||
ICryptoTransform decryptor = myRijndael.CreateDecryptor(baKey, RetrieveIV(fileName, baKey));
|
ICryptoTransform decryptor = myRijndael.CreateDecryptor(baKey, RetrieveIV(fileName, baKey, userID));
|
||||||
//Now decrypt
|
//Now decrypt
|
||||||
#if LINUX
|
#if LINUX
|
||||||
UnixFileInfo fsTest = new UnixFileInfo (fileName);
|
UnixFileInfo fsTest = new UnixFileInfo (fileName);
|
||||||
if((fsTest == null) || !(fsTest.Exists) || fsTest.IsSymbolicLink)
|
if((fsTest == null) || !(fsTest.Exists) || fsTest.IsSymbolicLink || !CSSSUtils.CompareSocketAndFileUserIds(fileName, userID))
|
||||||
#else
|
#else
|
||||||
if (!File.Exists(fileName))
|
if (!File.Exists(fileName))
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
fsDecrypt = new FileStream(fileName, FileMode.Open);
|
fsDecrypt = new FileStream(fileName, FileMode.Open);
|
||||||
csDecrypt = new CryptoStream(fsDecrypt, decryptor,
|
csDecrypt = new CryptoStream(fsDecrypt, decryptor, CryptoStreamMode.Read);
|
||||||
CryptoStreamMode.Read);
|
|
||||||
baSavedMasterPasscode = new byte[16];
|
baSavedMasterPasscode = new byte[16];
|
||||||
|
|
||||||
//Read the data out of the crypto stream.
|
//Read the data out of the crypto stream.
|
||||||
@ -633,7 +660,8 @@ namespace sscs.crypto
|
|||||||
internal static byte[] GetMasterPasscodeUsingMasterPasswd(
|
internal static byte[] GetMasterPasscodeUsingMasterPasswd(
|
||||||
string mPasswd,
|
string mPasswd,
|
||||||
string fileName,
|
string fileName,
|
||||||
bool bUseOldMethod)
|
bool bUseOldMethod,
|
||||||
|
UserIdentifier userID)
|
||||||
{
|
{
|
||||||
byte[] baMasterPasscode;
|
byte[] baMasterPasscode;
|
||||||
try
|
try
|
||||||
@ -643,7 +671,7 @@ namespace sscs.crypto
|
|||||||
/* Decrypt the passcode from the file using master passwd.
|
/* Decrypt the passcode from the file using master passwd.
|
||||||
* and return the decrypted passcode.
|
* and return the decrypted passcode.
|
||||||
*/
|
*/
|
||||||
baMasterPasscode = DecryptMasterPasscodeUsingString(mPasswd, fileName, bUseOldMethod);
|
baMasterPasscode = DecryptMasterPasscodeUsingString(mPasswd, fileName, bUseOldMethod, userID);
|
||||||
return baMasterPasscode;
|
return baMasterPasscode;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -660,7 +688,8 @@ namespace sscs.crypto
|
|||||||
internal static byte[] GetMasterPasscodeUsingDesktopPasswd(
|
internal static byte[] GetMasterPasscodeUsingDesktopPasswd(
|
||||||
string desktopPasswd,
|
string desktopPasswd,
|
||||||
string fileName,
|
string fileName,
|
||||||
bool bUseOldMethod)
|
bool bUseOldMethod,
|
||||||
|
UserIdentifier userID)
|
||||||
{
|
{
|
||||||
byte[] passcode;
|
byte[] passcode;
|
||||||
try
|
try
|
||||||
@ -671,7 +700,7 @@ namespace sscs.crypto
|
|||||||
* and return the decrypted passcode.
|
* and return the decrypted passcode.
|
||||||
*/
|
*/
|
||||||
passcode = DecryptMasterPasscodeUsingString(desktopPasswd,
|
passcode = DecryptMasterPasscodeUsingString(desktopPasswd,
|
||||||
fileName, bUseOldMethod);
|
fileName, bUseOldMethod, userID);
|
||||||
return passcode;
|
return passcode;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -689,12 +718,13 @@ namespace sscs.crypto
|
|||||||
internal static byte[] GetServerMasterPasscodeUsingMasterPasswd(
|
internal static byte[] GetServerMasterPasscodeUsingMasterPasswd(
|
||||||
string mPasswd,
|
string mPasswd,
|
||||||
string fileName,
|
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;
|
byte[] baSavedMasterPasscode = null;
|
||||||
|
|
||||||
@ -702,7 +732,7 @@ namespace sscs.crypto
|
|||||||
{
|
{
|
||||||
#if LINUX
|
#if LINUX
|
||||||
UnixFileInfo fsTest = new UnixFileInfo (fileName);
|
UnixFileInfo fsTest = new UnixFileInfo (fileName);
|
||||||
if((fsTest == null) || !(fsTest.Exists) || fsTest.IsSymbolicLink)
|
if((fsTest == null) || !(fsTest.Exists) || fsTest.IsSymbolicLink || !CSSSUtils.CompareSocketAndFileUserIds(fileName, userID))
|
||||||
#else
|
#else
|
||||||
if (!File.Exists(fileName))
|
if (!File.Exists(fileName))
|
||||||
#endif
|
#endif
|
||||||
@ -716,7 +746,7 @@ namespace sscs.crypto
|
|||||||
fs.Close();
|
fs.Close();
|
||||||
|
|
||||||
baSavedMasterPasscode = new byte[16];
|
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)
|
catch (CryptographicException e)
|
||||||
{
|
{
|
||||||
@ -732,7 +762,7 @@ namespace sscs.crypto
|
|||||||
string desktopPasswd,
|
string desktopPasswd,
|
||||||
string fileName,
|
string fileName,
|
||||||
string validationFile,
|
string validationFile,
|
||||||
UserIdentifier userId
|
UserIdentifier userID
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@ -747,9 +777,9 @@ namespace sscs.crypto
|
|||||||
|
|
||||||
EncryptAndStoreMasterPasscodeUsingString(baPasscode,
|
EncryptAndStoreMasterPasscodeUsingString(baPasscode,
|
||||||
desktopPasswd,
|
desktopPasswd,
|
||||||
fileName);
|
fileName,
|
||||||
|
userID);
|
||||||
ComputeHashAndWriteToFile(baPasscode, validationFile + "Hash"); //Hash of MPC is written to ".miCASAValidateHash" file
|
ComputeHashAndWriteToFile(baPasscode, validationFile + "Hash", userID); //Hash of MPC is written to ".miCASAValidateHash" file
|
||||||
return baPasscode;
|
return baPasscode;
|
||||||
}
|
}
|
||||||
catch(Exception e)
|
catch(Exception e)
|
||||||
@ -762,7 +792,8 @@ namespace sscs.crypto
|
|||||||
|
|
||||||
internal static byte[] GenerateServerMasterPasscode(
|
internal static byte[] GenerateServerMasterPasscode(
|
||||||
string fileName,
|
string fileName,
|
||||||
string validationFile
|
string validationFile,
|
||||||
|
UserIdentifier userID
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
byte[] baPasscode = null;
|
byte[] baPasscode = null;
|
||||||
@ -775,14 +806,18 @@ namespace sscs.crypto
|
|||||||
myRijndael.GenerateKey();
|
myRijndael.GenerateKey();
|
||||||
baPasscode = myRijndael.Key;
|
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);
|
FileStream fs = new FileStream(fileName, FileMode.Create);
|
||||||
File.SetAttributes(fileName, FileAttributes.Hidden);
|
File.SetAttributes(fileName, FileAttributes.Hidden);
|
||||||
fs.Write(encryptedMasterPasscode, 0, encryptedMasterPasscode.Length);
|
fs.Write(encryptedMasterPasscode, 0, encryptedMasterPasscode.Length);
|
||||||
fs.Flush();
|
fs.Flush();
|
||||||
fs.Close();
|
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)
|
catch(Exception e)
|
||||||
@ -794,14 +829,14 @@ namespace sscs.crypto
|
|||||||
return baPasscode;
|
return baPasscode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool CompareHashes(byte[] baPasscode, string fileName)
|
public static bool CompareHashes(byte[] baPasscode, string fileName, UserIdentifier userID)
|
||||||
{
|
{
|
||||||
FileStream fsHash = null;
|
FileStream fsHash = null;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
#if LINUX
|
#if LINUX
|
||||||
UnixFileInfo fsTest = new UnixFileInfo (fileName);
|
UnixFileInfo fsTest = new UnixFileInfo (fileName);
|
||||||
if((fsTest == null) || !(fsTest.Exists) || fsTest.IsSymbolicLink)
|
if((fsTest == null) || !(fsTest.Exists) || fsTest.IsSymbolicLink || !CSSSUtils.CompareSocketAndFileUserIds(fileName, userID))
|
||||||
#else
|
#else
|
||||||
if (!File.Exists(fileName))
|
if (!File.Exists(fileName))
|
||||||
#endif
|
#endif
|
||||||
@ -840,7 +875,7 @@ namespace sscs.crypto
|
|||||||
return false;
|
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
|
/* Here we decrpyt a well known string, throw exception
|
||||||
* if not successful
|
* if not successful
|
||||||
@ -854,7 +889,7 @@ namespace sscs.crypto
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if(CompareHashes(baPasscode, fileName + "Hash"))
|
if(CompareHashes(baPasscode, fileName + "Hash", userID))
|
||||||
{
|
{
|
||||||
CSSSLogger.DbgLog("Using the hash of MPC for validating the MPC");
|
CSSSLogger.DbgLog("Using the hash of MPC for validating the MPC");
|
||||||
return true;
|
return true;
|
||||||
@ -862,7 +897,7 @@ namespace sscs.crypto
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
CSSSLogger.DbgLog("Using the validation string encrypted with MPC for validating the MPC");
|
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);
|
string sString = Encoding.Default.GetString(baString);
|
||||||
char[] trimChars = {'\0'};
|
char[] trimChars = {'\0'};
|
||||||
sString = sString.TrimEnd(trimChars);
|
sString = sString.TrimEnd(trimChars);
|
||||||
@ -880,27 +915,27 @@ namespace sscs.crypto
|
|||||||
}
|
}
|
||||||
catch(Exception e)
|
catch(Exception e)
|
||||||
{
|
{
|
||||||
CSSSLogger.ExpLog(e.ToString());
|
CSSSLogger.ExpLog(e.ToString());
|
||||||
CSSSLogger.DbgLog("Validation of passcode failed.");
|
CSSSLogger.DbgLog("Validation of passcode failed.");
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static byte[] GenerateAndSaveIV(string sFileName, RijndaelManaged theRiManaged)
|
private static byte[] GenerateAndSaveIV(string sFileName, RijndaelManaged theRiManaged, UserIdentifier userID)
|
||||||
{
|
{
|
||||||
byte[] baIV = null;
|
byte[] baIV = null;
|
||||||
if ( theRiManaged != null )
|
if ( theRiManaged != null )
|
||||||
{
|
{
|
||||||
theRiManaged.GenerateIV();
|
theRiManaged.GenerateIV();
|
||||||
baIV = theRiManaged.IV;
|
baIV = theRiManaged.IV;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
RandomNumberGenerator rng = RandomNumberGenerator.Create ();
|
RandomNumberGenerator rng = RandomNumberGenerator.Create ();
|
||||||
baIV = new byte [16];
|
baIV = new byte [16];
|
||||||
rng.GetBytes (baIV);
|
rng.GetBytes (baIV);
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -911,6 +946,11 @@ namespace sscs.crypto
|
|||||||
fs.Close();
|
fs.Close();
|
||||||
|
|
||||||
File.SetAttributes(sFileName + ".IV", FileAttributes.Hidden);
|
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)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
@ -920,13 +960,23 @@ namespace sscs.crypto
|
|||||||
return baIV;
|
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];
|
byte[] IV = new byte[16];
|
||||||
// check for file existence
|
// check for file existence
|
||||||
try
|
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);
|
FileStream fs = new FileStream(sFileName + ".IV", FileMode.Open);
|
||||||
fs.Read(IV, 0, 16);
|
fs.Read(IV, 0, 16);
|
||||||
fs.Close();
|
fs.Close();
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -20,312 +20,326 @@
|
|||||||
*
|
*
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
|
|
||||||
//
|
//
|
||||||
// Rfc2898DeriveBytes.cs: RFC2898 (PKCS#5 v2) Key derivation for Password Based Encryption
|
// Rfc2898DeriveBytes.cs: RFC2898 (PKCS#5 v2) Key derivation for Password Based Encryption
|
||||||
//
|
//
|
||||||
// Author:
|
// Author:
|
||||||
// Sebastien Pouliot (sebastien@ximian.com)
|
// Sebastien Pouliot (sebastien@ximian.com)
|
||||||
//
|
//
|
||||||
// (C) 2003 Motus Technologies Inc. (http://www.motus.com)
|
// (C) 2003 Motus Technologies Inc. (http://www.motus.com)
|
||||||
// Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
|
// Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
|
||||||
//
|
//
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining
|
// Permission is hereby granted, free of charge, to any person obtaining
|
||||||
// a copy of this software and associated documentation files (the
|
// a copy of this software and associated documentation files (the
|
||||||
// "Software"), to deal in the Software without restriction, including
|
// "Software"), to deal in the Software without restriction, including
|
||||||
// without limitation the rights to use, copy, modify, merge, publish,
|
// without limitation the rights to use, copy, modify, merge, publish,
|
||||||
// distribute, sublicense, and/or sell copies of the Software, and to
|
// distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
// permit persons to whom the Software is furnished to do so, subject to
|
// permit persons to whom the Software is furnished to do so, subject to
|
||||||
// the following conditions:
|
// the following conditions:
|
||||||
//
|
//
|
||||||
// The above copyright notice and this permission notice shall be
|
// The above copyright notice and this permission notice shall be
|
||||||
// included in all copies or substantial portions of the Software.
|
// included in all copies or substantial portions of the Software.
|
||||||
//
|
//
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//using System.Runtime.InteropServices;
|
//using System.Runtime.InteropServices;
|
||||||
using System;
|
using System;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
|
|
||||||
using sscs.lss;
|
using sscs.lss;
|
||||||
using sscs.common;
|
using sscs.common;
|
||||||
|
|
||||||
namespace sscs.crypto {
|
namespace sscs.crypto {
|
||||||
|
|
||||||
//[ComVisible (true)]
|
//[ComVisible (true)]
|
||||||
public class Rfc2898DeriveBytes : DeriveBytes {
|
public class Rfc2898DeriveBytes : DeriveBytes {
|
||||||
|
|
||||||
private const int defaultIterations = 1000;
|
private const int defaultIterations = 1000;
|
||||||
|
|
||||||
private int _iteration;
|
private int _iteration;
|
||||||
private byte[] _salt;
|
private byte[] _salt;
|
||||||
private HMACSHA1 _hmac;
|
private HMACSHA1 _hmac;
|
||||||
private byte[] _buffer;
|
private byte[] _buffer;
|
||||||
private int _pos;
|
private int _pos;
|
||||||
private int _f;
|
private int _f;
|
||||||
|
|
||||||
// constructors
|
// constructors
|
||||||
|
|
||||||
public Rfc2898DeriveBytes (string password, byte[] salt)
|
public Rfc2898DeriveBytes (string password, byte[] salt)
|
||||||
: this (password, salt, defaultIterations)
|
: this (password, salt, defaultIterations)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public Rfc2898DeriveBytes (string password, byte[] salt, int iterations)
|
public Rfc2898DeriveBytes (string password, byte[] salt, int iterations)
|
||||||
{
|
{
|
||||||
if (password == null)
|
if (password == null)
|
||||||
throw new ArgumentNullException ("password");
|
throw new ArgumentNullException ("password");
|
||||||
|
|
||||||
Salt = salt;
|
Salt = salt;
|
||||||
IterationCount = iterations;
|
IterationCount = iterations;
|
||||||
_hmac = new HMACSHA1 (Encoding.UTF8.GetBytes (password));
|
_hmac = new HMACSHA1 (Encoding.UTF8.GetBytes (password));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Rfc2898DeriveBytes (byte[] password, byte[] salt, int iterations)
|
public Rfc2898DeriveBytes (byte[] password, byte[] salt, int iterations)
|
||||||
{
|
{
|
||||||
if (password == null)
|
if (password == null)
|
||||||
throw new ArgumentNullException ("password");
|
throw new ArgumentNullException ("password");
|
||||||
|
|
||||||
Salt = salt;
|
Salt = salt;
|
||||||
IterationCount = iterations;
|
IterationCount = iterations;
|
||||||
_hmac = new HMACSHA1 (password);
|
_hmac = new HMACSHA1 (password);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Rfc2898DeriveBytes (string password, int saltSize)
|
public Rfc2898DeriveBytes (string password, int saltSize)
|
||||||
: this (password, saltSize, defaultIterations)
|
: this (password, saltSize, defaultIterations)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public Rfc2898DeriveBytes(string password, int saltSize, int iterations)
|
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)
|
if (password == null)
|
||||||
throw new ArgumentNullException ("password");
|
throw new ArgumentNullException ("password");
|
||||||
if (saltSize < 0)
|
if (saltSize < 0)
|
||||||
throw new ArgumentOutOfRangeException ("invalid salt length");
|
throw new ArgumentOutOfRangeException ("invalid salt length");
|
||||||
|
|
||||||
if (bUseOldMethod)
|
if (bUseOldMethod)
|
||||||
{
|
{
|
||||||
Salt = GenerateOldSalt(password, saltSize);
|
Salt = GenerateOldSalt(password, saltSize);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (bGenerateAndSaveRandomSalt)
|
if (bGenerateAndSaveRandomSalt)
|
||||||
{
|
{
|
||||||
Salt = GenerateAndSaveRandomSalt(saltSize, sFilepath);
|
Salt = GenerateAndSaveRandomSalt(saltSize, sFilepath, userID);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// load saved salt if one was saved
|
// load saved salt if one was saved
|
||||||
if ((sFilepath != null) && (File.Exists(sFilepath + ".salt")))
|
if ((sFilepath != null) && (File.Exists(sFilepath + ".salt")))
|
||||||
{
|
{
|
||||||
Salt = LoadSavedSalt(sFilepath);
|
Salt = LoadSavedSalt(sFilepath, userID);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Salt = GenerateNewSalt(password, saltSize);
|
Salt = GenerateNewSalt(password, saltSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IterationCount = iterations;
|
IterationCount = iterations;
|
||||||
_hmac = new HMACSHA1 (Encoding.UTF8.GetBytes (password));
|
_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];
|
byte[] randomSalt = new byte[saltSize];
|
||||||
FastRandom fr = new FastRandom();
|
FastRandom fr = new FastRandom();
|
||||||
fr.NextBytes(randomSalt);
|
fr.NextBytes(randomSalt);
|
||||||
|
|
||||||
// save salt
|
// save salt
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
||||||
FileStream fs = new FileStream(sFilepath + ".salt", FileMode.OpenOrCreate);
|
FileStream fs = new FileStream(sFilepath + ".salt", FileMode.OpenOrCreate);
|
||||||
fs.Write(randomSalt, 0, randomSalt.Length);
|
fs.Write(randomSalt, 0, randomSalt.Length);
|
||||||
fs.Flush();
|
fs.Flush();
|
||||||
fs.Close();
|
fs.Close();
|
||||||
|
|
||||||
File.SetAttributes(sFilepath + ".salt", FileAttributes.Hidden);
|
File.SetAttributes(sFilepath + ".salt", FileAttributes.Hidden);
|
||||||
|
|
||||||
}
|
if (!CSSSUtils.SetSocketUserAsOwner(sFilepath + ".salt", userID))
|
||||||
catch (Exception e)
|
{
|
||||||
{
|
CSSSLogger.DbgLog("Unable to set the owner of the file to the socket user");
|
||||||
CSSSLogger.DbgLog(e.ToString());
|
}
|
||||||
}
|
}
|
||||||
|
catch (Exception e)
|
||||||
return randomSalt;
|
{
|
||||||
}
|
CSSSLogger.DbgLog(e.ToString());
|
||||||
|
}
|
||||||
private byte[] LoadSavedSalt(string sFilePath)
|
|
||||||
{
|
return randomSalt;
|
||||||
byte[] baSalt = null;
|
}
|
||||||
|
|
||||||
try
|
private byte[] LoadSavedSalt(string sFilePath, UserIdentifier userID)
|
||||||
{
|
{
|
||||||
FileStream fs = new FileStream(sFilePath + ".salt", FileMode.Open);
|
byte[] baSalt = null;
|
||||||
baSalt = new byte[fs.Length];
|
|
||||||
fs.Read(baSalt, 0, (int)fs.Length);
|
try
|
||||||
fs.Close();
|
{
|
||||||
}
|
#if LINUX
|
||||||
catch (Exception e)
|
Mono.Unix.UnixFileInfo fsTest = new Mono.Unix.UnixFileInfo (sFilePath + ".salt");
|
||||||
{
|
if((fsTest == null) || !(fsTest.Exists) || fsTest.IsSymbolicLink || !CSSSUtils.CompareSocketAndFileUserIds(sFilePath + ".salt", userID))
|
||||||
CSSSLogger.DbgLog(e.ToString());
|
#else
|
||||||
}
|
if (!File.Exists(sFilePath + ".salt"))
|
||||||
return baSalt;
|
#endif
|
||||||
}
|
{
|
||||||
|
return null;
|
||||||
private static byte[] GenerateOldSalt(string password, int saltSize)
|
}
|
||||||
{
|
|
||||||
byte[] buffer = new byte[saltSize];
|
FileStream fs = new FileStream(sFilePath + ".salt", FileMode.Open);
|
||||||
Random rand = new Random(password.GetHashCode());
|
baSalt = new byte[fs.Length];
|
||||||
rand.NextBytes(buffer);
|
fs.Read(baSalt, 0, (int)fs.Length);
|
||||||
return buffer;
|
fs.Close();
|
||||||
}
|
}
|
||||||
|
catch (Exception e)
|
||||||
private static byte[] GenerateNewSalt(string password, int saltSize)
|
{
|
||||||
{
|
CSSSLogger.DbgLog(e.ToString());
|
||||||
int j = 0;
|
}
|
||||||
byte[] buffer = new byte[saltSize];
|
return baSalt;
|
||||||
|
}
|
||||||
// iterate thru each character, creating a new Random,
|
|
||||||
// getting 2 bytes from each, until our salt buffer is full.
|
private static byte[] GenerateOldSalt(string password, int saltSize)
|
||||||
for (int i = 0; i < password.Length;)
|
{
|
||||||
{
|
byte[] buffer = new byte[saltSize];
|
||||||
char letter = password[i];
|
Random rand = new Random(password.GetHashCode());
|
||||||
int iLetter = (int)letter;
|
rand.NextBytes(buffer);
|
||||||
|
return buffer;
|
||||||
FastRandom ranNum = new FastRandom(iLetter * (j+1));
|
}
|
||||||
byte[] temp = new byte[2];
|
|
||||||
ranNum.NextBytes(temp);
|
private static byte[] GenerateNewSalt(string password, int saltSize)
|
||||||
|
{
|
||||||
for (int k = 0; k < temp.Length; k++)
|
int j = 0;
|
||||||
{
|
byte[] buffer = new byte[saltSize];
|
||||||
buffer[j++] = temp[k];
|
|
||||||
// get out if buffer is full
|
// iterate thru each character, creating a new Random,
|
||||||
if (j >= saltSize)
|
// getting 2 bytes from each, until our salt buffer is full.
|
||||||
{
|
for (int i = 0; i < password.Length;)
|
||||||
return buffer;
|
{
|
||||||
}
|
char letter = password[i];
|
||||||
}
|
int iLetter = (int)letter;
|
||||||
|
|
||||||
i++;
|
FastRandom ranNum = new FastRandom(iLetter * (j+1));
|
||||||
|
byte[] temp = new byte[2];
|
||||||
// reset i if at end of password
|
ranNum.NextBytes(temp);
|
||||||
if ((i + 1) > password.Length)
|
|
||||||
{
|
for (int k = 0; k < temp.Length; k++)
|
||||||
i = 0;
|
{
|
||||||
}
|
buffer[j++] = temp[k];
|
||||||
|
// get out if buffer is full
|
||||||
|
if (j >= saltSize)
|
||||||
}
|
{
|
||||||
|
return buffer;
|
||||||
return buffer;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// properties
|
i++;
|
||||||
public int IterationCount
|
|
||||||
{
|
// reset i if at end of password
|
||||||
get { return _iteration; }
|
if ((i + 1) > password.Length)
|
||||||
set {
|
{
|
||||||
if (value < 1)
|
i = 0;
|
||||||
throw new ArgumentOutOfRangeException ("IterationCount < 1");
|
}
|
||||||
|
|
||||||
_iteration = value;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
return buffer;
|
||||||
public byte[] Salt {
|
}
|
||||||
get { return (byte[]) _salt.Clone (); }
|
|
||||||
set {
|
// properties
|
||||||
if (value == null)
|
public int IterationCount
|
||||||
throw new ArgumentNullException ("Salt");
|
{
|
||||||
if (value.Length < 8)
|
get { return _iteration; }
|
||||||
throw new ArgumentException ("Salt < 8 bytes");
|
set {
|
||||||
|
if (value < 1)
|
||||||
_salt = (byte[])value.Clone ();
|
throw new ArgumentOutOfRangeException ("IterationCount < 1");
|
||||||
}
|
|
||||||
}
|
_iteration = value;
|
||||||
|
}
|
||||||
// methods
|
}
|
||||||
|
|
||||||
private byte[] F (byte[] s, int c, int i)
|
public byte[] Salt {
|
||||||
{
|
get { return (byte[]) _salt.Clone (); }
|
||||||
byte[] data = new byte [s.Length + 4];
|
set {
|
||||||
Buffer.BlockCopy (s, 0, data, 0, s.Length);
|
if (value == null)
|
||||||
byte[] int4 = BitConverter.GetBytes (i);
|
throw new ArgumentNullException ("Salt");
|
||||||
Array.Reverse (int4, 0, 4);
|
if (value.Length < 8)
|
||||||
Buffer.BlockCopy (int4, 0, data, s.Length, 4);
|
throw new ArgumentException ("Salt < 8 bytes");
|
||||||
|
|
||||||
// this is like j=0
|
_salt = (byte[])value.Clone ();
|
||||||
byte[] u1 = _hmac.ComputeHash (data);
|
}
|
||||||
data = u1;
|
}
|
||||||
// so we start at j=1
|
|
||||||
for (int j=1; j < c; j++) {
|
// methods
|
||||||
byte[] un = _hmac.ComputeHash (data);
|
|
||||||
// xor
|
private byte[] F (byte[] s, int c, int i)
|
||||||
for (int k=0; k < 20; k++)
|
{
|
||||||
u1 [k] = (byte)(u1 [k] ^ un [k]);
|
byte[] data = new byte [s.Length + 4];
|
||||||
data = un;
|
Buffer.BlockCopy (s, 0, data, 0, s.Length);
|
||||||
}
|
byte[] int4 = BitConverter.GetBytes (i);
|
||||||
return u1;
|
Array.Reverse (int4, 0, 4);
|
||||||
}
|
Buffer.BlockCopy (int4, 0, data, s.Length, 4);
|
||||||
|
|
||||||
public override byte[] GetBytes (int cb)
|
// this is like j=0
|
||||||
{
|
byte[] u1 = _hmac.ComputeHash (data);
|
||||||
if (cb < 1)
|
data = u1;
|
||||||
throw new ArgumentOutOfRangeException ("cb");
|
// so we start at j=1
|
||||||
|
for (int j=1; j < c; j++) {
|
||||||
int l = cb / 20; // HMACSHA1 == 160 bits == 20 bytes
|
byte[] un = _hmac.ComputeHash (data);
|
||||||
int r = cb % 20; // remainder
|
// xor
|
||||||
if (r != 0)
|
for (int k=0; k < 20; k++)
|
||||||
l++; // rounding up
|
u1 [k] = (byte)(u1 [k] ^ un [k]);
|
||||||
|
data = un;
|
||||||
byte[] result = new byte [cb];
|
}
|
||||||
int rpos = 0;
|
return u1;
|
||||||
if (_pos > 0) {
|
}
|
||||||
int count = Math.Min (20 - _pos, cb);
|
|
||||||
Buffer.BlockCopy (_buffer, _pos, result, 0, count);
|
public override byte[] GetBytes (int cb)
|
||||||
if (count >= cb)
|
{
|
||||||
return result;
|
if (cb < 1)
|
||||||
_pos = 0;
|
throw new ArgumentOutOfRangeException ("cb");
|
||||||
rpos = 20 - cb;
|
|
||||||
r = cb - rpos;
|
int l = cb / 20; // HMACSHA1 == 160 bits == 20 bytes
|
||||||
}
|
int r = cb % 20; // remainder
|
||||||
|
if (r != 0)
|
||||||
for (int i=1; i <= l; i++) {
|
l++; // rounding up
|
||||||
_buffer = F (_salt, _iteration, ++_f);
|
|
||||||
int count = ((i == l) ? r : 20);
|
byte[] result = new byte [cb];
|
||||||
Buffer.BlockCopy (_buffer, _pos, result, rpos, count);
|
int rpos = 0;
|
||||||
rpos += _pos + count;
|
if (_pos > 0) {
|
||||||
_pos = ((count == 20) ? 0 : count);
|
int count = Math.Min (20 - _pos, cb);
|
||||||
}
|
Buffer.BlockCopy (_buffer, _pos, result, 0, count);
|
||||||
|
if (count >= cb)
|
||||||
return result;
|
return result;
|
||||||
}
|
_pos = 0;
|
||||||
|
rpos = 20 - cb;
|
||||||
public override void Reset ()
|
r = cb - rpos;
|
||||||
{
|
}
|
||||||
_buffer = null;
|
|
||||||
_pos = 0;
|
for (int i=1; i <= l; i++) {
|
||||||
_f = 0;
|
_buffer = F (_salt, _iteration, ++_f);
|
||||||
}
|
int count = ((i == l) ? r : 20);
|
||||||
}
|
Buffer.BlockCopy (_buffer, _pos, result, rpos, count);
|
||||||
}
|
rpos += _pos + count;
|
||||||
|
_pos = ((count == 20) ? 0 : count);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Reset ()
|
||||||
|
{
|
||||||
|
_buffer = null;
|
||||||
|
_pos = 0;
|
||||||
|
_f = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user