diff --git a/CASA/micasad/Makefile.am b/CASA/micasad/Makefile.am
index 51b9b370..a1052e2f 100644
--- a/CASA/micasad/Makefile.am
+++ b/CASA/micasad/Makefile.am
@@ -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 \
diff --git a/CASA/micasad/cache/MPFileWatcher.cs b/CASA/micasad/cache/MPFileWatcher.cs
index 27573417..2fc04fa4 100644
--- a/CASA/micasad/cache/MPFileWatcher.cs
+++ b/CASA/micasad/cache/MPFileWatcher.cs
@@ -1,169 +1,174 @@
-using System;
-using System.IO;
-
-using sscs.common;
-
-namespace sscs.cache
-{
- ///
- /// Summary description for MPFileWatcher.
- ///
- public class MPFileWatcher
- {
- FileSystemWatcher fwatcher;
- private string m_dir = null;
- private string m_filename = null;
- private byte[] m_baMP = new byte[32];
- private byte[] m_baMPIV = new byte[32];
- private byte[] m_baMPSalt = null;
- private bool m_bIgnoreFileDeletes = false;
-
- public MPFileWatcher(string MPFilePath, string MPFileName)
- {
- m_dir = MPFilePath;
- m_filename = MPFileName;
-
- if ((MPFilePath != null) && (MPFileName != null))
- {
- LogMessage("Starting MPFile watcher on " + MPFilePath + "/" + MPFileName.Substring(1));
- fwatcher = new FileSystemWatcher(MPFilePath);
- fwatcher.Filter = MPFileName.Substring(1)+"*";
- fwatcher.Deleted += new FileSystemEventHandler(fwatcher_Deleted);
- fwatcher.Renamed += new RenamedEventHandler(fwatcher_Renamed);
- fwatcher.Changed += new FileSystemEventHandler(fwatcher_Changed);
- fwatcher.EnableRaisingEvents = true;
- }
-
- if (File.Exists(MPFilePath + MPFileName))
- {
- LoadAndCacheMPFiles();
- }
- }
-
- ~MPFileWatcher()
- {
- if (fwatcher != null)
- fwatcher.EnableRaisingEvents = false;
- fwatcher = null;
- }
- internal void pauseWatcher()
- {
- m_bIgnoreFileDeletes = true;
- }
-
- internal void resumeWatcher()
- {
- m_bIgnoreFileDeletes = false;
- }
-
- private void fwatcher_Deleted(object sender, FileSystemEventArgs e)
- {
- if (!m_bIgnoreFileDeletes)
- {
- LogMessage("MP file deleted");
- ReWriteFiles();
- }
- }
-
- private void fwatcher_Changed(object sender, FileSystemEventArgs e)
- {
- LogMessage("MP file Changed");
- LoadAndCacheMPFiles();
- }
-
- private void fwatcher_Renamed(object sender, RenamedEventArgs e)
- {
- LogMessage("MP file renamed");
- fwatcher_Deleted(sender, e);
- }
-
- private void LoadAndCacheMPFiles()
- {
- LogMessage("Loading and caching MP files");
-
- try
- {
- FileStream fs = new FileStream(m_dir + m_filename, FileMode.Open, FileAccess.Read);
- fs.Read(m_baMP, 0, m_baMP.Length);
- fs.Flush();
- fs.Close();
-
- fs = new FileStream(m_dir + m_filename + ".IV", FileMode.Open, FileAccess.Read);
- fs.Read(m_baMPIV, 0, m_baMPIV.Length);
- fs.Flush();
- fs.Close();
-
- if (File.Exists(m_dir + m_filename + ".salt"))
- {
- m_baMPSalt = new byte[64];
- fs = new FileStream(m_dir + m_filename + ".salt", FileMode.Open, FileAccess.Read);
- fs.Read(m_baMPSalt, 0, m_baMPSalt.Length);
- fs.Flush();
- fs.Close();
- }
-
- }
-
- catch (Exception e)
- {
- LogMessage(e.ToString());
- }
- }
-
- private void ReWriteFiles()
- {
- try
- {
- FileStream fs = new FileStream(m_dir + m_filename, FileMode.Create);
- fs.Write(m_baMP, 0, m_baMP.Length);
- fs.Flush();
- fs.Close();
-
- File.SetAttributes(m_dir + m_filename, FileAttributes.Hidden);
- }
- catch (Exception e)
- {
- LogMessage(e.ToString());
- }
-
- try
- {
- FileStream fs = new FileStream(m_dir + m_filename + ".IV", FileMode.Create);
- fs.Write(m_baMPIV, 0, m_baMPIV.Length);
- fs.Flush();
- fs.Close();
-
- File.SetAttributes(m_dir + m_filename + ".IV", FileAttributes.Hidden);
- }
- catch (Exception e)
- {
- LogMessage(e.ToString());
- }
-
-
- if (m_baMPSalt != null)
- {
- try
- {
- FileStream fs = new FileStream(m_dir + m_filename + ".salt", FileMode.Create);
- fs.Write(m_baMPSalt, 0, m_baMPSalt.Length);
- fs.Flush();
- fs.Close();
-
- File.SetAttributes(m_dir + m_filename + ".salt", FileAttributes.Hidden);
- }
- catch (Exception e)
- {
- LogMessage(e.ToString());
- }
- }
-
- }
-
- private void LogMessage(string message)
- {
-// Console.WriteLine(message);
- CSSSLogger.DbgLog("MPFileWatcher:" + message);
- }
- }
-}
+using System;
+using System.IO;
+
+using sscs.common;
+
+namespace sscs.cache
+{
+ ///
+ /// Summary description for MPFileWatcher.
+ ///
+ class MPFileWatcher
+ {
+ FileSystemWatcher fwatcher;
+ private string m_dir = null;
+ private string m_filename = null;
+ private byte[] m_baMP = new byte[32];
+ private byte[] m_baMPIV = new byte[32];
+ private byte[] m_baMPSalt = null;
+ private bool m_bIgnoreFileDeletes = false;
+ private SecretStore m_store = null;
+
+ public MPFileWatcher(SecretStore store, string MPFilePath, string MPFileName)
+ {
+ m_store = store;
+ m_dir = MPFilePath;
+ m_filename = MPFileName;
+
+ if ((MPFilePath != null) && (MPFileName != null))
+ {
+ LogMessage("Starting MPFile watcher on " + MPFilePath + "/" + MPFileName.Substring(1));
+ fwatcher = new FileSystemWatcher(MPFilePath);
+ fwatcher.Filter = MPFileName.Substring(1)+"*";
+ fwatcher.Deleted += new FileSystemEventHandler(fwatcher_Deleted);
+ fwatcher.Renamed += new RenamedEventHandler(fwatcher_Renamed);
+ fwatcher.Changed += new FileSystemEventHandler(fwatcher_Changed);
+ fwatcher.EnableRaisingEvents = true;
+ }
+
+ if (File.Exists(MPFilePath + MPFileName))
+ {
+ LoadAndCacheMPFiles();
+ }
+ }
+
+ ~MPFileWatcher()
+ {
+ if (fwatcher != null)
+ fwatcher.EnableRaisingEvents = false;
+ fwatcher = null;
+ }
+ internal void pauseWatcher()
+ {
+ m_bIgnoreFileDeletes = true;
+ }
+
+ internal void resumeWatcher()
+ {
+ m_bIgnoreFileDeletes = false;
+ }
+
+ private void fwatcher_Deleted(object sender, FileSystemEventArgs e)
+ {
+ if (!m_bIgnoreFileDeletes)
+ {
+ LogMessage("MP file deleted");
+ ReWriteFiles();
+ }
+ }
+
+ private void fwatcher_Changed(object sender, FileSystemEventArgs e)
+ {
+ LogMessage("MP file Changed");
+ LoadAndCacheMPFiles();
+ }
+
+ private void fwatcher_Renamed(object sender, RenamedEventArgs e)
+ {
+ LogMessage("MP file renamed");
+ fwatcher_Deleted(sender, e);
+ }
+
+ private void LoadAndCacheMPFiles()
+ {
+ LogMessage("Loading and caching MP files");
+
+ try
+ {
+ FileStream fs = new FileStream(m_dir + m_filename, FileMode.Open, FileAccess.Read);
+ fs.Read(m_baMP, 0, m_baMP.Length);
+ fs.Flush();
+ fs.Close();
+
+ fs = new FileStream(m_dir + m_filename + ".IV", FileMode.Open, FileAccess.Read);
+ fs.Read(m_baMPIV, 0, m_baMPIV.Length);
+ fs.Flush();
+ fs.Close();
+
+ if (File.Exists(m_dir + m_filename + ".salt"))
+ {
+ m_baMPSalt = new byte[64];
+ fs = new FileStream(m_dir + m_filename + ".salt", FileMode.Open, FileAccess.Read);
+ fs.Read(m_baMPSalt, 0, m_baMPSalt.Length);
+ fs.Flush();
+ fs.Close();
+ }
+
+ }
+
+ catch (Exception e)
+ {
+ LogMessage(e.ToString());
+ }
+ }
+
+ private void ReWriteFiles()
+ {
+ try
+ {
+ FileStream fs = new FileStream(m_dir + m_filename, FileMode.Create);
+ fs.Write(m_baMP, 0, m_baMP.Length);
+ fs.Flush();
+ fs.Close();
+
+ File.SetAttributes(m_dir + m_filename, FileAttributes.Hidden);
+ CSSSUtils.SetSocketUserAsOwner(m_dir + m_filename, m_store.user.UserIdentifier);
+ }
+ catch (Exception e)
+ {
+ LogMessage(e.ToString());
+ }
+
+ try
+ {
+ FileStream fs = new FileStream(m_dir + m_filename + ".IV", FileMode.Create);
+ fs.Write(m_baMPIV, 0, m_baMPIV.Length);
+ fs.Flush();
+ 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)
+ {
+ LogMessage(e.ToString());
+ }
+
+
+ if (m_baMPSalt != null)
+ {
+ try
+ {
+ FileStream fs = new FileStream(m_dir + m_filename + ".salt", FileMode.Create);
+ fs.Write(m_baMPSalt, 0, m_baMPSalt.Length);
+ fs.Flush();
+ 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)
+ {
+ LogMessage(e.ToString());
+ }
+ }
+
+ }
+
+ private void LogMessage(string message)
+ {
+// Console.WriteLine(message);
+ CSSSLogger.DbgLog("MPFileWatcher:" + message);
+ }
+ }
+}
diff --git a/CASA/micasad/cache/SecretStore.cs b/CASA/micasad/cache/SecretStore.cs
index 576dd549..b0b26057 100644
--- a/CASA/micasad/cache/SecretStore.cs
+++ b/CASA/micasad/cache/SecretStore.cs
@@ -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,16 +176,16 @@ 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,23 +336,23 @@ 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;
+ bIsStorePersistent = true;
ReEncryptPasscodeUsingRandomSalt(baPasscode, desktopPasswd, GetPasscodeByDesktopFilePath());
return true;
}
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
+ // 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,12 +518,12 @@ 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)
{
- lss = new LocalStorage(this, baPasscode);
+ lss = new LocalStorage(this, baPasscode);
ReEncryptPasscodeUsingRandomSalt(baPasscode, mPasswd, GetPasscodeByMasterPasswdFilePath());
bIsStorePersistent = true;
}
@@ -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,13 +553,13 @@ 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)
{
- lss = new LocalStorage(this, baPasscode);
+ lss = new LocalStorage(this, baPasscode);
ReEncryptPasscodeUsingRandomSalt(baPasscode, mPasswd, GetPasscodeByMasterPasswdFilePath());
bIsStorePersistent = true;
}
@@ -563,13 +567,13 @@ 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)
{
- lss = new LocalStorage(this, baPasscode);
+ lss = new LocalStorage(this, baPasscode);
ReEncryptPasscodeUsingRandomSalt(baPasscode, mPasswd, GetPasscodeByMasterPasswdFilePath());
bIsStorePersistent = true;
}
@@ -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,20 +610,20 @@ 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;
}
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)
@@ -917,53 +926,62 @@ namespace sscs.cache
return null;
}
else
- {
-
- 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());
- if (uiPolicy != null)
- {
- string sDir = uiPolicy.GetConfigSetting(ConstStrings.CONFIG_PERSISTENT_DIRECTORY);
- if ((sDir != null) && (sDir.Length > 0))
- {
- m_persistenceDirectory = sDir;
- return m_persistenceDirectory;
- }
- }
- }
- else
- {
- // user not logged in yet
- return null;
+ {
+
+ 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());
+ if (uiPolicy != null)
+ {
+ string sDir = uiPolicy.GetConfigSetting(ConstStrings.CONFIG_PERSISTENT_DIRECTORY);
+ 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
+ {
+ // user not logged in yet
+ return null;
}
}
- m_persistenceDirectory = MigrateMiCasaFiles();
- return m_persistenceDirectory;
+ m_persistenceDirectory = MigrateMiCasaFiles();
+ ChangeFileOwnershipForMiCasaFiles(null);
+ return m_persistenceDirectory;
}
internal string MigrateMiCasaFiles()
- {
+ {
string sSeperator = "/";
#if LINUX
// for v1.7, we are storing MiCasa files in /home/.casa/[username]
// let's migrate the files if needed
string sNewPath = POLICY_DIRECTORY + "/" + user.GetUserName();
-#else
- string sNewPath = GetUserHomeDirectory() + "\\CASA";
-
- System.Diagnostics.Trace.WriteLine("Migrate files to " + sNewPath);
-
- if (!Directory.Exists(sNewPath))
- {
- Directory.CreateDirectory(sNewPath);
- }
-
+#else
+ string sNewPath = GetUserHomeDirectory() + "\\CASA";
+
+ System.Diagnostics.Trace.WriteLine("Migrate files to " + sNewPath);
+
+ if (!Directory.Exists(sNewPath))
+ {
+ Directory.CreateDirectory(sNewPath);
+ }
+
sSeperator = "\\";
#endif
try
@@ -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);
}
@@ -1127,14 +1188,14 @@ namespace sscs.cache
String sXMLData = Encoding.ASCII.GetString(decryptedXmlSecrets);
doc.LoadXml(sXMLData);
LocalStorage.AddXMLSecretsToStore(this, doc);
- }
-
- private void ReEncryptPasscodeUsingRandomSalt(byte[] baPasscode, string sPassword, string sFilepath)
- {
- if (!File.Exists(sFilepath + ".salt"))
- {
- CASACrypto.EncryptAndStoreMasterPasscodeUsingString(baPasscode, sPassword, sFilepath);
- }
+ }
+
+ private void ReEncryptPasscodeUsingRandomSalt(byte[] baPasscode, string sPassword, string sFilepath)
+ {
+ if (!File.Exists(sFilepath + ".salt"))
+ {
+ CASACrypto.EncryptAndStoreMasterPasscodeUsingString(baPasscode, sPassword, sFilepath, user.UserIdentifier);
+ }
}
internal void CreatePolicyDirectory()
diff --git a/CASA/micasad/common/CSSSUtils.cs b/CASA/micasad/common/CSSSUtils.cs
new file mode 100644
index 00000000..768dacf1
--- /dev/null
+++ b/CASA/micasad/common/CSSSUtils.cs
@@ -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
+ }
+ }
+}
diff --git a/CASA/micasad/lss/CASACrypto.cs b/CASA/micasad/lss/CASACrypto.cs
index efa243d1..605188dd 100644
--- a/CASA/micasad/lss/CASACrypto.cs
+++ b/CASA/micasad/lss/CASACrypto.cs
@@ -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);
@@ -181,7 +192,7 @@ namespace sscs.crypto
{
//Get an decryptor.
RijndaelManaged myRijndael = new RijndaelManaged();
- ICryptoTransform decryptor = myRijndael.CreateDecryptor(key, baIV);
+ ICryptoTransform decryptor = myRijndael.CreateDecryptor(key, baIV);
csDecrypt = new CryptoStream(ms, decryptor, CryptoStreamMode.Read);
//Read all data to the crypto stream and flush it.
@@ -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);
@@ -249,8 +260,8 @@ namespace sscs.crypto
//Encrypt the data to a file
fsEncrypt = new FileStream(fileName, FileMode.Create);
- // make hidden
- File.SetAttributes(fileName, FileAttributes.Hidden);
+ // make hidden
+ File.SetAttributes(fileName, FileAttributes.Hidden);
SHA256 sha = new SHA256Managed();
@@ -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;
@@ -295,14 +312,21 @@ namespace sscs.crypto
try
{
- SHA256 shaM = new SHA256Managed();
- hash = shaM.ComputeHash(baPasscode);
+ SHA256 shaM = new SHA256Managed();
+ hash = shaM.ComputeHash(baPasscode);
- fsHash = new FileStream(fileName, FileMode.Create);
- File.SetAttributes(fileName, FileAttributes.Hidden);
+ fsHash = new FileStream(fileName, FileMode.Create);
+ File.SetAttributes(fileName, FileAttributes.Hidden);
- fsHash.Write(hash, 0, hash.Length);
- fsHash.Flush();
+ 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,16 +352,16 @@ 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)
+ UnixFileInfo fsTest = new UnixFileInfo (fileName);
+ if((fsTest == null) || !(fsTest.Exists) || fsTest.IsSymbolicLink || !CSSSUtils.CompareSocketAndFileUserIds(fileName, userID))
#else
- if(!File.Exists(fileName))
+ if(!File.Exists(fileName))
#endif
- {
+ {
return null;
}
@@ -347,23 +371,23 @@ namespace sscs.crypto
fsDecrypt.Read(storedHash,0,storedHash.Length);
csDecrypt = new CryptoStream(fsDecrypt, decryptor, CryptoStreamMode.Read);
- if(fsDecrypt.Length < HASH_SIZE )
- {
- csDecrypt.Close();
- fsDecrypt.Close();
- return null;
- }
+ if(fsDecrypt.Length < HASH_SIZE )
+ {
+ csDecrypt.Close();
+ fsDecrypt.Close();
+ return null;
+ }
- if(fsDecrypt.Length > MAX_FILE_SIZE )
- {
- CSSSLogger.DbgLog("Size of the secret file exceeded the maximum allowed.");
- csDecrypt.Close();
- fsDecrypt.Close();
- return null;
- }
+ if(fsDecrypt.Length > MAX_FILE_SIZE )
+ {
+ CSSSLogger.DbgLog("Size of the secret file exceeded the maximum allowed.");
+ csDecrypt.Close();
+ fsDecrypt.Close();
+ return null;
+ }
- ulong fileLen = (ulong)(fsDecrypt.Length - HASH_SIZE);
- byte[] fromEncrypt = new byte[fileLen];
+ ulong fileLen = (ulong)(fsDecrypt.Length - HASH_SIZE);
+ byte[] fromEncrypt = new byte[fileLen];
//Read the data out of the crypto stream.
int bytesRead = csDecrypt.Read(fromEncrypt, 0, fromEncrypt.Length);
@@ -407,24 +431,24 @@ namespace sscs.crypto
if (csDecrypt != null)
{
- try
- {
- csDecrypt.Close();
- }
- catch
- {
- }
+ try
+ {
+ csDecrypt.Close();
+ }
+ catch
+ {
+ }
}
if( fsDecrypt != null )
{
- try
- {
- fsDecrypt.Close();
- }
- catch
- {
- }
+ try
+ {
+ fsDecrypt.Close();
+ }
+ catch
+ {
+ }
}
return null;
}
@@ -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,24 +547,25 @@ namespace sscs.crypto
internal static void EncryptAndStoreMasterPasscodeUsingString(
byte[] baMasterPasscode,
string passwd,
- string fileName)
+ string fileName,
+ UserIdentifier userID)
{
FileStream fsEncrypt = null;
CryptoStream csEncrypt = null;
try
{
if(File.Exists(fileName))
- File.Delete(fileName);
-
- byte[] baKey = Generate16ByteKeyFromString(passwd, fileName, false, true);
+ File.Delete(fileName);
+
+ byte[] baKey = Generate16ByteKeyFromString(passwd, fileName, false, true, userID);
//Get an encryptor.
RijndaelManaged myRijndael = new RijndaelManaged();
- ICryptoTransform encryptor;
-
- encryptor = myRijndael.CreateEncryptor(baKey, GenerateAndSaveIV(fileName, myRijndael));
+ ICryptoTransform encryptor;
+
+ 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);
csEncrypt = new CryptoStream(fsEncrypt, encryptor,
@@ -552,9 +577,13 @@ namespace sscs.crypto
csEncrypt.Close();
fsEncrypt.Close();
- // make hidden
- File.SetAttributes(fileName, FileAttributes.Hidden);
+ // 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,27 +608,26 @@ 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)
+ UnixFileInfo fsTest = new UnixFileInfo (fileName);
+ if((fsTest == null) || !(fsTest.Exists) || fsTest.IsSymbolicLink || !CSSSUtils.CompareSocketAndFileUserIds(fileName, userID))
#else
- if (!File.Exists(fileName))
+ if (!File.Exists(fileName))
#endif
{
return null;
}
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);
@@ -880,27 +915,27 @@ namespace sscs.crypto
}
catch(Exception e)
{
- CSSSLogger.ExpLog(e.ToString());
- CSSSLogger.DbgLog("Validation of passcode failed.");
- }
- return false;
- }
+ CSSSLogger.ExpLog(e.ToString());
+ CSSSLogger.DbgLog("Validation of passcode failed.");
+ }
+ return false;
+ }
- private static byte[] GenerateAndSaveIV(string sFileName, RijndaelManaged theRiManaged)
+ private static byte[] GenerateAndSaveIV(string sFileName, RijndaelManaged theRiManaged, UserIdentifier userID)
{
byte[] baIV = null;
- if ( theRiManaged != null )
- {
- theRiManaged.GenerateIV();
- baIV = theRiManaged.IV;
- }
- else
- {
- RandomNumberGenerator rng = RandomNumberGenerator.Create ();
- baIV = new byte [16];
- rng.GetBytes (baIV);
- }
+ if ( theRiManaged != null )
+ {
+ theRiManaged.GenerateIV();
+ baIV = theRiManaged.IV;
+ }
+ else
+ {
+ RandomNumberGenerator rng = RandomNumberGenerator.Create ();
+ baIV = new byte [16];
+ rng.GetBytes (baIV);
+ }
try
{
@@ -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();
diff --git a/CASA/micasad/lss/LocalStorage.cs b/CASA/micasad/lss/LocalStorage.cs
index 40387dc1..a7b14ac3 100644
--- a/CASA/micasad/lss/LocalStorage.cs
+++ b/CASA/micasad/lss/LocalStorage.cs
@@ -18,28 +18,28 @@
* 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;
-using System.Collections;
-using System.Threading;
-using System.Security.Cryptography;
-using System.Xml;
+ ***********************************************************************/
+
+using System;
+using System.IO;
+using System.Text;
+using System.Collections;
+using System.Threading;
+using System.Security.Cryptography;
+using System.Xml;
#if LINUX
using Mono.Unix.Native;
-#endif
-using sscs.cache;
-using sscs.crypto;
-using sscs.common;
-using sscs.constants;
-using Novell.CASA.MiCasa.Common;
-using Novell.CASA.CASAPolicy;
-
-namespace sscs.lss
-{
- ///
+#endif
+using sscs.cache;
+using sscs.crypto;
+using sscs.common;
+using sscs.constants;
+using Novell.CASA.MiCasa.Common;
+using Novell.CASA.CASAPolicy;
+
+namespace sscs.lss
+{
+ ///
/*
* This class is a service to store data persistently.
* How it does this is determined by implementation within the
@@ -51,809 +51,738 @@ namespace sscs.lss
* Each piece of data is located by a DataID.
* This might be an individual credentail or
* a complete store.
- */
-
+ */
+
/* We might not need this as a separate class.
* Depending on the db changes, we can change this later.
- */
-
- ///
- public class LocalStorage
- {
- private byte[] m_baGeneratedKey = null;
- private SecretStore userStore = null;
-
- private int persistThreadSleepTime = 1000 * 60 * 5; //1000 * 30;
- private Thread persistThread = null;
- private Thread sPersistThread = null;
-
+ */
+
+ ///
+ public class LocalStorage
+ {
+ private byte[] m_baGeneratedKey = null;
+ private SecretStore userStore = null;
+
+ private int persistThreadSleepTime = 1000 * 60 * 5; //1000 * 30;
+ private Thread persistThread = null;
+ private Thread sPersistThread = null;
+
#if LINUX
Mono.Unix.UnixFileSystemInfo sockFileInfo;
Mono.Unix.UnixUserInfo sockFileOwner;
-#endif
-
- private static string LINUXID = "Unix";
-
- internal LocalStorage(SecretStore store, byte[] baMasterPasscode, bool dummy)
- {
- userStore = store;
- m_baGeneratedKey = baMasterPasscode;
- LoadPersistentStore(ConstStrings.SSCS_SERVER_KEY_CHAIN_ID);
- //userStore.DumpSecretstore();
- }
-
- internal LocalStorage(SecretStore store, byte[] baMasterPasscode)
- {
- userStore = store;
- m_baGeneratedKey = baMasterPasscode;
- LoadPersistentStore(ConstStrings.SSCS_SESSION_KEY_CHAIN_ID);
- userStore.DumpSecretstore();
- }
-
- ~LocalStorage()
- {
- if (persistThread != null)
- {
- persistThread.Abort();
- persistThread.Join();
- }
-
- if (sPersistThread != null)
- {
- sPersistThread.Abort();
- sPersistThread.Join();
- }
- }
-
- // allowing a user to choose the storage location is not approved yet
- private LocalStorage(SecretStore store,
- byte[] baMasterPasscode, string sStorageDirectory)
- {
- userStore = store;
- m_baGeneratedKey = baMasterPasscode;
- LoadPersistentStore(ConstStrings.SSCS_SESSION_KEY_CHAIN_ID);
- userStore.DumpSecretstore();
- }
-
- private void StorePersistentData(string sDataID, byte[] baData)
- {
-
- }
-
- private byte[] RetrievePersistentData(string sDataID)
- {
-
-
- return null;
- }
-
- public void PersistStoreWithDelay()
- {
- if (persistThread == null)
- {
- persistThread = new Thread(new ThreadStart(PersistStoreDelayThreadFn));
- persistThread.Start();
- }
- }
-
- public void PersistServerStoreWithDelay()
- {
- if (sPersistThread == null)
- {
- sPersistThread = new Thread(new ThreadStart(PersistServerStoreDelayThreadFn));
- sPersistThread.Start();
- }
- }
-
- public bool StopPersistence()
- {
- if (persistThread != null)
- {
- persistThread.Abort();
- persistThread.Join();
- }
- return true;
- }
-
- public bool StopServerPersistence()
- {
- if (sPersistThread != null)
- {
- sPersistThread.Abort();
- sPersistThread.Join();
- }
- return true;
- }
-
- public bool IsOwnedByRoot(string fileName)
- {
-#if LINUX
- sockFileInfo = new Mono.Unix.UnixFileInfo(fileName);
- sockFileOwner = sockFileInfo.OwnerUser;
- if(0==sockFileOwner.UserId)
- return true;
+#endif
+
+ private static string LINUXID = "Unix";
+
+ internal LocalStorage(SecretStore store, byte[] baMasterPasscode, bool dummy)
+ {
+ userStore = store;
+ m_baGeneratedKey = baMasterPasscode;
+ LoadPersistentStore(ConstStrings.SSCS_SERVER_KEY_CHAIN_ID);
+ //userStore.DumpSecretstore();
+ }
+
+ internal LocalStorage(SecretStore store, byte[] baMasterPasscode)
+ {
+ userStore = store;
+ m_baGeneratedKey = baMasterPasscode;
+ LoadPersistentStore(ConstStrings.SSCS_SESSION_KEY_CHAIN_ID);
+ userStore.DumpSecretstore();
+ }
+
+ ~LocalStorage()
+ {
+ if (persistThread != null)
+ {
+ persistThread.Abort();
+ persistThread.Join();
+ }
+
+ if (sPersistThread != null)
+ {
+ sPersistThread.Abort();
+ sPersistThread.Join();
+ }
+ }
+
+ // allowing a user to choose the storage location is not approved yet
+ private LocalStorage(SecretStore store,
+ byte[] baMasterPasscode, string sStorageDirectory)
+ {
+ userStore = store;
+ m_baGeneratedKey = baMasterPasscode;
+ LoadPersistentStore(ConstStrings.SSCS_SESSION_KEY_CHAIN_ID);
+ userStore.DumpSecretstore();
+ }
+
+ private void StorePersistentData(string sDataID, byte[] baData)
+ {
+
+ }
+
+ private byte[] RetrievePersistentData(string sDataID)
+ {
+
+
+ return null;
+ }
+
+ public void PersistStoreWithDelay()
+ {
+ if (persistThread == null)
+ {
+ persistThread = new Thread(new ThreadStart(PersistStoreDelayThreadFn));
+ persistThread.Start();
+ }
+ }
+
+ public void PersistServerStoreWithDelay()
+ {
+ if (sPersistThread == null)
+ {
+ sPersistThread = new Thread(new ThreadStart(PersistServerStoreDelayThreadFn));
+ sPersistThread.Start();
+ }
+ }
+
+ public bool StopPersistence()
+ {
+ if (persistThread != null)
+ {
+ persistThread.Abort();
+ persistThread.Join();
+ }
+ return true;
+ }
+
+ public bool StopServerPersistence()
+ {
+ if (sPersistThread != null)
+ {
+ sPersistThread.Abort();
+ sPersistThread.Join();
+ }
+ return true;
+ }
+
+ private string GetDecryptedServerSecretsXml()
+ {
+ try
+ {
+ string fileName = userStore.GetServerSecretsPersistenceFilePath();
+ string tempFile = fileName;
+ if (!File.Exists(fileName))
+ {
+ // check for tmp file
+ if (File.Exists(tempFile + ".tmp"))
+ {
+ File.Move(tempFile + ".tmp", fileName);
+ File.Delete(tempFile + ".tmp");
+ }
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();
- }
- }
- 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());
-
- if (null == baPasscode)
- return null;
-
- byte[] key = CASACrypto.GetKeySetFromFile(baPasscode, userStore.GetServerKeyFilePath());
- if (null == key)
- return null;
-
- byte[] decryptedBuffer = CASACrypto.ReadFileAndDecryptData(key, fileName);
-
- if (null == decryptedBuffer)
- return null;
-
- string temp = Encoding.UTF8.GetString(decryptedBuffer, 0, decryptedBuffer.Length);
-
- return temp;
- }
- catch (Exception e)
- {
- CSSSLogger.ExpLog(e.ToString());
- CSSSLogger.DbgLog("Unable to get persistent store");
- }
- return null;
- }
-
- private string GetDecryptedXml()
- {
- try
- {
- 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();
- }
- }
- 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());
-
- if (null == baPasscode)
- return null;
-
- byte[] key = CASACrypto.GetKeySetFromFile(baPasscode, userStore.GetKeyFilePath());
- if (null == key)
- return null;
-
- byte[] decryptedBuffer = CASACrypto.ReadFileAndDecryptData(key, fileName);
-
- if (null == decryptedBuffer)
- return null;
-
- string temp = Encoding.UTF8.GetString(decryptedBuffer, 0, decryptedBuffer.Length);
-
- return temp;
- }
- catch (Exception e)
- {
- CSSSLogger.ExpLog(e.ToString());
- CSSSLogger.DbgLog("Unable to get persistent store");
- }
- return null;
- }
-
+ return null;
+ }
+
+ byte[] baPasscode = null;
+ if (null != m_baGeneratedKey)
+ baPasscode = m_baGeneratedKey;
+ else
+ baPasscode = CASACrypto.GetServerMasterPasscodeUsingSystemKey(userStore.GetServerPasscodeBySystemKeyFilePath(), userStore.GetUserIdentifier());
+
+ if (null == baPasscode)
+ return null;
+
+ byte[] key = CASACrypto.GetKeySetFromFile(baPasscode, userStore.GetServerKeyFilePath(), userStore.GetUserIdentifier());
+ if (null == key)
+ return null;
+
+ byte[] decryptedBuffer = CASACrypto.ReadFileAndDecryptData(key, fileName, userStore.GetUserIdentifier());
+
+ if (null == decryptedBuffer)
+ return null;
+
+ string temp = Encoding.UTF8.GetString(decryptedBuffer, 0, decryptedBuffer.Length);
+
+ return temp;
+ }
+ catch (Exception e)
+ {
+ CSSSLogger.ExpLog(e.ToString());
+ CSSSLogger.DbgLog("Unable to get persistent store");
+ }
+ return null;
+ }
+
+ private string GetDecryptedXml()
+ {
+ try
+ {
+ string fileName = userStore.GetPersistenceFilePath();
+ string tempFile = fileName;
+ if (!File.Exists(fileName))
+ {
+ // check for tmp file
+ if (File.Exists(tempFile + ".tmp"))
+ {
+ File.Move(tempFile + ".tmp", fileName);
+ File.Delete(tempFile + ".tmp");
+ }
+ else
+ return null;
+ }
+
+ byte[] baPasscode = null;
+ if (null != m_baGeneratedKey)
+ baPasscode = m_baGeneratedKey;
+ else
+ baPasscode = CASACrypto.GetMasterPasscode(userStore.GetDesktopPasswd(), userStore.GetPasscodeByDesktopFilePath(), userStore.GetUserIdentifier());
+
+ if (null == baPasscode)
+ return null;
+
+ byte[] key = CASACrypto.GetKeySetFromFile(baPasscode, userStore.GetKeyFilePath(), userStore.GetUserIdentifier());
+ if (null == key)
+ return null;
+
+ byte[] decryptedBuffer = CASACrypto.ReadFileAndDecryptData(key, fileName, userStore.GetUserIdentifier());
+
+ if (null == decryptedBuffer)
+ return null;
+
+ string temp = Encoding.UTF8.GetString(decryptedBuffer, 0, decryptedBuffer.Length);
+
+ return temp;
+ }
+ catch (Exception e)
+ {
+ CSSSLogger.ExpLog(e.ToString());
+ CSSSLogger.DbgLog("Unable to get persistent store");
+ }
+ return null;
+ }
+
/* This method, uses the key to decrypt the persistent store
* and populates userStore with the persistent data.
- */
- private bool LoadPersistentStore(string keyChainId)
- {
- try
- {
- //string xpath = "";
- XmlDocument doc = new XmlDocument();
-
- string xmlToLoad = null;
- if (keyChainId == ConstStrings.SSCS_SESSION_KEY_CHAIN_ID)
- xmlToLoad = GetDecryptedXml();
- else if (keyChainId == ConstStrings.SSCS_SERVER_KEY_CHAIN_ID)
- xmlToLoad = GetDecryptedServerSecretsXml();
-
- if (xmlToLoad != null)
- {
- doc.LoadXml(xmlToLoad);
-
+ */
+ private bool LoadPersistentStore(string keyChainId)
+ {
+ try
+ {
+ //string xpath = "";
+ XmlDocument doc = new XmlDocument();
+
+ string xmlToLoad = null;
+ if (keyChainId == ConstStrings.SSCS_SESSION_KEY_CHAIN_ID)
+ xmlToLoad = GetDecryptedXml();
+ else if (keyChainId == ConstStrings.SSCS_SERVER_KEY_CHAIN_ID)
+ xmlToLoad = GetDecryptedServerSecretsXml();
+
+ if (xmlToLoad != null)
+ {
+ doc.LoadXml(xmlToLoad);
+
#if false
XmlTextWriter writer = new XmlTextWriter("d:/persist.xml",null);
writer.Formatting = Formatting.Indented;
doc.Save(writer);
writer.Close();
-#endif
- }
- else
- {
- return false;
- }
-
- // add these to the store
- AddXMLSecretsToStore(userStore, doc);
- }
- catch (Exception e)
- {
- CSSSLogger.ExpLog(e.ToString());
- }
-
- // collect now to remove old data from memory
- GC.Collect();
-
- return true;
- }
-
- internal static void AddXMLSecretsToStore(SecretStore userStore, XmlDocument doc)
- {
- // get the conflict keychain
- KeyChain kcConflict;
- if (!userStore.CheckIfKeyChainExists(ConstStrings.SSCS_CONFLICT_KEYCHAIN + '\0'))
- {
- kcConflict = new KeyChain(ConstStrings.SSCS_CONFLICT_KEYCHAIN + '\0');
- userStore.AddKeyChain(kcConflict);
- }
- else
- {
- kcConflict = userStore.GetKeyChain(ConstStrings.SSCS_CONFLICT_KEYCHAIN + '\0');
- }
-
- string xpath = "";
- xpath = "//" + XmlConsts.miCASANode;
- XmlNode miCASANode = doc.SelectSingleNode(xpath);
- if (miCASANode != null)
- {
- xpath = "descendant::" + XmlConsts.keyChainNode;
- XmlNodeList keyChainNodeList = miCASANode.SelectNodes(xpath);
- foreach (XmlNode node in keyChainNodeList)
- {
- XmlAttributeCollection attrColl = node.Attributes;
- string keyChainId = (attrColl[XmlConsts.idAttr]).Value + "\0";
- KeyChain keyChain = null;
-
- if (userStore.CheckIfKeyChainExists(keyChainId) == false)
- {
- keyChain = new KeyChain(keyChainId);
- userStore.AddKeyChain(keyChain);
- }
- else
- {
- keyChain = userStore.GetKeyChain(keyChainId);
-
- // set the created time if possible
- XmlNode timeNode = node.SelectSingleNode("descendant::" + XmlConsts.timeNode);
- if (timeNode != null)
- {
- XmlAttributeCollection timeAttribCol = timeNode.Attributes;
- if (timeAttribCol != null)
- {
- XmlNode createdTimeNode = timeAttribCol.GetNamedItem(XmlConsts.createdTimeNode);
- if (createdTimeNode != null)
- {
- //Console.WriteLine("KeyChain create time:" + new DateTime(long.Parse(createdTimeNode.Value)));
- }
- else
- {
- //Console.WriteLine("Create time not found");
- }
- XmlNode modifiedTimeNode = timeAttribCol.GetNamedItem(XmlConsts.modifiedTimeNode);
- if (modifiedTimeNode != null)
- {
- //Console.WriteLine("KeyChain mod time:" + new DateTime(long.Parse(modifiedTimeNode.Value)));
- }
- }
- }
- }
-
- xpath = "descendant::" + XmlConsts.secretNode;
- XmlNodeList secretNodeList = node.SelectNodes(xpath);
- foreach (XmlNode secretNode in secretNodeList)
- {
- attrColl = secretNode.Attributes;
- string secretId = (attrColl[XmlConsts.idAttr]).Value + "\0";
- xpath = "descendant::" + XmlConsts.valueNode;
- Secret secret = new Secret(secretId);
-
-
- // get time stamps for this secret
- XmlNode timeNode = secretNode.SelectSingleNode("descendant::" + XmlConsts.timeNode);
- if (timeNode != null)
- {
- //Console.WriteLine("Secret: " + secretId);
- XmlAttributeCollection timeAttribCol = timeNode.Attributes;
- if (timeAttribCol != null)
- {
- XmlNode createdTimeNode = timeAttribCol.GetNamedItem(XmlConsts.createdTimeNode);
- if (createdTimeNode != null)
- {
- //Console.WriteLine("Secret create time:" + new DateTime(long.Parse(createdTimeNode.Value)));
- secret.CreatedTime = new DateTime(long.Parse(createdTimeNode.Value), DateTimeKind.Utc).ToLocalTime();
- }
- else
- {
- //Console.WriteLine("Create time not found");
- }
-
- XmlNode modifiedTimeNode = timeAttribCol.GetNamedItem(XmlConsts.modifiedTimeNode);
- if (modifiedTimeNode != null)
- {
- //Console.WriteLine("Secret mod time:" + new DateTime(long.Parse(modifiedTimeNode.Value)));
- secret.ModifiedTime = new DateTime(long.Parse(modifiedTimeNode.Value), DateTimeKind.Utc).ToLocalTime();
- }
- else
- {
- //Console.WriteLine("mod time not found");
- }
- }
- }
-
-
- //if (keyChain.CheckIfSecretExists(secretId) == false)
- {
- //keyChain.AddSecret(secret);
- XmlNode secretValNode = (secretNode.SelectSingleNode(xpath));
- xpath = "descendant::" + XmlConsts.keyNode;
-
- XmlNodeList keyNodeList = secretValNode.SelectNodes(xpath);
-
- //secret = keyChain.GetSecret(secretId);
- foreach (XmlNode keyNode in keyNodeList)
- {
- attrColl = keyNode.Attributes;
- string key;
- string sIsBinary = "";
- try
- {
- key = (attrColl[XmlConsts.idAttr]).Value;
-
- }
- catch (Exception)
- {
- // LinkedKey node, continue
- continue;
- }
-
- // get binary attribute, if set
- try
- {
- sIsBinary = attrColl.GetNamedItem(XmlConsts.binaryAttr).Value;
- }
- catch
- {
- sIsBinary = "false";
- }
-
- xpath = "descendant::" + XmlConsts.keyValueNode;
- XmlNode keyValNode = keyNode.SelectSingleNode(xpath);
- string keyValue = keyValNode.InnerText;
-
- // set binary type if set
- if ((sIsBinary != null) && (sIsBinary.Equals("true")))
- {
- byte[] baDec = Convert.FromBase64String(keyValue);
- secret.SetKeyValue(key, baDec, false);
-
- KeyValue kv = secret.GetKeyValue(key);
- kv.SetValueType(KeyValue.VALUE_TYPE_BINARY);
- }
- else
- {
- secret.SetKeyValue(key, keyValue, false);
- }
-
- // get time attributes on this key/value
- XmlNode timeNodeKey = keyNode.SelectSingleNode("descendant::" + XmlConsts.timeNode);
- if (timeNodeKey != null)
- {
- // get the key value we just set
- KeyValue kv = secret.GetKeyValue(key);
-
- XmlAttributeCollection timeAttribCol = timeNodeKey.Attributes;
- if (timeAttribCol != null)
- {
- XmlNode createdTimeNode = timeAttribCol.GetNamedItem(XmlConsts.createdTimeNode);
- if (createdTimeNode != null)
- {
- kv.CreatedTime = new DateTime(long.Parse(createdTimeNode.Value), DateTimeKind.Utc).ToLocalTime();
- }
- else
- {
- //Console.WriteLine("Create time not found");
- }
-
- XmlNode modifiedTimeNode = timeAttribCol.GetNamedItem(XmlConsts.modifiedTimeNode);
- if (modifiedTimeNode != null)
- {
- kv.ModifiedTime = new DateTime(long.Parse(modifiedTimeNode.Value), DateTimeKind.Utc).ToLocalTime();
- }
- else
- {
- //Console.WriteLine("mod time not found");
- }
- }
- }
-
-
- // add linked keys
- xpath = "descendant::" + XmlConsts.linkedKeyNode;
- XmlNodeList linkNodeList = keyNode.SelectNodes(xpath);
- foreach (XmlNode linkNode in linkNodeList)
- {
- // get TargetSecretID
- xpath = "descendant::" + XmlConsts.linkedTargetSecretNode;
- XmlNode targetSecretNode = linkNode.SelectSingleNode(xpath);
- string sSecretID = targetSecretNode.InnerText + "\0";
-
- // get TargetSecretKey
- xpath = "descendant::" + XmlConsts.linkedTargetKeyNode;
- XmlNode targetKeyNode = linkNode.SelectSingleNode(xpath);
- string sKeyID = targetKeyNode.InnerText;
-
- LinkedKeyInfo lki = new LinkedKeyInfo(sSecretID, sKeyID, true);
- KeyValue kv = secret.GetKeyValue(key);
- kv.AddLink(lki);
- }
-
- }
- }//if ends
-
- // if SecretID already exists, add to the conflict keychain
- if (keyChain.CheckIfSecretExists(secretId) == false)
- {
- keyChain.AddSecret(secret);
- }
- else
- {
- if (kcConflict.CheckIfSecretExists(secretId))
- {
- kcConflict.RemoveSecret(secretId);
- }
- kcConflict.AddSecret(secret);
- }
-
- }
-
- }//end of traversing keyChainNodeList
- }
- }
-
- private void PersistStoreDelayThreadFn()
- {
- Thread.Sleep(15000);
- PersistStore(ConstStrings.SSCS_SESSION_KEY_CHAIN_ID);
- persistThread = null;
- }
-
- private void PersistServerStoreDelayThreadFn()
- {
- Thread.Sleep(15000);
- PersistStore(ConstStrings.SSCS_SERVER_KEY_CHAIN_ID);
- sPersistThread = null;
- }
-
- private void PersistStoreThreadFn()
- {
- while (true)
- {
- Thread.Sleep(persistThreadSleepTime);
- PersistStore(ConstStrings.SSCS_SESSION_KEY_CHAIN_ID);
- }
- }
-
- private void PersistServerStoreThreadFn()
- {
- while (true)
- {
- Thread.Sleep(persistThreadSleepTime);
- PersistStore(ConstStrings.SSCS_SERVER_KEY_CHAIN_ID);
- }
- }
-
+#endif
+ }
+ else
+ {
+ return false;
+ }
+
+ // add these to the store
+ AddXMLSecretsToStore(userStore, doc);
+ }
+ catch (Exception e)
+ {
+ CSSSLogger.ExpLog(e.ToString());
+ }
+
+ // collect now to remove old data from memory
+ GC.Collect();
+
+ return true;
+ }
+
+ internal static void AddXMLSecretsToStore(SecretStore userStore, XmlDocument doc)
+ {
+ // get the conflict keychain
+ KeyChain kcConflict;
+ if (!userStore.CheckIfKeyChainExists(ConstStrings.SSCS_CONFLICT_KEYCHAIN + '\0'))
+ {
+ kcConflict = new KeyChain(ConstStrings.SSCS_CONFLICT_KEYCHAIN + '\0');
+ userStore.AddKeyChain(kcConflict);
+ }
+ else
+ {
+ kcConflict = userStore.GetKeyChain(ConstStrings.SSCS_CONFLICT_KEYCHAIN + '\0');
+ }
+
+ string xpath = "";
+ xpath = "//" + XmlConsts.miCASANode;
+ XmlNode miCASANode = doc.SelectSingleNode(xpath);
+ if (miCASANode != null)
+ {
+ xpath = "descendant::" + XmlConsts.keyChainNode;
+ XmlNodeList keyChainNodeList = miCASANode.SelectNodes(xpath);
+ foreach (XmlNode node in keyChainNodeList)
+ {
+ XmlAttributeCollection attrColl = node.Attributes;
+ string keyChainId = (attrColl[XmlConsts.idAttr]).Value + "\0";
+ KeyChain keyChain = null;
+
+ if (userStore.CheckIfKeyChainExists(keyChainId) == false)
+ {
+ keyChain = new KeyChain(keyChainId);
+ userStore.AddKeyChain(keyChain);
+ }
+ else
+ {
+ keyChain = userStore.GetKeyChain(keyChainId);
+
+ // set the created time if possible
+ XmlNode timeNode = node.SelectSingleNode("descendant::" + XmlConsts.timeNode);
+ if (timeNode != null)
+ {
+ XmlAttributeCollection timeAttribCol = timeNode.Attributes;
+ if (timeAttribCol != null)
+ {
+ XmlNode createdTimeNode = timeAttribCol.GetNamedItem(XmlConsts.createdTimeNode);
+ if (createdTimeNode != null)
+ {
+ //Console.WriteLine("KeyChain create time:" + new DateTime(long.Parse(createdTimeNode.Value)));
+ }
+ else
+ {
+ //Console.WriteLine("Create time not found");
+ }
+ XmlNode modifiedTimeNode = timeAttribCol.GetNamedItem(XmlConsts.modifiedTimeNode);
+ if (modifiedTimeNode != null)
+ {
+ //Console.WriteLine("KeyChain mod time:" + new DateTime(long.Parse(modifiedTimeNode.Value)));
+ }
+ }
+ }
+ }
+
+ xpath = "descendant::" + XmlConsts.secretNode;
+ XmlNodeList secretNodeList = node.SelectNodes(xpath);
+ foreach (XmlNode secretNode in secretNodeList)
+ {
+ attrColl = secretNode.Attributes;
+ string secretId = (attrColl[XmlConsts.idAttr]).Value + "\0";
+ xpath = "descendant::" + XmlConsts.valueNode;
+ Secret secret = new Secret(secretId);
+
+
+ // get time stamps for this secret
+ XmlNode timeNode = secretNode.SelectSingleNode("descendant::" + XmlConsts.timeNode);
+ if (timeNode != null)
+ {
+ //Console.WriteLine("Secret: " + secretId);
+ XmlAttributeCollection timeAttribCol = timeNode.Attributes;
+ if (timeAttribCol != null)
+ {
+ XmlNode createdTimeNode = timeAttribCol.GetNamedItem(XmlConsts.createdTimeNode);
+ if (createdTimeNode != null)
+ {
+ //Console.WriteLine("Secret create time:" + new DateTime(long.Parse(createdTimeNode.Value)));
+ secret.CreatedTime = new DateTime(long.Parse(createdTimeNode.Value), DateTimeKind.Utc).ToLocalTime();
+ }
+ else
+ {
+ //Console.WriteLine("Create time not found");
+ }
+
+ XmlNode modifiedTimeNode = timeAttribCol.GetNamedItem(XmlConsts.modifiedTimeNode);
+ if (modifiedTimeNode != null)
+ {
+ //Console.WriteLine("Secret mod time:" + new DateTime(long.Parse(modifiedTimeNode.Value)));
+ secret.ModifiedTime = new DateTime(long.Parse(modifiedTimeNode.Value), DateTimeKind.Utc).ToLocalTime();
+ }
+ else
+ {
+ //Console.WriteLine("mod time not found");
+ }
+ }
+ }
+
+
+ //if (keyChain.CheckIfSecretExists(secretId) == false)
+ {
+ //keyChain.AddSecret(secret);
+ XmlNode secretValNode = (secretNode.SelectSingleNode(xpath));
+ xpath = "descendant::" + XmlConsts.keyNode;
+
+ XmlNodeList keyNodeList = secretValNode.SelectNodes(xpath);
+
+ //secret = keyChain.GetSecret(secretId);
+ foreach (XmlNode keyNode in keyNodeList)
+ {
+ attrColl = keyNode.Attributes;
+ string key;
+ string sIsBinary = "";
+ try
+ {
+ key = (attrColl[XmlConsts.idAttr]).Value;
+
+ }
+ catch (Exception)
+ {
+ // LinkedKey node, continue
+ continue;
+ }
+
+ // get binary attribute, if set
+ try
+ {
+ sIsBinary = attrColl.GetNamedItem(XmlConsts.binaryAttr).Value;
+ }
+ catch
+ {
+ sIsBinary = "false";
+ }
+
+ xpath = "descendant::" + XmlConsts.keyValueNode;
+ XmlNode keyValNode = keyNode.SelectSingleNode(xpath);
+ string keyValue = keyValNode.InnerText;
+
+ // set binary type if set
+ if ((sIsBinary != null) && (sIsBinary.Equals("true")))
+ {
+ byte[] baDec = Convert.FromBase64String(keyValue);
+ secret.SetKeyValue(key, baDec, false);
+
+ KeyValue kv = secret.GetKeyValue(key);
+ kv.SetValueType(KeyValue.VALUE_TYPE_BINARY);
+ }
+ else
+ {
+ secret.SetKeyValue(key, keyValue, false);
+ }
+
+ // get time attributes on this key/value
+ XmlNode timeNodeKey = keyNode.SelectSingleNode("descendant::" + XmlConsts.timeNode);
+ if (timeNodeKey != null)
+ {
+ // get the key value we just set
+ KeyValue kv = secret.GetKeyValue(key);
+
+ XmlAttributeCollection timeAttribCol = timeNodeKey.Attributes;
+ if (timeAttribCol != null)
+ {
+ XmlNode createdTimeNode = timeAttribCol.GetNamedItem(XmlConsts.createdTimeNode);
+ if (createdTimeNode != null)
+ {
+ kv.CreatedTime = new DateTime(long.Parse(createdTimeNode.Value), DateTimeKind.Utc).ToLocalTime();
+ }
+ else
+ {
+ //Console.WriteLine("Create time not found");
+ }
+
+ XmlNode modifiedTimeNode = timeAttribCol.GetNamedItem(XmlConsts.modifiedTimeNode);
+ if (modifiedTimeNode != null)
+ {
+ kv.ModifiedTime = new DateTime(long.Parse(modifiedTimeNode.Value), DateTimeKind.Utc).ToLocalTime();
+ }
+ else
+ {
+ //Console.WriteLine("mod time not found");
+ }
+ }
+ }
+
+
+ // add linked keys
+ xpath = "descendant::" + XmlConsts.linkedKeyNode;
+ XmlNodeList linkNodeList = keyNode.SelectNodes(xpath);
+ foreach (XmlNode linkNode in linkNodeList)
+ {
+ // get TargetSecretID
+ xpath = "descendant::" + XmlConsts.linkedTargetSecretNode;
+ XmlNode targetSecretNode = linkNode.SelectSingleNode(xpath);
+ string sSecretID = targetSecretNode.InnerText + "\0";
+
+ // get TargetSecretKey
+ xpath = "descendant::" + XmlConsts.linkedTargetKeyNode;
+ XmlNode targetKeyNode = linkNode.SelectSingleNode(xpath);
+ string sKeyID = targetKeyNode.InnerText;
+
+ LinkedKeyInfo lki = new LinkedKeyInfo(sSecretID, sKeyID, true);
+ KeyValue kv = secret.GetKeyValue(key);
+ kv.AddLink(lki);
+ }
+
+ }
+ }//if ends
+
+ // if SecretID already exists, add to the conflict keychain
+ if (keyChain.CheckIfSecretExists(secretId) == false)
+ {
+ keyChain.AddSecret(secret);
+ }
+ else
+ {
+ if (kcConflict.CheckIfSecretExists(secretId))
+ {
+ kcConflict.RemoveSecret(secretId);
+ }
+ kcConflict.AddSecret(secret);
+ }
+
+ }
+
+ }//end of traversing keyChainNodeList
+ }
+ }
+
+ private void PersistStoreDelayThreadFn()
+ {
+ Thread.Sleep(15000);
+ PersistStore(ConstStrings.SSCS_SESSION_KEY_CHAIN_ID);
+ persistThread = null;
+ }
+
+ private void PersistServerStoreDelayThreadFn()
+ {
+ Thread.Sleep(15000);
+ PersistStore(ConstStrings.SSCS_SERVER_KEY_CHAIN_ID);
+ sPersistThread = null;
+ }
+
+ private void PersistStoreThreadFn()
+ {
+ while (true)
+ {
+ Thread.Sleep(persistThreadSleepTime);
+ PersistStore(ConstStrings.SSCS_SESSION_KEY_CHAIN_ID);
+ }
+ }
+
+ private void PersistServerStoreThreadFn()
+ {
+ while (true)
+ {
+ Thread.Sleep(persistThreadSleepTime);
+ PersistStore(ConstStrings.SSCS_SERVER_KEY_CHAIN_ID);
+ }
+ }
+
/* Persists the store to an xml file.
* TBD : Would we require any form of encoding?
- */
-
- internal void PersistStore(string keyChainId)
- {
- string sPeristSecrets = null;
-
- // is policy set to persist secrets
- UIPol uiPolicy = (UIPol)ICASAPol.GetPolicy(CASAPolType.UI_POL, userStore.GetUserHomeDirectory(), userStore.GetUserName());
- if (uiPolicy != null)
- {
- sPeristSecrets = uiPolicy.GetConfigSetting(ConstStrings.CONFIG_PERSIST_SECRETS);
- }
-
- if ((sPeristSecrets != null) && (sPeristSecrets.Equals("0")))
- {
- // delete .miCASA file and .IV file
- if (keyChainId == ConstStrings.SSCS_SESSION_KEY_CHAIN_ID)
- File.Delete(userStore.GetPersistenceFilePath());
- else if (keyChainId == ConstStrings.SSCS_SERVER_KEY_CHAIN_ID)
- File.Delete(userStore.GetServerSecretsPersistenceFilePath());
- return;
- }
-
- //userStore.DumpSecretstore();
- try
- {
- MemoryStream ms1 = GetSecretsAsXMLStream(this.userStore, keyChainId);
- byte[] key = null;
- string fileName = null;
-
- if (keyChainId == ConstStrings.SSCS_SESSION_KEY_CHAIN_ID)
- {
- key = CASACrypto.GetKeySetFromFile(m_baGeneratedKey, userStore.GetKeyFilePath());
- fileName = userStore.GetPersistenceFilePath();
- }
- else if (keyChainId == ConstStrings.SSCS_SERVER_KEY_CHAIN_ID)
- {
- key = CASACrypto.GetKeySetFromFile(m_baGeneratedKey, userStore.GetServerKeyFilePath());
- 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);
-
- //remove temp
- if (File.Exists(tempFile + ".tmp"))
- {
- if (IsOwnedByRoot(tempFile + ".tmp"))
- File.Delete(tempFile + ".tmp");
- }
- }
- catch (Exception e)
- {
- CSSSLogger.ExpLog(e.ToString());
- }
- }
-
- internal static MemoryStream GetSecretsAsXMLStream(SecretStore userStore, string keyChainId)
- {
- try
- {
- MemoryStream ms1 = new MemoryStream();
- XmlTextWriter writer = new XmlTextWriter(ms1, null);
- writer.Formatting = Formatting.Indented;
-
- writer.WriteStartDocument();
- writer.WriteStartElement(XmlConsts.miCASANode);
- writer.WriteAttributeString(XmlConsts.versionAttr, "1.5");
-
- IDictionaryEnumerator iter = (IDictionaryEnumerator)userStore.GetKeyChainEnumerator();
- char[] tmpId;
- string sTmpId;
- while (iter.MoveNext())
- {
- KeyChain kc = (KeyChain)iter.Value;
- string kcId = kc.GetKey();
- tmpId = new char[kcId.Length - 1];
- for (int i = 0; i < kcId.Length - 1; i++)
- tmpId[i] = kcId[i];
- sTmpId = new string(tmpId);
-
- if ((keyChainId != null) && (keyChainId != sTmpId))
- continue;
-
- writer.WriteStartElement(XmlConsts.keyChainNode);
- writer.WriteAttributeString(XmlConsts.idAttr, sTmpId);
- // If we need to store time
- writer.WriteStartElement(XmlConsts.timeNode);
- writer.WriteAttributeString(XmlConsts.createdTimeNode, kc.CreatedTime.ToUniversalTime().Ticks.ToString());
- writer.WriteAttributeString(XmlConsts.modifiedTimeNode, kc.ModifiedTime.ToUniversalTime().Ticks.ToString());
- writer.WriteEndElement();
-
- PersistencePol policy = null;
-
- IDictionaryEnumerator secIter = (IDictionaryEnumerator)(kc.GetAllSecrets());
- while (secIter.MoveNext())
- {
- Secret secret = (Secret)secIter.Value;
- writer.WriteStartElement(XmlConsts.secretNode);
- string secretId = secret.GetKey();
-
- tmpId = new char[secretId.Length - 1];
- for (int i = 0; i < secretId.Length - 1; i++)
- {
- tmpId[i] = secretId[i];
- }
- sTmpId = new string(tmpId);
-
- // TODO: Does Policy allow persisting this secret.
- if (policy == null)
- {
- policy = (PersistencePol)ICASAPol.GetPolicy(CASAPolType.PERSISTENCE_POL, userStore.GetUserHomeDirectory(), userStore.GetUserName());
- }
-
- bool bSaveValues = true;
- if (policy != null)
- {
- if (policy.GetSecretPolicy(sTmpId, "Persistent", "True").Equals("False"))
- {
- //continue;
- bSaveValues = false;
- }
- }
-
- writer.WriteAttributeString(XmlConsts.idAttr, sTmpId);
- // If we need to store time
- writer.WriteStartElement(XmlConsts.timeNode);
- writer.WriteAttributeString(XmlConsts.createdTimeNode, secret.CreatedTime.ToUniversalTime().Ticks.ToString());
- writer.WriteAttributeString(XmlConsts.modifiedTimeNode, secret.ModifiedTime.ToUniversalTime().Ticks.ToString());
- writer.WriteEndElement();
-
- writer.WriteStartElement(XmlConsts.valueNode);
- // byte[] byteArr = secret.GetValue();
-
- IDictionaryEnumerator etor = (IDictionaryEnumerator)secret.GetKeyValueEnumerator();
- while (etor.MoveNext())
- {
- string sKey = (string)etor.Key;
- KeyValue kv = secret.GetKeyValue(sKey);
- if (!kv.IsPersistent)
- {
- continue;
- }
-
- string value = kv.GetValue();
- writer.WriteStartElement(XmlConsts.keyNode);
- writer.WriteAttributeString(XmlConsts.idAttr, sKey);
- if (kv.GetValueType() == KeyValue.VALUE_TYPE_BINARY)
- {
- writer.WriteAttributeString(XmlConsts.binaryAttr, "true");
- }
-
- writer.WriteStartElement(XmlConsts.keyValueNode);
-
- if (bSaveValues)
- {
- if (kv.GetValueType() == KeyValue.VALUE_TYPE_BINARY)
- {
- writer.WriteString(Convert.ToBase64String(kv.GetValueAsBytes()));
- }
- else
- {
- writer.WriteString(value);
- }
- }
- else
- writer.WriteString("");
-
- writer.WriteEndElement();
- // If we need to store time
- writer.WriteStartElement(XmlConsts.timeNode);
- writer.WriteAttributeString(XmlConsts.createdTimeNode, (secret.GetKeyValueCreatedTime(sKey)).ToUniversalTime().Ticks.ToString());
- writer.WriteAttributeString(XmlConsts.modifiedTimeNode, (secret.GetKeyValueModifiedTime(sKey)).ToUniversalTime().Ticks.ToString());
- writer.WriteEndElement();
-
- // write all LinkKeys
- Hashtable htLinkedKeys = secret.GetLinkedKeys(sKey);
- if (htLinkedKeys != null)
- {
- IDictionaryEnumerator etorLinked = (IDictionaryEnumerator)htLinkedKeys.GetEnumerator();
- while (etorLinked.MoveNext())
- {
- LinkedKeyInfo lki = (LinkedKeyInfo)etorLinked.Value;
- writer.WriteStartElement(XmlConsts.linkedKeyNode);
-
- writer.WriteStartElement(XmlConsts.linkedTargetSecretNode);
- writer.WriteString(lki.GetLinkedSecretID().Substring(0, lki.GetLinkedSecretID().Length - 1));
- writer.WriteEndElement();
-
- writer.WriteStartElement(XmlConsts.linkedTargetKeyNode);
- writer.WriteString(lki.GetLinkedKeyID());
- writer.WriteEndElement();
-
- writer.WriteEndElement();
- }
- }
-
- writer.WriteEndElement();
- }
-
+ */
+
+ internal void PersistStore(string keyChainId)
+ {
+ string sPeristSecrets = null;
+
+ // is policy set to persist secrets
+ UIPol uiPolicy = (UIPol)ICASAPol.GetPolicy(CASAPolType.UI_POL, userStore.GetUserHomeDirectory(), userStore.GetUserName());
+ if (uiPolicy != null)
+ {
+ sPeristSecrets = uiPolicy.GetConfigSetting(ConstStrings.CONFIG_PERSIST_SECRETS);
+ }
+
+ if ((sPeristSecrets != null) && (sPeristSecrets.Equals("0")))
+ {
+ // delete .miCASA file and .IV file
+ if (keyChainId == ConstStrings.SSCS_SESSION_KEY_CHAIN_ID)
+ File.Delete(userStore.GetPersistenceFilePath());
+ else if (keyChainId == ConstStrings.SSCS_SERVER_KEY_CHAIN_ID)
+ File.Delete(userStore.GetServerSecretsPersistenceFilePath());
+ return;
+ }
+
+ //userStore.DumpSecretstore();
+ try
+ {
+ MemoryStream ms1 = GetSecretsAsXMLStream(this.userStore, keyChainId);
+ byte[] key = null;
+ string fileName = null;
+
+ if (keyChainId == ConstStrings.SSCS_SESSION_KEY_CHAIN_ID)
+ {
+ 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(), userStore.GetUserIdentifier());
+ fileName = userStore.GetServerSecretsPersistenceFilePath();
+ }
+
+ string tempFile = fileName;
+ // rename existing file
+ if (File.Exists(fileName))
+ {
+ if (File.Exists(tempFile + ".tmp"))
+ {
+ File.Delete(tempFile + ".tmp");
+ }
+ File.Move(fileName, tempFile + ".tmp");
+ }
+
+ CASACrypto.EncryptDataAndWriteToFile(ms1.ToArray(), key, fileName, userStore.GetUserIdentifier());
+
+ //remove temp
+ if (File.Exists(tempFile + ".tmp"))
+ {
+ File.Delete(tempFile + ".tmp");
+ }
+ }
+ catch (Exception e)
+ {
+ CSSSLogger.ExpLog(e.ToString());
+ }
+ }
+
+ internal static MemoryStream GetSecretsAsXMLStream(SecretStore userStore, string keyChainId)
+ {
+ try
+ {
+ MemoryStream ms1 = new MemoryStream();
+ XmlTextWriter writer = new XmlTextWriter(ms1, null);
+ writer.Formatting = Formatting.Indented;
+
+ writer.WriteStartDocument();
+ writer.WriteStartElement(XmlConsts.miCASANode);
+ writer.WriteAttributeString(XmlConsts.versionAttr, "1.5");
+
+ IDictionaryEnumerator iter = (IDictionaryEnumerator)userStore.GetKeyChainEnumerator();
+ char[] tmpId;
+ string sTmpId;
+ while (iter.MoveNext())
+ {
+ KeyChain kc = (KeyChain)iter.Value;
+ string kcId = kc.GetKey();
+ tmpId = new char[kcId.Length - 1];
+ for (int i = 0; i < kcId.Length - 1; i++)
+ tmpId[i] = kcId[i];
+ sTmpId = new string(tmpId);
+
+ if ((keyChainId != null) && (keyChainId != sTmpId))
+ continue;
+
+ writer.WriteStartElement(XmlConsts.keyChainNode);
+ writer.WriteAttributeString(XmlConsts.idAttr, sTmpId);
+ // If we need to store time
+ writer.WriteStartElement(XmlConsts.timeNode);
+ writer.WriteAttributeString(XmlConsts.createdTimeNode, kc.CreatedTime.ToUniversalTime().Ticks.ToString());
+ writer.WriteAttributeString(XmlConsts.modifiedTimeNode, kc.ModifiedTime.ToUniversalTime().Ticks.ToString());
+ writer.WriteEndElement();
+
+ PersistencePol policy = null;
+
+ IDictionaryEnumerator secIter = (IDictionaryEnumerator)(kc.GetAllSecrets());
+ while (secIter.MoveNext())
+ {
+ Secret secret = (Secret)secIter.Value;
+ writer.WriteStartElement(XmlConsts.secretNode);
+ string secretId = secret.GetKey();
+
+ tmpId = new char[secretId.Length - 1];
+ for (int i = 0; i < secretId.Length - 1; i++)
+ {
+ tmpId[i] = secretId[i];
+ }
+ sTmpId = new string(tmpId);
+
+ // TODO: Does Policy allow persisting this secret.
+ if (policy == null)
+ {
+ policy = (PersistencePol)ICASAPol.GetPolicy(CASAPolType.PERSISTENCE_POL, userStore.GetUserHomeDirectory(), userStore.GetUserName());
+ }
+
+ bool bSaveValues = true;
+ if (policy != null)
+ {
+ if (policy.GetSecretPolicy(sTmpId, "Persistent", "True").Equals("False"))
+ {
+ //continue;
+ bSaveValues = false;
+ }
+ }
+
+ writer.WriteAttributeString(XmlConsts.idAttr, sTmpId);
+ // If we need to store time
+ writer.WriteStartElement(XmlConsts.timeNode);
+ writer.WriteAttributeString(XmlConsts.createdTimeNode, secret.CreatedTime.ToUniversalTime().Ticks.ToString());
+ writer.WriteAttributeString(XmlConsts.modifiedTimeNode, secret.ModifiedTime.ToUniversalTime().Ticks.ToString());
+ writer.WriteEndElement();
+
+ writer.WriteStartElement(XmlConsts.valueNode);
+ // byte[] byteArr = secret.GetValue();
+
+ IDictionaryEnumerator etor = (IDictionaryEnumerator)secret.GetKeyValueEnumerator();
+ while (etor.MoveNext())
+ {
+ string sKey = (string)etor.Key;
+ KeyValue kv = secret.GetKeyValue(sKey);
+ if (!kv.IsPersistent)
+ {
+ continue;
+ }
+
+ string value = kv.GetValue();
+ writer.WriteStartElement(XmlConsts.keyNode);
+ writer.WriteAttributeString(XmlConsts.idAttr, sKey);
+ if (kv.GetValueType() == KeyValue.VALUE_TYPE_BINARY)
+ {
+ writer.WriteAttributeString(XmlConsts.binaryAttr, "true");
+ }
+
+ writer.WriteStartElement(XmlConsts.keyValueNode);
+
+ if (bSaveValues)
+ {
+ if (kv.GetValueType() == KeyValue.VALUE_TYPE_BINARY)
+ {
+ writer.WriteString(Convert.ToBase64String(kv.GetValueAsBytes()));
+ }
+ else
+ {
+ writer.WriteString(value);
+ }
+ }
+ else
+ writer.WriteString("");
+
+ writer.WriteEndElement();
+ // If we need to store time
+ writer.WriteStartElement(XmlConsts.timeNode);
+ writer.WriteAttributeString(XmlConsts.createdTimeNode, (secret.GetKeyValueCreatedTime(sKey)).ToUniversalTime().Ticks.ToString());
+ writer.WriteAttributeString(XmlConsts.modifiedTimeNode, (secret.GetKeyValueModifiedTime(sKey)).ToUniversalTime().Ticks.ToString());
+ writer.WriteEndElement();
+
+ // write all LinkKeys
+ Hashtable htLinkedKeys = secret.GetLinkedKeys(sKey);
+ if (htLinkedKeys != null)
+ {
+ IDictionaryEnumerator etorLinked = (IDictionaryEnumerator)htLinkedKeys.GetEnumerator();
+ while (etorLinked.MoveNext())
+ {
+ LinkedKeyInfo lki = (LinkedKeyInfo)etorLinked.Value;
+ writer.WriteStartElement(XmlConsts.linkedKeyNode);
+
+ writer.WriteStartElement(XmlConsts.linkedTargetSecretNode);
+ writer.WriteString(lki.GetLinkedSecretID().Substring(0, lki.GetLinkedSecretID().Length - 1));
+ writer.WriteEndElement();
+
+ writer.WriteStartElement(XmlConsts.linkedTargetKeyNode);
+ writer.WriteString(lki.GetLinkedKeyID());
+ writer.WriteEndElement();
+
+ writer.WriteEndElement();
+ }
+ }
+
+ writer.WriteEndElement();
+ }
+
/*
char[] chArr = new char[byteArr.Length];
for(int z = 0; z < byteArr.Length; z++)
@@ -861,24 +790,24 @@ namespace sscs.lss
string stringToStore = new string(chArr);
writer.WriteString(stringToStore);
- */
-
- writer.WriteEndElement(); //end of value node
- writer.WriteEndElement();
- }
- writer.WriteEndElement(); //keychain
- }
-
- writer.WriteEndElement(); //miCASA node
- writer.WriteEndDocument();
- writer.Flush();
- writer.Close();
- return ms1;
- }
- catch (Exception e)
- {
- throw e;
- }
- }
- }
-}
+ */
+
+ writer.WriteEndElement(); //end of value node
+ writer.WriteEndElement();
+ }
+ writer.WriteEndElement(); //keychain
+ }
+
+ writer.WriteEndElement(); //miCASA node
+ writer.WriteEndDocument();
+ writer.Flush();
+ writer.Close();
+ return ms1;
+ }
+ catch (Exception e)
+ {
+ throw e;
+ }
+ }
+ }
+}
diff --git a/CASA/micasad/lss/Rfc2898DeriveBytes.cs b/CASA/micasad/lss/Rfc2898DeriveBytes.cs
index 7e62f996..9566dfaf 100644
--- a/CASA/micasad/lss/Rfc2898DeriveBytes.cs
+++ b/CASA/micasad/lss/Rfc2898DeriveBytes.cs
@@ -20,312 +20,326 @@
*
***********************************************************************/
-//
-// Rfc2898DeriveBytes.cs: RFC2898 (PKCS#5 v2) Key derivation for Password Based Encryption
-//
-// Author:
-// Sebastien Pouliot (sebastien@ximian.com)
-//
-// (C) 2003 Motus Technologies Inc. (http://www.motus.com)
-// Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-
-
-
-//using System.Runtime.InteropServices;
-using System;
-using System.Text;
-using System.IO;
-using System.Security.Cryptography;
-
-using sscs.lss;
-using sscs.common;
-
-namespace sscs.crypto {
-
- //[ComVisible (true)]
- public class Rfc2898DeriveBytes : DeriveBytes {
-
- private const int defaultIterations = 1000;
-
- private int _iteration;
- private byte[] _salt;
- private HMACSHA1 _hmac;
- private byte[] _buffer;
- private int _pos;
- private int _f;
-
- // constructors
-
- public Rfc2898DeriveBytes (string password, byte[] salt)
- : this (password, salt, defaultIterations)
- {
- }
-
- public Rfc2898DeriveBytes (string password, byte[] salt, int iterations)
- {
- if (password == null)
- throw new ArgumentNullException ("password");
-
- Salt = salt;
- IterationCount = iterations;
- _hmac = new HMACSHA1 (Encoding.UTF8.GetBytes (password));
- }
-
- public Rfc2898DeriveBytes (byte[] password, byte[] salt, int iterations)
- {
- if (password == null)
- throw new ArgumentNullException ("password");
-
- Salt = salt;
- IterationCount = iterations;
- _hmac = new HMACSHA1 (password);
- }
-
- public Rfc2898DeriveBytes (string password, int saltSize)
- : this (password, saltSize, defaultIterations)
- {
- }
-
- public Rfc2898DeriveBytes(string password, int saltSize, int iterations)
- : this (password, saltSize, iterations, false, null, false)
- {
- }
-
- public Rfc2898DeriveBytes (string password, int saltSize, int iterations, bool bUseOldMethod, string sFilepath, bool bGenerateAndSaveRandomSalt)
- {
- if (password == null)
- throw new ArgumentNullException ("password");
- if (saltSize < 0)
- throw new ArgumentOutOfRangeException ("invalid salt length");
-
- if (bUseOldMethod)
- {
- Salt = GenerateOldSalt(password, saltSize);
- }
- else
- {
- if (bGenerateAndSaveRandomSalt)
- {
- Salt = GenerateAndSaveRandomSalt(saltSize, sFilepath);
- }
- else
- {
- // load saved salt if one was saved
- if ((sFilepath != null) && (File.Exists(sFilepath + ".salt")))
- {
- Salt = LoadSavedSalt(sFilepath);
- }
- else
- {
- Salt = GenerateNewSalt(password, saltSize);
- }
- }
- }
-
- IterationCount = iterations;
- _hmac = new HMACSHA1 (Encoding.UTF8.GetBytes (password));
- }
-
- private byte[] GenerateAndSaveRandomSalt(int saltSize, string sFilepath)
- {
- byte[] randomSalt = new byte[saltSize];
- FastRandom fr = new FastRandom();
- fr.NextBytes(randomSalt);
-
- // save salt
- try
- {
-
- FileStream fs = new FileStream(sFilepath + ".salt", FileMode.OpenOrCreate);
- fs.Write(randomSalt, 0, randomSalt.Length);
- fs.Flush();
- fs.Close();
-
- File.SetAttributes(sFilepath + ".salt", FileAttributes.Hidden);
-
- }
- catch (Exception e)
- {
- CSSSLogger.DbgLog(e.ToString());
- }
-
- return randomSalt;
- }
-
- private byte[] LoadSavedSalt(string sFilePath)
- {
- byte[] baSalt = null;
-
- try
- {
- FileStream fs = new FileStream(sFilePath + ".salt", FileMode.Open);
- baSalt = new byte[fs.Length];
- fs.Read(baSalt, 0, (int)fs.Length);
- fs.Close();
- }
- catch (Exception e)
- {
- CSSSLogger.DbgLog(e.ToString());
- }
- return baSalt;
- }
-
- private static byte[] GenerateOldSalt(string password, int saltSize)
- {
- byte[] buffer = new byte[saltSize];
- Random rand = new Random(password.GetHashCode());
- rand.NextBytes(buffer);
- return buffer;
- }
-
- private static byte[] GenerateNewSalt(string password, int saltSize)
- {
- int j = 0;
- byte[] buffer = new byte[saltSize];
-
- // iterate thru each character, creating a new Random,
- // getting 2 bytes from each, until our salt buffer is full.
- for (int i = 0; i < password.Length;)
- {
- char letter = password[i];
- int iLetter = (int)letter;
-
- FastRandom ranNum = new FastRandom(iLetter * (j+1));
- byte[] temp = new byte[2];
- ranNum.NextBytes(temp);
-
- for (int k = 0; k < temp.Length; k++)
- {
- buffer[j++] = temp[k];
- // get out if buffer is full
- if (j >= saltSize)
- {
- return buffer;
- }
- }
-
- i++;
-
- // reset i if at end of password
- if ((i + 1) > password.Length)
- {
- i = 0;
- }
-
-
- }
-
- return buffer;
- }
-
- // properties
- public int IterationCount
- {
- get { return _iteration; }
- set {
- if (value < 1)
- throw new ArgumentOutOfRangeException ("IterationCount < 1");
-
- _iteration = value;
- }
- }
-
- public byte[] Salt {
- get { return (byte[]) _salt.Clone (); }
- set {
- if (value == null)
- throw new ArgumentNullException ("Salt");
- if (value.Length < 8)
- throw new ArgumentException ("Salt < 8 bytes");
-
- _salt = (byte[])value.Clone ();
- }
- }
-
- // methods
-
- private byte[] F (byte[] s, int c, int i)
- {
- byte[] data = new byte [s.Length + 4];
- Buffer.BlockCopy (s, 0, data, 0, s.Length);
- byte[] int4 = BitConverter.GetBytes (i);
- Array.Reverse (int4, 0, 4);
- Buffer.BlockCopy (int4, 0, data, s.Length, 4);
-
- // this is like j=0
- byte[] u1 = _hmac.ComputeHash (data);
- data = u1;
- // so we start at j=1
- for (int j=1; j < c; j++) {
- byte[] un = _hmac.ComputeHash (data);
- // xor
- for (int k=0; k < 20; k++)
- u1 [k] = (byte)(u1 [k] ^ un [k]);
- data = un;
- }
- return u1;
- }
-
- public override byte[] GetBytes (int cb)
- {
- if (cb < 1)
- throw new ArgumentOutOfRangeException ("cb");
-
- int l = cb / 20; // HMACSHA1 == 160 bits == 20 bytes
- int r = cb % 20; // remainder
- if (r != 0)
- l++; // rounding up
-
- byte[] result = new byte [cb];
- int rpos = 0;
- if (_pos > 0) {
- int count = Math.Min (20 - _pos, cb);
- Buffer.BlockCopy (_buffer, _pos, result, 0, count);
- if (count >= cb)
- return result;
- _pos = 0;
- rpos = 20 - cb;
- r = cb - rpos;
- }
-
- for (int i=1; i <= l; i++) {
- _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;
- }
- }
-}
-
-
+//
+// Rfc2898DeriveBytes.cs: RFC2898 (PKCS#5 v2) Key derivation for Password Based Encryption
+//
+// Author:
+// Sebastien Pouliot (sebastien@ximian.com)
+//
+// (C) 2003 Motus Technologies Inc. (http://www.motus.com)
+// Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+
+
+//using System.Runtime.InteropServices;
+using System;
+using System.Text;
+using System.IO;
+using System.Security.Cryptography;
+
+using sscs.lss;
+using sscs.common;
+
+namespace sscs.crypto {
+
+ //[ComVisible (true)]
+ public class Rfc2898DeriveBytes : DeriveBytes {
+
+ private const int defaultIterations = 1000;
+
+ private int _iteration;
+ private byte[] _salt;
+ private HMACSHA1 _hmac;
+ private byte[] _buffer;
+ private int _pos;
+ private int _f;
+
+ // constructors
+
+ public Rfc2898DeriveBytes (string password, byte[] salt)
+ : this (password, salt, defaultIterations)
+ {
+ }
+
+ public Rfc2898DeriveBytes (string password, byte[] salt, int iterations)
+ {
+ if (password == null)
+ throw new ArgumentNullException ("password");
+
+ Salt = salt;
+ IterationCount = iterations;
+ _hmac = new HMACSHA1 (Encoding.UTF8.GetBytes (password));
+ }
+
+ public Rfc2898DeriveBytes (byte[] password, byte[] salt, int iterations)
+ {
+ if (password == null)
+ throw new ArgumentNullException ("password");
+
+ Salt = salt;
+ IterationCount = iterations;
+ _hmac = new HMACSHA1 (password);
+ }
+
+ public Rfc2898DeriveBytes (string password, int saltSize)
+ : this (password, saltSize, defaultIterations)
+ {
+ }
+
+ public Rfc2898DeriveBytes(string password, int saltSize, int iterations)
+ : this (password, saltSize, iterations, false, null, false, null)
+ {
+ }
+
+ public Rfc2898DeriveBytes (string password, int saltSize, int iterations, bool bUseOldMethod, string sFilepath, bool bGenerateAndSaveRandomSalt, UserIdentifier userID)
+ {
+ if (password == null)
+ throw new ArgumentNullException ("password");
+ if (saltSize < 0)
+ throw new ArgumentOutOfRangeException ("invalid salt length");
+
+ if (bUseOldMethod)
+ {
+ Salt = GenerateOldSalt(password, saltSize);
+ }
+ else
+ {
+ if (bGenerateAndSaveRandomSalt)
+ {
+ Salt = GenerateAndSaveRandomSalt(saltSize, sFilepath, userID);
+ }
+ else
+ {
+ // load saved salt if one was saved
+ if ((sFilepath != null) && (File.Exists(sFilepath + ".salt")))
+ {
+ Salt = LoadSavedSalt(sFilepath, userID);
+ }
+ else
+ {
+ Salt = GenerateNewSalt(password, saltSize);
+ }
+ }
+ }
+
+ IterationCount = iterations;
+ _hmac = new HMACSHA1 (Encoding.UTF8.GetBytes (password));
+ }
+
+ private byte[] GenerateAndSaveRandomSalt(int saltSize, string sFilepath, UserIdentifier userID)
+ {
+ byte[] randomSalt = new byte[saltSize];
+ FastRandom fr = new FastRandom();
+ fr.NextBytes(randomSalt);
+
+ // save salt
+ try
+ {
+
+ FileStream fs = new FileStream(sFilepath + ".salt", FileMode.OpenOrCreate);
+ fs.Write(randomSalt, 0, randomSalt.Length);
+ fs.Flush();
+ fs.Close();
+
+ 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)
+ {
+ CSSSLogger.DbgLog(e.ToString());
+ }
+
+ return randomSalt;
+ }
+
+ 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);
+ fs.Close();
+ }
+ catch (Exception e)
+ {
+ CSSSLogger.DbgLog(e.ToString());
+ }
+ return baSalt;
+ }
+
+ private static byte[] GenerateOldSalt(string password, int saltSize)
+ {
+ byte[] buffer = new byte[saltSize];
+ Random rand = new Random(password.GetHashCode());
+ rand.NextBytes(buffer);
+ return buffer;
+ }
+
+ private static byte[] GenerateNewSalt(string password, int saltSize)
+ {
+ int j = 0;
+ byte[] buffer = new byte[saltSize];
+
+ // iterate thru each character, creating a new Random,
+ // getting 2 bytes from each, until our salt buffer is full.
+ for (int i = 0; i < password.Length;)
+ {
+ char letter = password[i];
+ int iLetter = (int)letter;
+
+ FastRandom ranNum = new FastRandom(iLetter * (j+1));
+ byte[] temp = new byte[2];
+ ranNum.NextBytes(temp);
+
+ for (int k = 0; k < temp.Length; k++)
+ {
+ buffer[j++] = temp[k];
+ // get out if buffer is full
+ if (j >= saltSize)
+ {
+ return buffer;
+ }
+ }
+
+ i++;
+
+ // reset i if at end of password
+ if ((i + 1) > password.Length)
+ {
+ i = 0;
+ }
+
+
+ }
+
+ return buffer;
+ }
+
+ // properties
+ public int IterationCount
+ {
+ get { return _iteration; }
+ set {
+ if (value < 1)
+ throw new ArgumentOutOfRangeException ("IterationCount < 1");
+
+ _iteration = value;
+ }
+ }
+
+ public byte[] Salt {
+ get { return (byte[]) _salt.Clone (); }
+ set {
+ if (value == null)
+ throw new ArgumentNullException ("Salt");
+ if (value.Length < 8)
+ throw new ArgumentException ("Salt < 8 bytes");
+
+ _salt = (byte[])value.Clone ();
+ }
+ }
+
+ // methods
+
+ private byte[] F (byte[] s, int c, int i)
+ {
+ byte[] data = new byte [s.Length + 4];
+ Buffer.BlockCopy (s, 0, data, 0, s.Length);
+ byte[] int4 = BitConverter.GetBytes (i);
+ Array.Reverse (int4, 0, 4);
+ Buffer.BlockCopy (int4, 0, data, s.Length, 4);
+
+ // this is like j=0
+ byte[] u1 = _hmac.ComputeHash (data);
+ data = u1;
+ // so we start at j=1
+ for (int j=1; j < c; j++) {
+ byte[] un = _hmac.ComputeHash (data);
+ // xor
+ for (int k=0; k < 20; k++)
+ u1 [k] = (byte)(u1 [k] ^ un [k]);
+ data = un;
+ }
+ return u1;
+ }
+
+ public override byte[] GetBytes (int cb)
+ {
+ if (cb < 1)
+ throw new ArgumentOutOfRangeException ("cb");
+
+ int l = cb / 20; // HMACSHA1 == 160 bits == 20 bytes
+ int r = cb % 20; // remainder
+ if (r != 0)
+ l++; // rounding up
+
+ byte[] result = new byte [cb];
+ int rpos = 0;
+ if (_pos > 0) {
+ int count = Math.Min (20 - _pos, cb);
+ Buffer.BlockCopy (_buffer, _pos, result, 0, count);
+ if (count >= cb)
+ return result;
+ _pos = 0;
+ rpos = 20 - cb;
+ r = cb - rpos;
+ }
+
+ for (int i=1; i <= l; i++) {
+ _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;
+ }
+ }
+}
+
+