Moving micasa 1.5 trunk to Novell forge.

This commit is contained in:
Cameron (Kamran) Mashayekhi
2005-10-11 19:51:00 +00:00
parent 082db33275
commit efe0a5e13c
691 changed files with 116628 additions and 0 deletions

20
c_micasad/Makefile Normal file
View File

@@ -0,0 +1,20 @@
#
# configure environment
#
TARGET = micasad
CS_NAME = $(TARGET)$(xtra).$(EXE)
include global.mak
include defaults.$(PLAT)
include rules.mak
#
# target object and source files
#
include src.$(PLAT)
include objs.$(PLAT)
#
# targets
#
include target.cs

15
c_micasad/cache/IKeychain.cs vendored Normal file
View File

@@ -0,0 +1,15 @@
using System;
using System.Collections;
namespace sscs.cache
{
interface IKeychain
{
void AddSecret(Secret mySecret);
void RemoveSecret(String secretID);
Secret GetSecret(string secretID);
// IEnumerator getAllSecrets();
}
}

14
c_micasad/cache/ISecret.cs vendored Normal file
View File

@@ -0,0 +1,14 @@
using System;
namespace sscs.cache
{
interface ISecret
{
//Setter methods
void SetValue(byte[] key);
void SetKey(String newkey);
//Get methods
byte[] GetValue(String key);
string GetKey();
}
}

136
c_micasad/cache/KeyChain.cs vendored Normal file
View File

@@ -0,0 +1,136 @@
using System;
using System.Collections;
using System.Threading;
using sscs.common;
namespace sscs.cache
{
class KeyChain : IKeychain
{
//We can have a Arraylist in case we dont need to look up via SecretID
// Hashtable has [SecretID(string), Secret(class)]
private Hashtable tSecretList = new Hashtable();
private Hashtable SecretList; // = Hashtable.Synchronized(tSecretList);
private string keyChainId;
private DateTime createdTime;
internal DateTime CreatedTime
{
get
{
return createdTime;
}
set
{
createdTime = value;
}
}
private DateTime accessedTime;
internal DateTime AccessedTime
{
get
{
return accessedTime;
}
set
{
accessedTime = value;
}
}
private DateTime modifiedTime;
internal DateTime ModifiedTime
{
get
{
return modifiedTime;
}
set
{
modifiedTime = value;
}
}
internal KeyChain()
{
SecretList = Hashtable.Synchronized(tSecretList);
}
internal KeyChain(string keyChainId)
{
SecretList = Hashtable.Synchronized(tSecretList);
this.keyChainId = keyChainId;
}
~KeyChain()
{
}
public void SetKey(string value)
{
keyChainId = value;
}
public void AddSecret(Secret mySecret)
{
try
{
mySecret.CreatedTime = DateTime.Now;
SecretList.Add((mySecret.GetKey()), mySecret);
this.ModifiedTime = DateTime.Now;
}
catch(Exception e)
{
CSSSLogger.ExpLog(e.ToString());
throw e;
}
}
public void RemoveSecret(String secretID)
{
SecretList.Remove(secretID);
this.ModifiedTime = DateTime.Now;
}
public void RemoveAllSecrets()
{
SecretList.Clear();
}
public Secret GetSecret(string secretID)
{
if(SecretList.ContainsKey(secretID))
{
Secret secret = (Secret)SecretList[secretID];
secret.AccessedTime = DateTime.Now;
return secret;
}
else
throw new SecretNotFoundException(secretID);
}
internal string GetKey()
{
return keyChainId;
}
internal IEnumerator GetAllSecrets()
{
return SecretList.GetEnumerator();
}
internal int GetNumSecrets()
{
return SecretList.Count;
}
internal bool CheckIfSecretExists(string id)
{
if( SecretList.ContainsKey(id) )
return true;
else
return false;
}
}
}

170
c_micasad/cache/KeyValue.cs vendored Normal file
View File

@@ -0,0 +1,170 @@
using System;
using System.Text;
using System.Collections;
using Novell.CASA.MiCasa.Common;
namespace sscs.cache
{
public class KeyValue
{
private string m_key;
public string Key
{
get
{
return m_key;
}
set
{
m_key = value;
}
}
private byte[] m_value;
public string GetValue()
{
return (DecryptValue());
}
public void SetValue(string sValue)
{
string oldValue = DecryptValue();
if (oldValue.Equals(sValue))
return;
else
{
byte[] newEncryptedValue = EncryptValue(sValue);
m_value = newEncryptedValue;
m_modified = DateTime.Now;
}
}
/*
public string Value
{
get
{
// decrypt
return (DecryptValue());
}
set
{
byte[] newEncrypteValue = EncryptValue(value);
if ((newEncrypteValue != null) && (newEncrypteValue.Equals(m_value)))
return;
else
{
m_value = newEncrypteValue;
m_modified = DateTime.Now;
}
}
}
*/
private Hashtable mLinkedKeys = null; // = new Hashtable();
public void AddLink(LinkedKeyInfo linkedInfo)
{
if (mLinkedKeys == null)
mLinkedKeys = new Hashtable();
if(!mLinkedKeys.ContainsKey(linkedInfo.GetLinkID()))
mLinkedKeys.Add(linkedInfo.GetLinkID(), linkedInfo);
}
public void RemoveLink(string sLinkID)
{
// remove link
if (mLinkedKeys != null)
{
mLinkedKeys.Remove(sLinkID);
}
}
public Hashtable GetLinkedKeys()
{
return mLinkedKeys;
}
private DateTime m_created;
public DateTime CreatedTime
{
get
{
return m_created;
}
}
private DateTime m_modified;
public DateTime ModifiedTime
{
get
{
return m_modified;
}
}
public KeyValue(string sKey, string sValue)
{
// NOTE: Order is important, do not change
m_created = m_modified = DateTime.Now;
m_key = sKey;
m_value = EncryptValue(sValue);
}
private byte[] EncryptValue(string sValue)
{
byte[] baValueClear = Encoding.Default.GetBytes(sValue);
return (XORValue(baValueClear));
}
private string DecryptValue()
{
byte[] baValueClear = XORValue(m_value);
return Encoding.Default.GetString(baValueClear);
}
private byte[] XORValue(byte[] baInput)
{
byte[] baOutput = new byte[baInput.Length];
Random rand = new Random((int)m_created.Ticks);
for (int i=0; i<baInput.Length; i++)
{
baOutput[i] = (byte)((int)baInput[i] ^ rand.Next());
}
return baOutput;
}
public string ToXML()
{
StringBuilder sb = new StringBuilder();
sb.Append("<ENTRY>");
sb.Append("<KEY>");
sb.Append(m_key);
sb.Append("</KEY>");
sb.Append("<VALUE>");
sb.Append(m_value);
sb.Append("</VALUE>");
sb.Append("<MODIFIED>");
sb.Append(m_modified.Ticks);
sb.Append("</MODIFIED>");
sb.Append("</ENTRY>");
return sb.ToString();
}
}
}

318
c_micasad/cache/Secret.cs vendored Normal file
View File

@@ -0,0 +1,318 @@
using System;
using System.Text;
using System.Collections;
namespace sscs.cache
{
class Secret : ISecret
{
private string secretID;
//private byte[] data;
string ePasswd ; // TBD
DateTime createdTime;
public DateTime CreatedTime
{
get
{
return createdTime;
}
set
{
createdTime = value;
}
}
DateTime accessedTime;
public DateTime AccessedTime
{
get
{
return accessedTime;
}
set
{
accessedTime = value;
}
}
DateTime modifiedTime;
public DateTime ModifiedTime
{
get
{
return modifiedTime;
}
set
{
modifiedTime = value;
}
}
private Hashtable htKeyValues = new Hashtable();
internal Secret()
{
}
internal Secret(string secretID)
{
this.secretID = secretID;
}
internal Secret(string secretID, byte[] data)
{
this.secretID = secretID;
//this.data = data;
// parse the data
ParseDataBuffer(data);
}
internal Secret(string secretID, byte[] data, string ePasswd)
{
this.secretID = secretID;
this.ePasswd = ePasswd;
ParseDataBuffer(data);
}
internal void ParseDataBuffer(byte[] data)
{
if (data != null)
{
UTF8Encoding dec = new UTF8Encoding();
string theData = dec.GetString(data);
char[] theChars = new char[2];
theChars[0] = '\n';
theChars[1] = '\0';
String[] keyValues = theData.Split(theChars);
char delimiter = '=';
foreach (string keyValue in keyValues)
{
int iLocation = keyValue.IndexOf(delimiter);
if (iLocation > 0)
{
String key = keyValue.Substring(0, iLocation);
String value = keyValue.Substring(iLocation + 1);
if (key != null && value != null)
this.SetKeyValue(key, value);
}
}
}
}
internal void SetEpasswd(string value)
{
ePasswd = value;
}
internal string GetEpasswd()
{
return ePasswd;
}
public void SetValue(byte[] data)
{
this.ModifiedTime = DateTime.Now;
ParseDataBuffer(data);
}
public void SetKey(String newkey)
{
//Validation TBD
this.secretID = newkey;
}
//Get methods
public byte[] GetValue(String key)
{
//validation TBD
//if (data == null)
{
StringBuilder sb = new StringBuilder();
IDictionaryEnumerator etor = (IDictionaryEnumerator)this.htKeyValues.GetEnumerator();
while(etor.MoveNext())
{
string sKey = (string)etor.Key;
KeyValue kv = (KeyValue)this.htKeyValues[sKey];
sb.Append(kv.Key);
sb.Append("=");
sb.Append(kv.GetValue());
sb.Append('\n');
}
//sb.Append('\0');
UTF8Encoding enc = new UTF8Encoding();
this.AccessedTime = DateTime.Now;
return (enc.GetBytes(sb.ToString()));
}
//else
// return data;
}
public byte[] GetValue()
{
//validation TBD
this.AccessedTime = DateTime.Now;
return GetValue(null);
}
public string GetKey()
{
return secretID;
}
public void SetKeyValue(string key, string value)
{
KeyValue kv;
if (htKeyValues.Contains(key))
{
kv = (KeyValue)htKeyValues[key];
kv.SetValue(value);
}
else
{
kv = new KeyValue(key, value);
htKeyValues.Add(key, kv);
}
this.ModifiedTime = DateTime.Now;
}
public KeyValue GetKeyValue(string key)
{
this.AccessedTime = DateTime.Now;
if (htKeyValues.Contains(key))
{
KeyValue kv = (KeyValue)htKeyValues[key];
return kv;
}
else
return null;
}
public void RemoveKeyValue(string key)
{
if (htKeyValues.Contains(key))
{
htKeyValues.Remove(key);
}
}
public DateTime GetKeyValueCreatedTime(string key)
{
if (htKeyValues.Contains(key))
{
KeyValue kv = (KeyValue)htKeyValues[key];
return kv.CreatedTime;
}
else
return (new DateTime(0));
}
public Hashtable GetLinkedKeys(string keyId)
{
if (htKeyValues.Contains(keyId))
{
KeyValue kv = (KeyValue)htKeyValues[keyId];
return kv.GetLinkedKeys();
}
else
return null;
}
public DateTime GetKeyValueModifiedTime(string key)
{
if (htKeyValues.Contains(key))
{
KeyValue kv = (KeyValue)htKeyValues[key];
return kv.ModifiedTime;
}
else
return (new DateTime(0));
}
public void MergeSecret(Secret newSecret)
{
IDictionaryEnumerator etor = (IDictionaryEnumerator)newSecret.htKeyValues.GetEnumerator();
while(etor.MoveNext())
{
string sKey = (string)etor.Key;
// TODO: When we sync, we should consider modified time as well
KeyValue newKV = (KeyValue)newSecret.htKeyValues[sKey];
this.SetKeyValue(newKV.Key, newKV.GetValue());
}
etor = (IDictionaryEnumerator)newSecret.htKeyValues.GetEnumerator();
while(etor.MoveNext())
{
string sKey = (string)etor.Key;
if(!htKeyValues.Contains(sKey))
this.RemoveKeyValue(sKey);
}
}
public ArrayList GetKeyList()
{
IDictionaryEnumerator etor = (IDictionaryEnumerator)this.htKeyValues.GetEnumerator();
ArrayList list = new ArrayList();
if( null == etor )
{
return null;
}
while(etor.MoveNext())
{
string key = (string)etor.Key;
list.Add(key);
}
return list;
}
internal IDictionaryEnumerator GetKeyValueEnumerator()
{
if( htKeyValues != null)
return htKeyValues.GetEnumerator();
else
return null;
}
public string ToXML()
{
StringBuilder sb = new StringBuilder();
sb.Append("<SECRET>");
sb.Append("<ID>");
sb.Append(secretID);
sb.Append("</ID>");
sb.Append("<DATA>");
// enum the htKeyValues list
//IDictionaryEnumerator ienum = htKeyValues.GetEnumerator();
ICollection coll = htKeyValues.Values;
IDictionaryEnumerator ienum = (IDictionaryEnumerator)coll.GetEnumerator();
KeyValue kv = (KeyValue)ienum.Current;
while (kv != null)
{
sb.Append(kv.ToXML());
if (ienum.MoveNext())
kv = (KeyValue)ienum.Value;
else
kv = null;
}
sb.Append("</DATA>");
sb.Append("</SECRET>");
return sb.ToString();
}
}
}

603
c_micasad/cache/SecretStore.cs vendored Normal file
View File

@@ -0,0 +1,603 @@
using System;
using System.Collections;
using System.Threading;
using System.IO;
using System.Xml;
using System.Xml.Serialization;
using System.Security.Cryptography;
using System.Text;
using sscs.cache;
using sscs.common;
using sscs.constants;
using sscs.lss;
using sscs.crypto;
namespace sscs.cache
{
class SecretStore
{
internal string secretStoreName; // User name ?
internal int refCount;
private uint version;
private Hashtable tKeyChainList = new Hashtable();
private Hashtable keyChainList; //= Hashtable.Synchronized(tKeyChainList);
internal User user;
private Mutex ssMutex ; //reqd only for refCount
private int state; // Maintains the state of SS ( keychain
// type availability). TODO: Convert to a class.
private static int STATE_NOT_DEFINED = 0;
private static int STATE_OK = 1;
private static int STATE_LOCKED = 2;
private LocalStorage lss = null;
bool bIsStorePersistent = false;
private DateTime createTime;
public DateTime CreateTime
{
get
{
return createTime;
}
set
{
createTime = value;
}
}
~SecretStore()
{
ssMutex.Close();
}
internal SecretStore(User ssUser)
{
secretStoreName = ssUser.GetUserName();
version = 1;
state = STATE_NOT_DEFINED;
user = ssUser;
refCount = 0;
keyChainList = Hashtable.Synchronized(tKeyChainList);
ssMutex = new Mutex();
}
internal bool IsStorePersistent()
{
return bIsStorePersistent;
}
public bool StopPersistence()
{
if(lss != null && bIsStorePersistent == true)
{
lss.StopPersistence();
lss = null;
bIsStorePersistent = false;
}
return true;
}
public bool IsStoreLocked()
{
if (state == STATE_LOCKED)
return true;
else
return false;
}
public void LockStore()
{
state = STATE_LOCKED;
}
public bool UnlockStore(string sDesktopPassword, string sMasterPassword)
{
if (sDesktopPassword != null)
{
// verify Desktop password
state = STATE_OK;
return true;
}
if (sMasterPassword != null)
{
// verify MasterPassword
state = STATE_OK;
return true;
}
return false;
}
internal bool StartPersistenceByDesktopPasswd(string desktopPasswd)
{
try
{
byte[] baPasscode;
/* Persistence could have started because the user
* could have set master password.
*/
if(lss != null && bIsStorePersistent == true)
{
/* Verify passcode and if validation fails, rewrite
* desktop file.
*/
if(File.Exists(GetPasscodeByDesktopFilePath()))
{
}
else
{
/* Write the desktop passwd file.
*/
}
CSSSLogger.DbgLog(CSSSLogger.GetExecutionPath(this) + " Store is already persistent");
return true;
}
if(!File.Exists(GetPasscodeByDesktopFilePath()))
{
//Else passcode needs to be generated.
baPasscode = CASACrypto.GenerateMasterPasscodeUsingString(
desktopPasswd,
GetPasscodeByDesktopFilePath(),
GetValidationFilePath(),
user.UserIdentifier);
if( null == baPasscode )
return false;
if(!File.Exists(GetKeyFilePath()))
{
RijndaelManaged myRijndael = new RijndaelManaged();
byte[] key;
byte[] IV = new byte[16];
//Create a new key and initialization vector.
myRijndael.GenerateKey();
key = myRijndael.Key;
CASACrypto.StoreKeySetUsingMasterPasscode(key,IV,
baPasscode,
GetKeyFilePath());
}
lss = new LocalStorage(this,baPasscode);
bIsStorePersistent = true;
return true;
}
baPasscode = CASACrypto.GetMasterPasscodeUsingDesktopPasswd(desktopPasswd, GetPasscodeByDesktopFilePath());
if(baPasscode != null)
{
if(CASACrypto.ValidatePasscode(baPasscode,GetValidationFilePath()))
{
lss = new LocalStorage(this,baPasscode);
bIsStorePersistent = true;
return true;
}
else
{
lss = null;
bIsStorePersistent = false; //till masterPasswd is verified
}
return true;
}
else
{
CSSSLogger.DbgLog(CSSSLogger.GetExecutionPath(this) + " May be desktop passwd has changed");
lss = null;
bIsStorePersistent = false;
return false;
}
}
catch(Exception e)
{
CSSSLogger.ExpLog(e.ToString());
}
return false;
}
internal bool SetMasterPassword(string mPasswdFromIDK)
{
try
{
char[] trimChars = {'\0'};
string mPasswd = mPasswdFromIDK.TrimEnd(trimChars);
bool isVerifyOperation = false;
string mPasswdFileName = GetPasscodeByMasterPasswdFilePath();
byte[] baPasscode;
if(File.Exists(mPasswdFileName))
isVerifyOperation = true; //else it is a set operation.
string desktopPasswd = GetDesktopPasswd();
if(isVerifyOperation == false)
{
/* Here the master password file needs to be generated.
*/
if(desktopPasswd != null)
{
baPasscode = CASACrypto.GetMasterPasscodeUsingDesktopPasswd(desktopPasswd, GetPasscodeByDesktopFilePath());
if(CASACrypto.ValidatePasscode(baPasscode,GetValidationFilePath()))
{
CASACrypto.EncryptAndStoreMasterPasscodeUsingString(
baPasscode,
mPasswd,
GetPasscodeByMasterPasswdFilePath());
return true;
}
else
{
//Probably desktop passwd has changed.
//But as even master passwd is being set only now,
//the persistent store is lost.
baPasscode = CASACrypto.GenerateMasterPasscodeUsingString(mPasswd,GetPasscodeByMasterPasswdFilePath(),GetValidationFilePath(), user.UserIdentifier);
if(baPasscode != null)
{
CASACrypto.EncryptAndStoreMasterPasscodeUsingString(baPasscode,mPasswd,GetPasscodeByMasterPasswdFilePath());
CASACrypto.EncryptAndStoreMasterPasscodeUsingString(baPasscode,desktopPasswd,GetPasscodeByDesktopFilePath());
if(File.Exists(GetPersistenceFilePath()))
{
File.Delete(GetPersistenceFilePath());
CSSSLogger.DbgLog("Removing the persistent storeas its meaningless now.");
}
if( bIsStorePersistent == false )
{
lss = new LocalStorage(this,baPasscode);
bIsStorePersistent = true;
}
return true;
}
else
{
return false;
}
}
//return true;
}//if a valid desktop Passwd is present - if ends here
else
{
/* If desktop passwd is not there and user sets
* master password.
*/
if(File.Exists(GetPersistenceFilePath()))
{
File.Delete(GetPersistenceFilePath());
CSSSLogger.DbgLog("Removing the persistent storeas its meaningless now. - Desktop passwd is not there and Master password is being set");
}
if(File.Exists((GetPasscodeByDesktopFilePath())))
{
File.Delete((GetPasscodeByDesktopFilePath()));
CSSSLogger.DbgLog("Removing the persistent storeas its meaningless now. - Desktop passwd is not there and Master password is being set");
}
baPasscode = CASACrypto.GenerateMasterPasscodeUsingString(mPasswd,GetPasscodeByMasterPasswdFilePath(),GetValidationFilePath(), user.UserIdentifier);
if(baPasscode != null)
{
CASACrypto.EncryptAndStoreMasterPasscodeUsingString(baPasscode,mPasswd,GetPasscodeByMasterPasswdFilePath());
if( bIsStorePersistent == false )
{
lss = new LocalStorage(this,baPasscode);
bIsStorePersistent = true;
}
return true;
}
return false;
}
}//end of isVerifyOperation == false
else
{
/* Verify the master password. If verified, and if
* persistence has not started, start it.
*/
//Get the passcode from master passwd file and validate.
//If validation succeeds,start persistence.
if(desktopPasswd == null)
{
baPasscode = CASACrypto.DecryptMasterPasscodeUsingString(mPasswd, GetPasscodeByMasterPasswdFilePath());
if(CASACrypto.ValidatePasscode(baPasscode,GetValidationFilePath()))
{
if(bIsStorePersistent == false)
{
lss = new LocalStorage(this,baPasscode);
bIsStorePersistent = true;
}
return true;
}
else
{
return false;
}
}
else
{ //There are 2 cases - either desktop passwd has changed
//or it hasnt.
baPasscode = CASACrypto.GetMasterPasscodeUsingMasterPasswd(mPasswd, GetPasscodeByMasterPasswdFilePath());
if(CASACrypto.ValidatePasscode(baPasscode,GetValidationFilePath()))
{
RewriteDesktopPasswdFile(baPasscode,desktopPasswd);
if(bIsStorePersistent == false)
{
lss = new LocalStorage(this,baPasscode);
bIsStorePersistent = true;
}
return true;
}
else
{
return false;
}
}
}
}
catch(Exception e)
{
CSSSLogger.ExpLog(e.ToString());
}
return false;
}//End of SetMasterPassword
internal bool RewriteDesktopPasswdFile(byte[] baPasscode, string desktopPasswd)
{
try
{
CASACrypto.EncryptAndStoreMasterPasscodeUsingString(baPasscode, desktopPasswd, GetPasscodeByDesktopFilePath());
CSSSLogger.DbgLog("Re-encryted passcode with desktop passwd");
}
catch(Exception e)
{
CSSSLogger.ExpLog(e.ToString());
}
return true;
}
internal byte[] GetPasscodeFromOldDesktopPasswd(string oldDesktopPasswd)
{
try
{
byte[] baPasscode = CASACrypto.GetMasterPasscodeUsingDesktopPasswd(oldDesktopPasswd, GetPasscodeByDesktopFilePath());
if(CASACrypto.ValidatePasscode(baPasscode,GetValidationFilePath()))
{
return baPasscode;
}
}
catch(Exception e)
{
CSSSLogger.ExpLog(e.ToString());
}
return null;
}
/* This method would be called, when the user is setting his
* master passcode for the first time.
*/
internal bool SetMasterPasscode(string sMasterPasscode)
{
return true;
#if false
bool bRet = false;
try
{
if(!CASACrypto.CheckIfMasterPasscodeIsAvailable(desktopPasswd, GetPasswdFilePath()))
{
RijndaelManaged myRijndael = new RijndaelManaged();
byte[] key;
byte[] IV = new byte[16];
//Create a new key and initialization vector.
myRijndael.GenerateKey();
key = myRijndael.Key;
CASACrypto.StoreKeySetUsingMasterPasscode(key,IV,sMasterPasscode,GetKeyFilePath());
//Store the master passcode encrypted with the desktopPasswd
CASACrypto.EncryptAndStoreMasterPasscodeUsingString(sMasterPasscode, desktopPasswd, GetPasswdFilePath());
lss = new LocalStorage(this,sMasterPasscode);
bIsStorePersistent = true;
bRet = true;
}
else
{
//Console.WriteLine("Master passcode is already set");
}
}
catch(Exception e)
{
CSSSLogger.ExpLog(e.ToString());
}
return bRet;
#endif
}
internal void IncrRefCount()
{
try
{
ssMutex.WaitOne();
refCount++;
ssMutex.ReleaseMutex();
CSSSLogger.DbgLog(CSSSLogger.GetExecutionPath(this) + " : RefCount = " + refCount);
}
catch(Exception e)
{
CSSSLogger.ExpLog(e.ToString());
throw e;
}
}
internal void DecrRefCount()
{
try
{
ssMutex.WaitOne();
refCount--;
ssMutex.ReleaseMutex();
CSSSLogger.DbgLog(CSSSLogger.GetExecutionPath(this) + " : RefCount = " + refCount);
}
catch(Exception e)
{
CSSSLogger.ExpLog(e.ToString());
throw e;
}
}
internal bool AddKeyChain(KeyChain keychain)
{
try
{
keychain.CreatedTime = DateTime.Now;
keyChainList.Add(keychain.GetKey(),keychain);
}
catch(Exception e)
{
CSSSLogger.DbgLog(e.ToString());
throw e;
}
CSSSLogger.DbgLog(CSSSLogger.GetExecutionPath(this) + " - Succefully added Keychain = "+ keychain.GetKey() + " length = "+ (keychain.GetKey()).Length);
return true;
}
internal bool RemoveKeyChain(string id)
{
keyChainList.Remove(id);
return true;
}
internal KeyChain GetKeyChain(string id)
{
if(keyChainList.ContainsKey(id))
{
CSSSLogger.DbgLog("In " + CSSSLogger.GetExecutionPath(this) + " Keychain already exists.");
KeyChain kc = (KeyChain)(keyChainList[id]);
kc.AccessedTime = DateTime.Now;
return kc;
}
else
{
CSSSLogger.DbgLog("In " + CSSSLogger.GetExecutionPath(this) + " Keychain doesnot exist.Returning null.");
throw new KeyChainDoesNotExistException(id);
}
}
internal bool CheckIfKeyChainExists(string id)
{
if(keyChainList.ContainsKey(id))
return true;
else
return false;
}
/* This function would need to do any storage/cleanup required
* before removing a user session.
*/
internal bool CommitStore()
{
if(lss != null)
lss.PersistStore();
return true;
}
internal IEnumerator GetKeyChainEnumerator()
{
//TBD
// Return an Enumerator class which has all secrets in this keychain
return keyChainList.GetEnumerator();
}
internal void DumpSecretstore()
{
lock(keyChainList.SyncRoot)
{
IDictionaryEnumerator iter = (IDictionaryEnumerator)GetKeyChainEnumerator();
while( iter.MoveNext() )
{
int i = 0;
KeyChain kc = (KeyChain)iter.Value;
CSSSLogger.DbgLog("\nKeychain id = " + kc.GetKey());
CSSSLogger.DbgLog("Secret List is ");
IDictionaryEnumerator secIter = (IDictionaryEnumerator)(kc.GetAllSecrets());
while(secIter.MoveNext())
{
Secret secret = (Secret)secIter.Value;
CSSSLogger.DbgLog("Secret " + i.ToString() + " id = " + secret.GetKey() + " value = " + secret.GetValue() );
IDictionaryEnumerator etor = (IDictionaryEnumerator) secret.GetKeyValueEnumerator();
while(etor.MoveNext())
{
KeyValue kv = (KeyValue)etor.Value;
CSSSLogger.DbgLog("Key = " + kv.Key +" Value = " + kv.GetValue());
}
i++;
}
}
}
}
internal int GetSecretStoreState()
{
return state;
}
internal int GetNumKeyChains()
{
return keyChainList.Count;
}
internal bool SetSecretStoreState(int stateToSet)
{
//BrainShare Special Only - Only Session keychains state 1
state = STATE_OK;
return true;
}
internal string GetDesktopPasswd()
{
try
{
string keyChainId = ConstStrings.SSCS_SESSION_KEY_CHAIN_ID + "\0";
KeyChain keyChain = GetKeyChain(keyChainId);
Secret secret = keyChain.GetSecret(ConstStrings.MICASA_DESKTOP_PASSWD);
string passwd = secret.GetKeyValue(ConstStrings.MICASA_DESKTOP_PASSWD_KEYNAME).GetValue();
return passwd;
}
catch(Exception e)
{
CSSSLogger.ExpLog(e.ToString());
}
return null;
}
internal string GetUserHomeDirectory()
{
return user.GetUserHomeDir();
}
internal string GetKeyFilePath()
{
string homeDir = GetUserHomeDirectory();
return homeDir + ConstStrings.MICASA_KEY_FILE;
}
internal string GetPasscodeByDesktopFilePath()
{
string homeDir = GetUserHomeDirectory();
return homeDir + ConstStrings.MICASA_PASSCODE_BY_DESKTOP_FILE;
}
internal string GetPasscodeByMasterPasswdFilePath()
{
string homeDir = GetUserHomeDirectory();
return homeDir + ConstStrings.MICASA_PASSCODE_BY_MASTERPASSWD_FILE;
}
internal string GetPersistenceFilePath()
{
string homeDir = GetUserHomeDirectory();
return homeDir + ConstStrings.MICASA_PERSISTENCE_FILE;
}
internal string GetValidationFilePath()
{
string homeDir = GetUserHomeDirectory();
return homeDir + ConstStrings.MICASA_VALIDATION_FILE;
}
}
}

View File

@@ -0,0 +1,80 @@
using System;
using System.IO;
namespace sscs.common
{
//TBD
// All user defined exceptions will extend this class in future
internal class CSSSException : ApplicationException
{
internal string user;
internal CSSSException (string message)
{
}
}
internal class CommunicationException : ApplicationException
{
internal CommunicationException (String message) : base (message)
{
}
internal CommunicationException (String message, Exception inner) : base(message,inner)
{
}
}
internal class MessageFormatException : Exception
{
internal MessageFormatException (String message) : base (message)
{
}
internal MessageFormatException (String message, Exception inner) : base(message,inner)
{
}
}
internal class UserNotInSessionException : Exception
{
internal UserNotInSessionException (String message) : base (message)
{
CSSSLogger.DbgLog(message);
}
internal UserNotInSessionException (UserIdentifier user)
{
CSSSLogger.DbgLog("UserIdentifier is not in session table " + user.GetUID());
}
}
internal class KeyChainDoesNotExistException : Exception
{
internal KeyChainDoesNotExistException (String kId)
{
CSSSLogger.DbgLog("Keychain - " + kId + " not found");
}
}
internal class SecretNotFoundException : Exception
{
internal SecretNotFoundException (String sId)
{
CSSSLogger.DbgLog("SecretId - " + sId + " not found");
}
}
internal class CryptoException : ApplicationException
{
internal CryptoException(string msg)
{
CSSSLogger.DbgLog("Crypto exception : " + msg );
}
}
}

View File

@@ -0,0 +1,211 @@
using System;
using System.Text;
using System.Diagnostics;
using sscs.common;
using sscs.constants;
using System.IO;
using System.Threading;
namespace sscs.common
{
/*
* This ia a common logging facility for windows and Linux.
* This also is the common place to log all server logs and debug logs.
*/
class CSSSLogger
{
//private static CSSSLogger csssLog = null;
//private static string WINID = "Microsoft";
private static string engineLog = null;
#if DEBUG
private static string LINUXID = "Unix";
private static string debugLog = null;
private static Stream debugStream= null;
#endif
private static StreamWriter serverTrace= null;
private static Mutex dbgmutex = new Mutex();
static CSSSLogger()
{
#if DEBUG
if (Environment.OSVersion.ToString().StartsWith(LINUXID))
{
engineLog = ConstStrings.SSCS_LINUX_ENGINELOG;
debugLog = ConstStrings.SSCS_LINUX_DEBUGLOG;
}
else
{
engineLog = ConstStrings.SSCS_WIN_ENGINELOG;
debugLog = ConstStrings.SSCS_WIN_DEBUGLOG;
}
/* There is no set up for Server Trace
* open and close would be done when needed.
*/
// Set up for Debug
if( File.Exists( debugLog ) )
{
File.Delete( debugLog );
}
debugStream = File.Create(debugLog);
Debug.Listeners.Add(new TextWriterTraceListener(debugStream));
Debug.AutoFlush = true;
Debug.Indent();
Debug.WriteLine("Debug Log created");
#endif
}
public static void log(bool criticality, String message)
{
if (criticality) // Status message
WritetoServerLog(message);
else
DbgLog(message);
}
public static void log(bool criticality, System.Exception e)
{
if (criticality) // Status message
WritetoServerLog(e.ToString());
else
DbgLog(e.ToString());
}
public static void ExecutionTrace(Object obj)
{
#if DEBUG
StringBuilder message = null;
StackTrace st = null;
try
{
message = new StringBuilder();
st = new StackTrace(true);
}
catch( OutOfMemoryException e )
{
ExpLog(e.ToString());
throw e;
}
Type type = obj.GetType();
StackFrame sf = st.GetFrame(1);
message.Append(" ThreadID: ");
message.Append(Thread.CurrentThread.GetHashCode().ToString());
message.Append(" Executing Path: ");
message.Append(type.ToString());
message.Append(":");
message.Append(sf.GetMethod().ToString());
log( ConstStrings.DEBUG,message.ToString() );
#endif
}
public static void ExecutionTrace(Type type)
{
#if DEBUG
StringBuilder message = null;
StackTrace st = null;
try
{
message = new StringBuilder();
st = new StackTrace(true);
}
catch( OutOfMemoryException e )
{
ExpLog(e.ToString());
throw e;
}
StackFrame sf = st.GetFrame(1);
message.Append(" ThreadID: ");
message.Append(Thread.CurrentThread.GetHashCode().ToString());
message.Append(" Executing Path: ");
message.Append(type.ToString());
message.Append(":");
message.Append(sf.GetMethod().ToString());
log( ConstStrings.DEBUG,message.ToString() );
#endif
}
public static string GetExecutionPath(Object obj)
{
StringBuilder message = null;
StackTrace st = null;
try
{
message = new StringBuilder();
st = new StackTrace(true);
}
catch( OutOfMemoryException e )
{
ExpLog(e.ToString());
throw e;
}
Type type = obj.GetType();
StackFrame sf = st.GetFrame(1);
message.Append(" ThreadID: ");
message.Append(Thread.CurrentThread.GetHashCode().ToString());
message.Append(" Executing Path: ");
message.Append(type.ToString());
message.Append("::");
message.Append(sf.GetMethod().ToString());
return message.ToString();
}
public static void logbreak()
{
dbgmutex.WaitOne();
Debug.WriteLine(" ") ;
Debug.WriteLine("----------------------------------------------------") ;
Debug.WriteLine(" ") ;
dbgmutex.ReleaseMutex();
}
// The log format is Time stamp : Machine name: Product name: Logging information
private static void WritetoServerLog( string message )
{
serverTrace = File.AppendText(engineLog);
serverTrace.Write("{0} {1}", DateTime.Now.ToLongTimeString(), DateTime.Now.ToLongDateString());
serverTrace.Write("CSSS");
serverTrace.Write(message);
serverTrace.Flush();
serverTrace.Close();
}
// The log format is Time stamp :Component name: Error description
public static void DbgLog(string message)
{
dbgmutex.WaitOne();
Debug.Write(DateTime.Now.ToLongTimeString());
Debug.Write(" " + DateTime.Now.ToLongDateString());
Debug.Write(":");
Debug.WriteLine(message);
// Debug.WriteLine(" ") ;
dbgmutex.ReleaseMutex();
}
public static void ExpLog(string message)
{
dbgmutex.WaitOne();
Debug.Write(DateTime.Now.ToLongTimeString());
Debug.Write(" " + DateTime.Now.ToLongDateString());
Debug.Write(": Exception encountered - ");
Debug.WriteLine(message);
Debug.WriteLine(" ") ;
StackTrace st = new StackTrace();
Debug.WriteLine(st.ToString());
dbgmutex.ReleaseMutex();
}
}
}

View File

@@ -0,0 +1,125 @@
using System;
namespace sscs.constants
{
class IPCRetCodes
{
internal static int SSCS_REPLY_SUCCESS = 0;
internal static int SSCS_E_INVALID_MESSAGE = -1;
internal static int SSCS_E_VERSION_NOT_SUPPORTED = -2;
internal static int SSCS_E_SYSTEM_ERROR = -3;
internal static int SSCS_E_REPLY_NOT_AVAILABLE = -4;
internal static int SSCS_E_INVALID_KEYCHAIN = -5;
internal static int SSCS_E_INVALID_SECRETID = -6;
internal static int SSCS_E_KEYCHAIN_ALREADY_EXISTS = -7;
internal static int SSCS_E_MAX_KEYCHAINS_REACHED = -8;
internal static int SSCS_E_ADD_KEYCHAIN_FAILED = -9;
internal static int SSCS_E_NO_KEYCHAINS_EXIST = -10;
internal static int SSCS_E_KEYCHAIN_DOES_NOT_EXIST = -11;
internal static int SSCS_E_REMOVE_KEYCHAIN_FAILED = -12;
internal static int SSCS_E_WRITE_SECRET_FAILED = -13;
internal static int SSCS_E_ADDING_DEFAULT_KEYCHAIN_FAILED = -14;
internal static int SSCS_E_NO_SECRETS_EXIST = -15;
internal static int SSCS_E_REMOVE_SECRET_FAILED = -16;
internal static int SSCS_E_GET_SOCKET_PATH_FAILED = -17;
internal static int SSCS_E_CREATE_SOCKET_FAILED = -18;
internal static int SSCS_E_SECRETID_DOES_NOT_EXIST = -19;
internal static int SSCS_E_INVALID_INPUT = -20;
internal static int SSCS_E_SETTING_PASSCODE_FAILED = -21;
internal static int SSCS_PROMPT_PASSCODE = 1;
internal static int SSCS_STORE_IS_PERSISTENT = -22;
internal static int SSCS_STORE_IS_NOT_PERSISTENT = -23;
internal static int SSCS_SECRET_IS_PERSISTENT = -24;
internal static int SSCS_SECRET_IS_NOT_PERSISTENT = -25;
}
internal class ReqMsgId
{
}
internal class RespMsgId
{
}
internal class RetCodes
{
internal static int SUCCESS = 0;
internal static int FAILURE = -1;
internal static int LOAD_HIDDEN_ONLY = 1;
internal static int LOAD_ALL_EXCEPT_HIDDEN = 2;
internal static int WRITE_HIDDEN_ONLY = 3;
internal static int WRITE_ALL_EXCEPT_HIDDEN = 4;
internal static int WRITE_ALL = 5;
}
internal class ConstStrings
{
internal static string SSCS_SESSION_KEY_CHAIN_ID = "SSCS_SESSION_KEY_CHAIN_ID";
internal static string SSCS_LOCAL_KEY_CHAIN_ID = "SSCS_LOCAL_KEY_CHAIN_ID";
internal static string SSCS_HIDDEN_LOCAL_KEYCHAIN_ID = "SSCS_HIDDEN_LOCAL_KEYCHAIN_ID";
internal static string SSCS_REMOTE_KEYCHAIN_ID = "SSCS_REMOTE_KEYCHAIN_ID";
internal static string SSCS_LOCAL_REMOTE_KEYCHAIN_ID = "SSCS_LOCAL_REMOTE_KEYCHAIN_ID";
//TBD , Need to look at Novell standard for the desktop
internal static string SSCS_WIN_ENGINELOG = "c:\\CSSS.log";
internal static string SSCS_WIN_DEBUGLOG = "c:\\CSSSDEBUG.log";
//TBD , Need to look at Novell standard for the desktop
internal static string SSCS_LINUX_ENGINELOG = "/var/log/localmessages";
internal static string SSCS_LINUX_DEBUGLOG = "/var/log/micasad_debug.log";
internal static string SSCS_LINUX_PIDFILE = "/var/run/micasad.pid";
internal static bool STATUS = true;
internal static bool DEBUG = false;
internal static string MICASA_DESKTOP_PASSWD = "SS_CredSet:Desktop\0";
// internal static string MICASA_DESKTOP_PASSWD_KEYNAME = "Password\0";
internal static string MICASA_DESKTOP_PASSWD_KEYNAME = "Password";
// The file where the key (encrypted with master passcode)
// would be stored
internal static string MICASA_PASSCODE_BY_DESKTOP_FILE = "/.miCASAPCByDesktop";
internal static string MICASA_PASSCODE_BY_MASTERPASSWD_FILE = "/.miCASAPCByMPasswd";
//The file where all possible passwds are cross encrypted and
//stored to provide multiple recovery points.
internal static string MICASA_KEY_FILE = "/.miCASAKey";
//The file where the user's credentials are persisted.
internal static string MICASA_PERSISTENCE_FILE = "/.miCASA";
//The file required to validate the desktop passwd
internal static string MICASA_VALIDATION_FILE = "/.miCASAValidate";
internal static string MICASA_VALIDATION_STRING = "miCASAValidationString";
}
internal class ConstFlags
{
internal static uint SSFLAGS_DESTROY_SESSION_F = 1;
}
internal class XmlConsts
{
internal static string miCASANode = "miCASA";
internal static string versionAttr = "version";
internal static string keyChainNode = "KeyChain";
internal static string idAttr = "id";
internal static string secretNode = "Secret";
internal static string valueNode = "Value";
internal static string timeNode = "Time";
internal static string createdTimeNode = "created";
internal static string modifiedTimeNode = "modified";
internal static string keyNode = "Key";
internal static string keyValueNode = "KeyValue";
internal static string linkedKeyNode = "LinkedKey";
internal static string linkedTargetSecretNode = "TargetSecret";
internal static string linkedTargetKeyNode = "TargetKey";
}
}

View File

@@ -0,0 +1,97 @@
using System;
using System.Collections;
using System.Text;
using System.Threading;
using sscs.verbs;
using sscs.common;
/*
* After the bytes format is finalized for Windows this class might need to
* be modified..
* Depending upon impact either a new method can be invoked after platfrom
* check or a Factory pattern can be used to redesign this class.
*/
/*
* Namespaces used inside SSCS(main) will be of the following format "sscs.*"
* The NameSpaces available are....
* sscs.common [session, RequestParser]
* sscs.authentication
* sscs.verbs;[ssVerb, .......]
* sscs.cache [secretstore, keychain, secret]
* sscs.lss;
* sscs.synchronization;
* sscs.crypto
*/
namespace sscs.common
{
/* This class will be used to convert raw bytes to one of the SecretStore
* Verbs. Although there is no need to have many instances,
* this class will NOT be singleton class since we
* do not want a hit on performance (synchronization, obtaining locks,
* releasing locks...etc )
* Making it singleton is not giving us any advantage versus performance.
*/
internal class RequestParser
{
Hashtable msgIdMap = new Hashtable();
internal RequestParser()
{
msgIdMap.Add(1,"sscs.verbs.OpenSecretStore");
msgIdMap.Add(2,"sscs.verbs.CloseSecretStore");
msgIdMap.Add(3,"sscs.verbs.RemoveSecretStore");
msgIdMap.Add(4,"sscs.verbs.EnumerateKeyChainIds");
msgIdMap.Add(5,"sscs.verbs.AddKeyChain");
msgIdMap.Add(6,"sscs.verbs.RemoveKeyChain");
msgIdMap.Add(7,"sscs.verbs.EnumerateSecretIds");
msgIdMap.Add(8,"sscs.verbs.ReadSecret");
msgIdMap.Add(9,"sscs.verbs.WriteSecret");
msgIdMap.Add(10,"sscs.verbs.RemoveSecret");
msgIdMap.Add(11,"sscs.verbs.GetSecretStoreInfo");
msgIdMap.Add(12,"sscs.verbs.GetKeyChainInfo");
msgIdMap.Add(13,"sscs.verbs.LockCache");
msgIdMap.Add(14,"sscs.verbs.UnLockCache");
msgIdMap.Add(15,"sscs.verbs.SetMasterPasscode");
msgIdMap.Add(16,"sscs.verbs.ReadKey");
msgIdMap.Add(17,"sscs.verbs.WriteKey");
msgIdMap.Add(18,"sscs.verbs.SetMasterPassword");
msgIdMap.Add(19,"sscs.verbs.IsSecretPersistent");
msgIdMap.Add(20,"sscs.verbs.ObjectSerialization");
}
/* Processes the request and returns the corrrect SSverb.
* This interface works on the class member rawbytes and
* returns the result.
*/
internal SSVerb ParseRequest(byte[] rawbytes)
{
if (rawbytes == null)
throw new FormatException("Message format incorrect");
String className = GetClassName(rawbytes);
SSVerb theVerb = (SSVerb)Activator.CreateInstance(null, className ).Unwrap();
theVerb.SetMessageContent(rawbytes);
/*
* TBD: We can send the activation params in the same call.
*/
//SSVerb theVerb = (SSVerb)Activator.CreateInstance(Type.GetType(className)).Unwrap();
return theVerb;
}
private string GetClassName(byte[] ipcbytes)
{
/*
* Read first two bytes and get ushort
* Look up table and send class name
*/
ushort msgId = BitConverter.ToUInt16(ipcbytes,0);
return ((String)(msgIdMap[(int)msgId]));
}
}
}

View File

@@ -0,0 +1,343 @@
using System;
using System.Collections;
using System.Threading;
using System.IO;
using sscs.cache;
using sscs.common;
using sscs.constants;
using System.Diagnostics;
namespace sscs.common
{
class SessionManager
{
private static readonly SessionManager sessionManager = new SessionManager();
private static Mutex mutex = new Mutex();
private static Hashtable sessionTable = new Hashtable();
private static Thread tJanitor = null;
private static int JANITOR_SLEEP_TIME = 1000*60*5; // 5 minutes
private SessionManager()
{
#if LINUX
if (tJanitor == null)
{
tJanitor = new Thread(new ThreadStart(CleanUpSessionsThread));
tJanitor.Start();
}
#endif
}
~SessionManager()
{
if (tJanitor != null)
{
tJanitor.Abort();
tJanitor.Join();
}
mutex.Close();
}
internal static SessionManager GetSessionManager
{
get
{
return sessionManager;
}
}
internal static SecretStore CreateUserSession(UserIdentifier userId)
{
CSSSLogger.ExecutionTrace(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
SecretStore ss;
userId.PrintIdentifier();
try
{
ss = GetUserSecretStore(userId);
ss.IncrRefCount();
ss.CreateTime = DateTime.Now;
return ss;
}
catch(UserNotInSessionException e)
{
// Would create either windows/unix user
// depending on the platform.
User user = User.CreateUser(userId);
mutex.WaitOne();
sessionTable.Add(userId,user);
mutex.ReleaseMutex();
ss = user.GetSecretStore();
ss.IncrRefCount();
ss.CreateTime = DateTime.Now;
return ss;
}
}
internal static bool RemoveUserSession(UserIdentifier userId, bool destroySession)
{
CSSSLogger.ExecutionTrace(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
try
{
mutex.WaitOne();
SecretStore ss = GetUserSecretStore(userId);
ss.DecrRefCount();
// We must keep the cache alive, and destroy it on
// a logout event
//if( 0 == ss.refCount )
if (destroySession)
{
CSSSLogger.DbgLog("Removing the user session of " + userId.GetUID());
ss.CommitStore();
sessionTable.Remove(userId);
}
mutex.ReleaseMutex();
return true;
}
catch(Exception e)
{
CSSSLogger.ExpLog(e.ToString());
}
return false;
}
internal static bool CheckIfUserSessionExists(UserIdentifier userId)
{
CSSSLogger.ExecutionTrace(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
mutex.WaitOne();
if( sessionTable.ContainsKey(userId) )
{
mutex.ReleaseMutex();
return true;
}
else
{
mutex.ReleaseMutex();
return false;
}
}
internal static SecretStore GetUserSecretStore(UserIdentifier userId)
{
CSSSLogger.ExecutionTrace(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
userId.PrintIdentifier();
ListActiveUserSessions();
mutex.WaitOne();
if( sessionTable.ContainsKey(userId) )
{
User user = (User)sessionTable[userId];
SecretStore ss = user.GetSecretStore();
mutex.ReleaseMutex();
return ss;
}
else
{
mutex.ReleaseMutex();
throw new UserNotInSessionException(userId);
}
}
internal static DateTime GetSessionCreateTime(UserIdentifier userId)
{
CSSSLogger.ExecutionTrace(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
mutex.WaitOne();
if( sessionTable.ContainsKey(userId) )
{
User user = (User)sessionTable[userId];
SecretStore ss = user.GetSecretStore();
mutex.ReleaseMutex();
return ss.CreateTime;
}
else
{
mutex.ReleaseMutex();
throw new UserNotInSessionException(userId);
}
}
internal static void ListActiveUserSessions()
{
CSSSLogger.ExecutionTrace(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
mutex.WaitOne();
IDictionaryEnumerator etor = sessionTable.GetEnumerator();
int i = 0;
while(etor.MoveNext())
{
i++;
/*
CSSSLogger.DbgLog("Listing Active User Sessions");
Console.WriteLine(etor.Key);
Console.WriteLine((((SecretStore)(etor.Value)).secretStoreName + ":" + ((SecretStore)(etor.Value)).refCount);
*/
}
mutex.ReleaseMutex();
}
private static void CleanUpSessionsThread()
{
CSSSLogger.ExecutionTrace(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
try
{
while (true)
{
// enumerate users in the session
IEnumerator etor;
ICollection keys = sessionTable.Keys;
if (keys != null)
{
etor = keys.GetEnumerator();
while(etor.MoveNext())
{
UserIdentifier userIdentifier = (UserIdentifier)etor.Current;
// check if this user still has
// processes running
if(CheckAndDestroySession(userIdentifier,false))
{
/* If at least 1 session was removed,
* the etor must be
* re-initiated, else
* Invalidoperationexception will be
* thrown.
*/
keys = sessionTable.Keys;
if( null == keys )
break;
else
{
etor = keys.GetEnumerator();
}
}
}//while etor.MoveNext ends here.
}
Thread.Sleep(JANITOR_SLEEP_TIME);
} //while true ends here.
}
catch(ThreadAbortException e)
{
CSSSLogger.DbgLog("Janitor thread is going down.");
}
}//Method ends here.
/* As the pam module does a seteuid(), when is ps is
* execed it would appear as if the user owns the process.
* Hence, if this method is called from CloseSecretStore
* verb ( that would have been initiated from the pam
* module with ssFlags = 1), then if number of processes
* is one, then delete the session.
*/
internal static bool CheckAndDestroySession(UserIdentifier userID, bool calledFromClose)
{
CSSSLogger.ExecutionTrace(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
int iUID = userID.GetUID();
bool retVal = false;
Process myProcess = null;
StreamReader myStreamReader = null;
if (iUID != -1)
{
// make the 'ps h U UID' call
try
{
myProcess = new Process();
ProcessStartInfo myProcessStartInfo = new ProcessStartInfo("ps" );
myProcessStartInfo.Arguments = "h U " + iUID.ToString();
myProcessStartInfo.UseShellExecute = false;
myProcessStartInfo.RedirectStandardOutput = true;
myProcess.StartInfo = myProcessStartInfo;
myProcess.Start();
myProcess.WaitForExit();
myStreamReader = myProcess.StandardOutput;
// Read the standard output of the spawned process.
string myString = myStreamReader.ReadLine();
int numProcs = 0;
while( myString != null)
{
if(numProcs > 1)
break;
numProcs++;
myString = myStreamReader.ReadLine();
}
do
{
/* If this has been called from
* CloseSecretStore verb,
* verb, the session must be deleted.
*/
if( calledFromClose )
{
RemoveUserSession(userID, true);
retVal = true;
break;
}
/* If the session was created during login,
* and the janitor thread starts processing
* before user login is completed, we need
* maintain the user session (say for 5 mts).
*/
if( (numProcs == 0) && (CheckIfLoginTimeSession(userID)) )
{
retVal = false;
break;
}
/* If the user does not own any processes and
* if this method has not been called from
* CloseSecretStore verb, it implies that a user
* background process, which existed during user
* logout has died now.
* So, clean the user session.
*/
if ( (numProcs == 0) && (!calledFromClose) )
{
RemoveUserSession(userID, true);
retVal = true;
break;
}
}while(false);
/*
myProcess.Close();
myStreamReader.Close();
*/
}
catch (Exception e)
{
CSSSLogger.DbgLog(e.ToString());
}
finally
{
if( myProcess != null )
myProcess.Close();
if( myStreamReader != null )
myStreamReader.Close();
}
}
return retVal;
}
internal static bool CheckIfLoginTimeSession(UserIdentifier userId)
{
if( ((TimeSpan)(DateTime.Now - GetSessionCreateTime(userId))).TotalMinutes < 3 )
{
return true;
}
else
return false;
}
}
}

View File

@@ -0,0 +1,42 @@
using System;
using System.Collections;
using System.IO;
using sscs.cache;
using sscs.common;
using sscs.constants;
namespace sscs.common
{
internal class UnixUser : User
{
internal UnixUser()
{
}
internal UnixUser(UserIdentifier unixUserId)
{
userId = unixUserId;
secretStore = new SecretStore(this);
}
override internal void SetUserName(string username)
{
userName = username;
}
override internal string GetUserName()
{
return userName;
}
override internal string GetUserHomeDir()
{
uint uid = (uint)userId.GetUID();
return Mono.Unix.UnixUser.GetHomeDirectory(uid);
}
}
}

View File

@@ -0,0 +1,36 @@
using System;
namespace sscs.common
{
internal class UnixUserIdentifier : UserIdentifier
{
private int uid;
internal UnixUserIdentifier(int uid)
{
this.uid = uid;
}
public override bool Equals(Object obj)
{
UnixUserIdentifier u = (UnixUserIdentifier)obj;
if (u.uid == uid)
return true;
else
return false;
}
public override int GetHashCode()
{
return uid.GetHashCode();
}
public void PrintIdentifier()
{
// Console.WriteLine("UnixUserIdentifier : uid is {0}",uid);
}
public int GetUID()
{
return uid;
}
}
}

49
c_micasad/common/User.cs Normal file
View File

@@ -0,0 +1,49 @@
using System;
using System.IO;
using sscs.cache;
namespace sscs.common
{
abstract class User
{
protected UserIdentifier userId;
public UserIdentifier UserIdentifier
{
get
{
return userId;
}
}
protected SecretStore secretStore;
protected string home;
/* Change the protection level after getting the latest requirements */
protected string userName = null;
abstract internal void SetUserName(string userName);
abstract internal string GetUserName();
abstract internal string GetUserHomeDir();
internal SecretStore GetSecretStore()
{
return secretStore;
}
internal static User CreateUser(UserIdentifier userId)
{
User user = null;
#if LINUX
user = new UnixUser(userId);
#endif
#if W32
user = new WinUser(userId);
#endif
return user;
}
}
}

View File

@@ -0,0 +1,12 @@
using System;
using System.IO;
namespace sscs.common
{
public interface UserIdentifier
{
void PrintIdentifier();
int GetUID();
}
}

View File

@@ -0,0 +1,92 @@
using System;
using System.Collections;
using System.IO;
using Microsoft.Win32;
using sscs.cache;
using sscs.common;
using sscs.constants;
namespace sscs.common
{
internal class WinUser : User
{
private string m_sUserHome = "";
internal WinUser()
{
}
internal WinUser(UserIdentifier winUserId)
{
userId = winUserId;
secretStore = new SecretStore(this);
}
override internal void SetUserName(string username)
{
userName = username;
}
override internal string GetUserName()
{
return userName;
}
/* A method to find the user's home dir on windows needs to be added.
*/
override internal string GetUserHomeDir()
{
if (m_sUserHome.Length < 1)
{
//Console.WriteLine("read registry");
// get the users home drive and homepath from the registry
//
string sSIDString = ((WinUserIdentifier)userId).GetSID();
// look up Profile path
// [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\S-1-5-21-1757981266-436374069-725345543-1006]
string sProfile = ReadRegKey(Registry.LocalMachine, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\" + sSIDString, "ProfileImagePath");
m_sUserHome = sProfile;
//string sHomeDrive = ReadRegKey(Registry.Users, sSIDString+"\\Volatile Environment", "HOMEDRIVE");
//string sHomeDir = ReadRegKey(Registry.Users, sSIDString+"\\Volatile Environment", "HOMEPATH");
//m_sUserHome = sHomeDrive+sHomeDir;
//Console.WriteLine("Homedir: "+ m_sUserHome);
}
return m_sUserHome;
}
private string ReadRegKey(RegistryKey rk, string sSubKey, string KeyName)
{
// Opening the registry key
// RegistryKey rk = Registry.Users;
// Open a subKey as read-only
RegistryKey sk1 = rk.OpenSubKey(sSubKey);
// If the RegistrySubKey doesn't exist -> (null)
if ( sk1 == null )
{
return null;
}
else
{
try
{
// If the RegistryKey exists I get its value
// or null is returned.
return (string)sk1.GetValue(KeyName.ToUpper());
}
catch (Exception e)
{
//ShowErrorMessage(e, "Reading registry " + KeyName.ToUpper());
return null;
}
}
}
}
}

View File

@@ -0,0 +1,51 @@
using System;
namespace sscs.common
{
internal class WinUserIdentifier : UserIdentifier
{
private int uidLow;
private int uidHigh;
private string m_sSID = "";
internal WinUserIdentifier(int uidLowPart, int uidHighPart, string sSID)
{
this.uidLow = uidLowPart;
this.uidHigh = uidHighPart;
this.m_sSID = sSID;
}
internal WinUserIdentifier(int uidLowPart, int uidHighPart)
{
this.uidLow = uidLowPart;
this.uidHigh = uidHighPart;
}
internal string GetSID()
{
return m_sSID;
}
public override bool Equals(Object obj)
{
WinUserIdentifier u = (WinUserIdentifier)obj;
if ((u.uidLow == uidLow) && (u.uidHigh == uidHigh))
return true;
else
return false;
}
public override int GetHashCode()
{
return uidLow.GetHashCode();
}
public void PrintIdentifier()
{
// Console.WriteLine("WinUserIdentifier : uid is {0}",uid);
}
public int GetUID()
{
return -1;
}
}
}

View File

@@ -0,0 +1,30 @@
using System;
/* This class would have only static methods.
*/
namespace sscs.communication
{
class CommunicationFactory
{
/* Make the constructor private, to avoid instances of this
* class.
*/
private CommunicationFactory()
{
}
/* This method must check for platform and return
* an appropriate class. As of now, it assumes platform as Linux.
*/
public static Communication CreateCommunicationEndPoint()
{
#if LINUX
return( new UnixCommunication());
#endif
#if W32
return (new WinCommunication());
#endif
}
}
}

View File

@@ -0,0 +1,15 @@
using System;
/* This is an interface which would be implemented
* by UnixCommunication and WinCommunication.
*/
namespace sscs.communication
{
interface Communication
{
void StartCommunicationEndPoint();
void CloseCommunicationEndPoint();
}
}

View File

@@ -0,0 +1,40 @@
using System;
using System.Net;
using System.Net.Sockets;
#if W32
using sscs.communication.win.NamedPipes;
#endif
using sscs.common;
namespace sscs.communication
{
abstract class IPCChannel
{
/* This must check for the platform and return an
* appropriate IPCChannel.
*/
#if LINUX
internal static IPCChannel Create(Socket socket)
{
if(( (int)Environment.OSVersion.Platform) == 128)
return (new UnixIPCChannel(socket) );
else
return null;
}
#endif
#if W32
internal static IPCChannel Create(ServerPipeConnection serverPipe)
{
return (new WinIPCChannel(serverPipe));
}
#endif
abstract internal UserIdentifier GetIPCChannelUserId();
abstract internal int Read(byte[] buf);
abstract internal byte[] Read();
abstract internal int Write(byte[] buf);
abstract internal void Close();
}
}

View File

@@ -0,0 +1,130 @@
using System;
using System.Net;
using System.Net.Sockets;
using Mono.Unix;
using System.IO;
using System.Text;
using System.Threading;
using sscs.common;
using sscs.constants;
namespace sscs.communication
{
/* Platform specific class which implements
* the 'Communication' interface.
*/
class UnixCommunication : Communication
{
private Socket listeningSocket;
private Socket connectedSocket;
private string socketFileName = "/tmp/.novellCASA";
private EndPoint sockEndPoint;
private ManualResetEvent eventVar = null;
//Methods
internal UnixCommunication()
{
CSSSLogger.ExecutionTrace(this);
Syscall.umask(0);
if(File.Exists(socketFileName))
File.Delete(socketFileName);
listeningSocket = new Socket( AddressFamily.Unix,
SocketType.Stream,
ProtocolType.IP );
sockEndPoint = new UnixEndPoint(socketFileName);
eventVar = new ManualResetEvent(true);
}
~UnixCommunication()
{
CSSSLogger.ExecutionTrace(this);
eventVar.Close();
CloseCommunicationEndPoint();
}
// This code executes in the listening thread.
public void StartCommunicationEndPoint()
{
CSSSLogger.ExecutionTrace(this);
try
{
listeningSocket.Bind(sockEndPoint);
listeningSocket.Listen(50);
}
catch(Exception e)
{
CSSSLogger.ExpLog(e.ToString());
}
while(true)
{
try
{
eventVar.Reset();
listeningSocket.BeginAccept(new AsyncCallback(ListenCb),
listeningSocket);
eventVar.WaitOne();
}
catch(Exception e)
{
CSSSLogger.ExpLog(e.ToString());
throw e;
}
}
}
public void CloseCommunicationEndPoint()
{
CSSSLogger.ExecutionTrace(this);
listeningSocket.Close();
if(File.Exists( socketFileName ))
File.Delete(socketFileName);
}
// On receipt of a new client, this method is called.
private void ListenCb (IAsyncResult state)
{
try
{
CSSSLogger.ExecutionTrace(this);
connectedSocket = ((Socket)state.AsyncState).EndAccept (state);
eventVar.Set();
ServiceClient();
}
catch(Exception e)
{
/* All resources would have been cleaned up before reaching
* here.
*/
CSSSLogger.ExpLog(e.ToString());
}
/* End of thread function */
}
private void ServiceClient()
{
CSSSLogger.ExecutionTrace(this);
IPCChannel ipcChannel = IPCChannel.Create(connectedSocket);
AppHandler appHandler = new AppHandler(ipcChannel);
try
{
int retVal = appHandler.ServiceApp();
if( retVal != RetCodes.SUCCESS )
CSSSLogger.DbgLog("Servicing client failed.");
}
catch( Exception e )
{
CSSSLogger.ExpLog(e.ToString());
}
finally
{
ipcChannel.Close();
}
}
}
}

View File

@@ -0,0 +1,142 @@
using System;
using System.Net;
using System.Net.Sockets;
using Mono.Posix;
using System.IO;
using System.Text;
using sscs.common;
using sscs.verbs;
using sscs.constants;
namespace sscs.communication
{
class UnixIPCChannel : IPCChannel
{
// Data
private Socket clientSocket;
private UnixUserIdentifier userId;
//Methods
internal UnixIPCChannel(Socket connectedSocket)
{
CSSSLogger.ExecutionTrace(this);
clientSocket = connectedSocket;
PeerCred cred = new PeerCred(connectedSocket);
userId = new UnixUserIdentifier(cred.UserID);
}
override internal UserIdentifier GetIPCChannelUserId()
{
CSSSLogger.ExecutionTrace(this);
return userId;
}
private UnixIPCChannel()
{
CSSSLogger.ExecutionTrace(this);
}
~UnixIPCChannel()
{
CSSSLogger.ExecutionTrace(this);
clientSocket.Close();
}
override internal int Read(byte[] buf)
{
return 0;
}
override internal byte[] Read()
{
CSSSLogger.ExecutionTrace(this);
int bytesRecvd = 0;
try
{
byte[] msgIdBytes = new byte[2];
bytesRecvd = clientSocket.Receive(msgIdBytes);
if( 0 == bytesRecvd )
{
return null;
}
if( bytesRecvd < 0 ) // IPC is fine and Client had some problem
{
throw new CommunicationException("Client has not sent data.");
}
byte[] msgLenBytes = new byte[4];
bytesRecvd = clientSocket.Receive(msgLenBytes);
if( 0 == bytesRecvd )
{
return null;
}
if( bytesRecvd < 0 ) // IPC is fine and Client had some problem
{
throw new CommunicationException("Client has not sent data.");
}
byte[] bufToReturn = null;
uint msgLen = BitConverter.ToUInt32(msgLenBytes,0);
if( msgLen > 6 )
{
byte[] buf = new byte[msgLen - 6];
bytesRecvd = clientSocket.Receive (buf);
CSSSLogger.DbgLog("In " + CSSSLogger.GetExecutionPath(this) + " Bytes received is " + bytesRecvd);
if( 0 == bytesRecvd )
{
return null;
}
if( bytesRecvd < 0 ) // IPC is fine and Client had some problem
{
throw new CommunicationException("Client has not sent data.");
}
bufToReturn = new byte[msgLen];
Array.Copy(msgIdBytes,bufToReturn,2);
Array.Copy(msgLenBytes,0,bufToReturn,2,4);
Array.Copy(buf,0,bufToReturn,6,buf.Length);
return bufToReturn;
}
else
{
bufToReturn = new byte[6];
Array.Copy(msgIdBytes,bufToReturn,2);
Array.Copy(msgLenBytes,0,bufToReturn,2,4);
return bufToReturn;
}
}
catch(CommunicationException e)
{
throw e;
}
catch(Exception e)
{
CSSSLogger.ExpLog(e.ToString());
throw new CommunicationException(e.ToString());
}
}
override internal int Write(byte[] buf)
{
try
{
CSSSLogger.ExecutionTrace(this);
int bytesSent = clientSocket.Send(buf);
CSSSLogger.DbgLog("In " + CSSSLogger.GetExecutionPath(this) + " - Bytes sent is " + bytesSent);
return bytesSent;
}
catch(Exception e)
{
CSSSLogger.ExpLog(e.ToString());
return -1;
}
}
override internal void Close()
{
CSSSLogger.ExecutionTrace(this);
clientSocket.Close();
}
}
}

View File

@@ -0,0 +1,40 @@
using System;
using sscs.common;
using sscs.constants;
using sscs.communication.win.InterProcessComm;
using sscs.communication.win.NamedPipes;
namespace sscs.communication
{
/// <summary>
/// Summary description for WinCommunication.
/// </summary>
public class WinCommunication : Communication
{
public static IChannelManager PipeManager;
public WinCommunication()
{
PipeManager = new sscs.communication.win.PipeManager();
PipeManager.Initialize();
}
public void StartCommunicationEndPoint()
{
Console.WriteLine("StartCommunctionEndPointed called");
//PipeManager = new PipeManager();
//PipeManager.Initialize();
//PipeManager.Start();
PipeManager.Start();
}
public void CloseCommunicationEndPoint()
{
PipeManager.Stop();
}
}
}

View File

@@ -0,0 +1,102 @@
using System;
using System.IO;
using System.Text;
using sscs.communication.win.NamedPipes;
using sscs.common;
using sscs.verbs;
using sscs.constants;
namespace sscs.communication
{
class WinIPCChannel : IPCChannel
{
// Data
private ServerPipeConnection m_serverPipeConnection;
private WinUserIdentifier userId = null;
//Methods
public WinIPCChannel(ServerPipeConnection serverPipeConnection)
{
m_serverPipeConnection = serverPipeConnection;
}
override internal UserIdentifier GetIPCChannelUserId()
{
CSSSLogger.DbgLog("In WinIPCChannel::GetIPCChannelUserId");
return userId;
}
private WinIPCChannel()
{
CSSSLogger.DbgLog("WinIPCChannel constructor must be called with a serverPipe");
}
~WinIPCChannel()
{
// Console.WriteLine("WinIPCChannel::~~WinIPCChannel");
}
override internal byte[] Read()
{
int localUserIDLow = 0;
int localUserIDHigh = 0;
string sSIDString = "";
byte[] incoming = null;
try
{
incoming = m_serverPipeConnection.ReadBytes();
// get local Userid and SID
m_serverPipeConnection.GetLocalUserID(ref localUserIDLow, ref localUserIDHigh, ref sSIDString);
if (localUserIDLow != 0 || localUserIDHigh !=0)
{
userId = new WinUserIdentifier(localUserIDLow, localUserIDHigh, sSIDString);
}
return incoming;
}
catch(Exception e)
{
return null;
//CSSSLogger.DbgLog("Exception in reading data from client" + e.ToString());
//throw new CommunicationException(e.ToString());
}
}
override internal int Read(byte[] buf)
{
return 0;
}
override internal int Write(byte[] buf)
{
int bytesSent = 0;
try
{
m_serverPipeConnection.WriteBytes(buf);
bytesSent = buf.Length;
}
catch (Exception)
{
}
CSSSLogger.DbgLog("WinIPCChannel::Write - Bytes sent is {0}" +bytesSent);
return bytesSent;
}
override internal void Close()
{
CSSSLogger.DbgLog("WinIPCChannel Closed");
//clientSocket.Close();
m_serverPipeConnection.Close();
}
}
}

View File

@@ -0,0 +1,72 @@
//////////////////////////////////////////////////
// Created by Ivan Latunov - IvanWeb.com //
//----------------------------------------------//
// This program is free software. You can //
// redistribute it and/or modify it as you wish //
//////////////////////////////////////////////////
using System;
namespace sscs.communication.win.InterProcessComm {
#region Comments
/// <summary>
/// Interface, which defines methods for a Channel Manager class.
/// </summary>
/// <remarks>
/// A Channel Manager is responsible for creating and maintaining channels for inter-process communication. The opened channels are meant to be reusable for performance optimization. Each channel needs to procees requests by calling the <see cref="AppModule.InterProcessComm.IChannelManager.HandleRequest">HandleRequest</see> method of the Channel Manager.
/// </remarks>
#endregion
public interface IChannelManager {
#region Comments
/// <summary>
/// Initializes the Channel Manager.
/// </summary>
#endregion
void Initialize();
#region Comments
/// <summary>
/// Closes all opened channels and stops the Channel Manager.
/// </summary>
#endregion
void Start();
void Stop();
#region Comments
/// <summary>
/// Handles a request.
/// </summary>
/// <remarks>
/// This method currently caters for text based requests. XML strings can be used in case complex request structures are needed.
/// </remarks>
/// <param name="request">The incoming request.</param>
/// <returns>The resulting response.</returns>
#endregion
string HandleRequest(string request);
#region Comments
/// <summary>
/// Indicates whether the Channel Manager is in listening mode.
/// </summary>
/// <remarks>
/// This property is left public so that other classes, like a server channel can start or stop listening based on the Channel Manager mode.
/// </remarks>
#endregion
bool Listen {get; set;}
#region Comments
/// <summary>
/// Forces the Channel Manager to exit a sleeping mode and create a new channel.
/// </summary>
/// <remarks>
/// Normally the Channel Manager will create a number of reusable channels, which will handle the incoming reqiests, and go into a sleeping mode. However if the request load is high, the Channel Manager needs to be asked to create additional channels.
/// </remarks>
#endregion
void WakeUp();
#region Comments
/// <summary>
/// Removes an existing channel.
/// </summary>
/// <param name="param">A parameter identifying the channel.</param>
#endregion
void RemoveServerChannel(object param);
}
}

View File

@@ -0,0 +1,51 @@
//////////////////////////////////////////////////
// Created by Ivan Latunov - IvanWeb.com //
//----------------------------------------------//
// This program is free software. You can //
// redistribute it and/or modify it as you wish //
//////////////////////////////////////////////////
using System;
using System.IO;
namespace sscs.communication.win.InterProcessComm {
#region Comments
/// <summary>
///
/// </summary>
#endregion
public interface IClientChannel : IDisposable {
#region Comments
/// <summary>
///
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
#endregion
string HandleRequest(string request);
#region Comments
/// <summary>
///
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
#endregion
string HandleRequest(Stream request);
#region Comments
/// <summary>
///
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
#endregion
object HandleRequest(object request);
#region Comments
/// <summary>
///
/// </summary>
/// <returns></returns>
#endregion
IClientChannel Create();
}
}

View File

@@ -0,0 +1,72 @@
//////////////////////////////////////////////////
// Created by Ivan Latunov - IvanWeb.com //
//----------------------------------------------//
// This program is free software. You can //
// redistribute it and/or modify it as you wish //
//////////////////////////////////////////////////
using System;
namespace sscs.communication.win.InterProcessComm {
#region Comments
/// <summary>
///
/// </summary>
#endregion
public interface IInterProcessConnection : IDisposable {
#region Comments
/// <summary>
///
/// </summary>
#endregion
int NativeHandle{get;}
#region Comments
/// <summary>
///
/// </summary>
#endregion
void Connect();
#region Comments
/// <summary>
///
/// </summary>
#endregion
void Close();
#region Comments
/// <summary>
///
/// </summary>
/// <returns></returns>
#endregion
string Read();
#region Comments
/// <summary>
///
/// </summary>
/// <returns></returns>
#endregion
byte[] ReadBytes();
#region Comments
/// <summary>
///
/// </summary>
/// <param name="text"></param>
#endregion
void Write(string text);
#region Comments
/// <summary>
///
/// </summary>
/// <param name="bytes"></param>
#endregion
void WriteBytes(byte[] bytes);
#region Comments
/// <summary>
///
/// </summary>
/// <returns></returns>
#endregion
InterProcessConnectionState GetState();
}
}

View File

@@ -0,0 +1,127 @@
//////////////////////////////////////////////////
// Created by Ivan Latunov - IvanWeb.com //
//----------------------------------------------//
// This program is free software. You can //
// redistribute it and/or modify it as you wish //
//////////////////////////////////////////////////
using System;
namespace sscs.communication.win.InterProcessComm {
#region Comments
/// <summary>
///
/// </summary>
#endregion
public enum InterProcessConnectionState {
#region Comments
/// <summary>
///
/// </summary>
#endregion
NotSet = 0,
#region Comments
/// <summary>
///
/// </summary>
#endregion
Error = 1,
#region Comments
/// <summary>
///
/// </summary>
#endregion
Creating = 2,
#region Comments
/// <summary>
///
/// </summary>
#endregion
Created = 3,
#region Comments
/// <summary>
///
/// </summary>
#endregion
WaitingForClient = 4,
#region Comments
/// <summary>
///
/// </summary>
#endregion
ConnectedToClient = 5,
#region Comments
/// <summary>
///
/// </summary>
#endregion
ConnectingToServer = 6,
#region Comments
/// <summary>
///
/// </summary>
#endregion
ConnectedToServer = 7,
#region Comments
/// <summary>
///
/// </summary>
#endregion
Reading = 8,
#region Comments
/// <summary>
///
/// </summary>
#endregion
ReadData = 9,
#region Comments
/// <summary>
///
/// </summary>
#endregion
Writing = 10,
#region Comments
/// <summary>
///
/// </summary>
#endregion
WroteData = 11,
#region Comments
/// <summary>
///
/// </summary>
#endregion
Flushing = 12,
#region Comments
/// <summary>
///
/// </summary>
#endregion
FlushedData = 13,
#region Comments
/// <summary>
///
/// </summary>
#endregion
Disconnecting = 14,
#region Comments
/// <summary>
///
/// </summary>
#endregion
Disconnected = 15,
#region Comments
/// <summary>
///
/// </summary>
#endregion
Closing = 16,
#region Comments
/// <summary>
///
/// </summary>
#endregion
Closed = 17,
}
}

View File

@@ -0,0 +1,49 @@
//////////////////////////////////////////////////
// Created by Ivan Latunov - IvanWeb.com //
//----------------------------------------------//
// This program is free software. You can //
// redistribute it and/or modify it as you wish //
//////////////////////////////////////////////////
using System;
using System.Runtime.Serialization;
namespace sscs.communication.win.InterProcessComm {
#region Comments
/// <summary>
///
/// </summary>
#endregion
public class InterProcessIOException : Exception {
#region Comments
/// <summary>
///
/// </summary>
#endregion
public bool IsServerAvailable = true;
#region Comments
/// <summary>
///
/// </summary>
#endregion
public uint ErrorCode = 0;
#region Comments
/// <summary>
///
/// </summary>
/// <param name="text"></param>
#endregion
public InterProcessIOException(String text) : base(text) {
}
#region Comments
/// <summary>
///
/// </summary>
/// <param name="info"></param>
/// <param name="context"></param>
#endregion
protected InterProcessIOException(SerializationInfo info, StreamingContext context) : base(info, context) {
}
}
}

View File

@@ -0,0 +1,184 @@
//////////////////////////////////////////////////
// Created by Ivan Latunov - IvanWeb.com //
//----------------------------------------------//
// This program is free software. You can //
// redistribute it and/or modify it as you wish //
//////////////////////////////////////////////////
using System;
using System.IO;
using sscs.communication.win.InterProcessComm;
namespace sscs.communication.win.NamedPipes {
#region Comments
/// <summary>
/// An abstract class, which defines the methods for creating named pipes
/// connections, reading and writing data.
/// </summary>
/// <remarks>
/// This class is inherited by
/// <see cref="AppModule.NamedPipes.ClientPipeConnection">ClientPipeConnection</see>
/// and <see cref="AppModule.NamedPipes.ServerPipeConnection">ServerPipeConnection</see>
/// classes, used for client and server applications respectively, which communicate
/// using NamesPipes.
/// </remarks>
#endregion
public abstract class APipeConnection : IInterProcessConnection {
#region Comments
/// <summary>
/// A <see cref="AppModule.NamedPipes.PipeHandle">PipeHandle</see> object containing
/// the native pipe handle.
/// </summary>
#endregion
protected PipeHandle Handle = new PipeHandle();
#region Comments
/// <summary>
/// The name of the named pipe.
/// </summary>
/// <remarks>
/// This name is used for creating a server pipe and connecting client ones to it.
/// </remarks>
#endregion
protected string Name;
#region Comments
/// <summary>
/// Boolean field used by the IDisposable implementation.
/// </summary>
#endregion
protected bool disposed = false;
#region Comments
/// <summary>
/// The maximum bytes that will be read from the pipe connection.
/// </summary>
/// <remarks>
/// This field could be used if the maximum length of the client message
/// is known and we want to implement some security, which prevents the
/// server from reading larger messages.
/// </remarks>
#endregion
protected int maxReadBytes;
#region Comments
/// <summary>
/// Reads a message from the pipe connection and converts it to a string
/// using the UTF8 encoding.
/// </summary>
/// <remarks>
/// See the <see cref="AppModule.NamedPipes.NamedPipeWrapper.Read">NamedPipeWrapper.Read</see>
/// method for an explanation of the message format.
/// </remarks>
/// <returns>The UTF8 encoded string representation of the data.</returns>
#endregion
public string Read() {
CheckIfDisposed();
return NamedPipeWrapper.Read(Handle, maxReadBytes);
}
#region Comments
/// <summary>
/// Reads a message from the pipe connection.
/// </summary>
/// <remarks>
/// See the <see cref="AppModule.NamedPipes.NamedPipeWrapper.ReadBytes">NamedPipeWrapper.ReadBytes</see>
/// method for an explanation of the message format.
/// </remarks>
/// <returns>The bytes read from the pipe connection.</returns>
#endregion
public byte[] ReadBytes() {
CheckIfDisposed();
return NamedPipeWrapper.ReadBytes(Handle, maxReadBytes);
}
#region Comments
/// <summary>
/// Writes a string to the pipe connection/
/// </summary>
/// <param name="text">The text to write.</param>
#endregion
public void Write(string text) {
CheckIfDisposed();
NamedPipeWrapper.Write(Handle, text);
}
#region Comments
/// <summary>
/// Writes an array of bytes to the pipe connection.
/// </summary>
/// <param name="bytes">The bytes array.</param>
#endregion
public void WriteBytes(byte[] bytes) {
CheckIfDisposed();
NamedPipeWrapper.WriteBytes(Handle, bytes);
}
#region Comments
/// <summary>
/// Closes the pipe connection.
/// </summary>
#endregion
public abstract void Close();
#region Comments
/// <summary>
/// Connects a pipe connection.
/// </summary>
#endregion
public abstract void Connect();
#region Comments
/// <summary>
/// Disposes a pipe connection by closing the underlying native handle.
/// </summary>
#endregion
public void Dispose() {
Dispose(true);
GC.SuppressFinalize(this);
}
#region Comments
/// <summary>
/// Disposes a pipe connection by closing the underlying native handle.
/// </summary>
/// <param name="disposing">A boolean indicating how the method is called.</param>
#endregion
protected void Dispose(bool disposing) {
if(!this.disposed) {
NamedPipeWrapper.Close(this.Handle);
}
disposed = true;
}
#region Comments
/// <summary>
/// Checks if the pipe connection is disposed.
/// </summary>
/// <remarks>
/// This check is done before performing any pipe operations.
/// </remarks>
#endregion
public void CheckIfDisposed() {
if(this.disposed) {
throw new ObjectDisposedException("The Pipe Connection is disposed.");
}
}
#region Comments
/// <summary>
/// Gets the pipe connection state from the <see cref="AppModule.NamedPipes.PipeHandle">PipeHandle</see>
/// object.
/// </summary>
/// <returns>The pipe connection state.</returns>
#endregion
public InterProcessConnectionState GetState() {
CheckIfDisposed();
return this.Handle.State;
}
#region Comments
/// <summary>
/// Retrieved the operating system native handle for the pipe connection.
/// </summary>
#endregion
public int NativeHandle {
get {
CheckIfDisposed();
return (int)this.Handle.Handle;
}
}
public int GetLocalUserID(ref int lowPart, ref int highPart, ref string sSIDString)
{
return NamedPipeWrapper.GetLocalUserID(this.Handle, ref lowPart, ref highPart, ref sSIDString);
}
}
}

View File

@@ -0,0 +1,110 @@
//////////////////////////////////////////////////
// Created by Ivan Latunov - IvanWeb.com //
//----------------------------------------------//
// This program is free software. You can //
// redistribute it and/or modify it as you wish //
//////////////////////////////////////////////////
using System;
using System.IO;
using sscs.communication.win.InterProcessComm;
namespace sscs.communication.win.NamedPipes {
#region Comments
/// <summary>
/// Used by client applications to communicate with server ones by using named pipes.
/// </summary>
#endregion
public sealed class ClientPipeConnection : APipeConnection {
#region Comments
/// <summary>
/// The network name of the server where the server pipe is created.
/// </summary>
/// <remarks>
/// If "." is used as a server name then the pipe is connected to the local machine.
/// </remarks>
#endregion
private string Server = ".";
#region Comments
/// <summary>
/// Closes a client named pipe connection.
/// </summary>
/// <remarks>
/// A client pipe connection is closed by closing the underlying pipe handle.
/// </remarks>
#endregion
public override void Close() {
CheckIfDisposed();
NamedPipeWrapper.Close(this.Handle);
}
#region Comments
/// <summary>
/// Connects a client pipe to an existing server one.
/// </summary>
#endregion
public override void Connect() {
CheckIfDisposed();
this.Handle = NamedPipeWrapper.ConnectToPipe(this.Name, this.Server);
}
#region Comments
/// <summary>
/// Attempts to establish a connection to the a server named pipe.
/// </summary>
/// <remarks>
/// If the attempt is successful the method creates the
/// <see cref="AppModule.NamedPipes.PipeHandle">PipeHandle</see> object
/// and assigns it to the <see cref="AppModule.NamedPipes.APipeConnection.Handle">Handle</see>
/// field.<br/><br/>
/// This method is used when it is not known whether a server pipe already exists.
/// </remarks>
/// <returns>True if a connection is established.</returns>
#endregion
public bool TryConnect() {
CheckIfDisposed();
bool ReturnVal = NamedPipeWrapper.TryConnectToPipe(this.Name, this.Server, out this.Handle);
return ReturnVal;
}
#region Comments
/// <summary>
/// Creates an instance of the ClientPipeConnection assuming that the server pipe
/// is created on the same machine.
/// </summary>
/// <remarks>
/// The maximum bytes to read from the client is set to be Int32.MaxValue.
/// </remarks>
/// <param name="name">The name of the server pipe.</param>
#endregion
public ClientPipeConnection(string name) {
this.Name = name;
this.Server = ".";
this.maxReadBytes = Int32.MaxValue;
}
#region Comments
/// <summary>
/// Creates an instance of the ClientPipeConnection specifying the network name
/// of the server.
/// </summary>
/// <remarks>
/// The maximum bytes to read from the client is set to be Int32.MaxValue.
/// </remarks>
/// <param name="name">The name of the server pipe.</param>
/// <param name="server">The network name of the machine, where the server pipe is created.</param>
#endregion
public ClientPipeConnection(string name, string server) {
this.Name = name;
this.Server = server;
this.maxReadBytes = Int32.MaxValue;
}
#region Comments
/// <summary>
/// Object destructor.
/// </summary>
#endregion
~ClientPipeConnection() {
Dispose(false);
}
}
}

View File

@@ -0,0 +1,52 @@
//////////////////////////////////////////////////
// Created by Ivan Latunov - IvanWeb.com //
//----------------------------------------------//
// This program is free software. You can //
// redistribute it and/or modify it as you wish //
//////////////////////////////////////////////////
using System;
using System.Runtime.Serialization;
using sscs.communication.win.InterProcessComm;
namespace sscs.communication.win.NamedPipes {
#region Comments
/// <summary>
/// This exception is thrown by named pipes communication methods.
/// </summary>
#endregion
public class NamedPipeIOException : InterProcessIOException {
#region Comments
/// <summary>
/// Creates a NamedPipeIOException instance.
/// </summary>
/// <param name="text">The error message text.</param>
#endregion
public NamedPipeIOException(String text) : base(text) {
}
#region Comments
/// <summary>
/// Creates a NamedPipeIOException instance.
/// </summary>
/// <param name="text">The error message text.</param>
/// <param name="errorCode">The native error code.</param>
#endregion
public NamedPipeIOException(String text, uint errorCode) : base(text) {
this.ErrorCode = errorCode;
if (errorCode == NamedPipeNative.ERROR_CANNOT_CONNECT_TO_PIPE) {
this.IsServerAvailable = false;
}
}
#region Comments
/// <summary>
/// Creates a NamedPipeIOException instance.
/// </summary>
/// <param name="info">The serialization information.</param>
/// <param name="context">The streaming context.</param>
#endregion
protected NamedPipeIOException(SerializationInfo info, StreamingContext context) : base(info, context) {
}
}
}

View File

@@ -0,0 +1,641 @@
using System;
using System.Text;
using System.Security;
using System.Runtime.InteropServices;
namespace sscs.communication.win.NamedPipes {
#region Comments
/// <summary>
/// This utility class exposes kernel32.dll methods for named pipes communication.
/// </summary>
/// <remarks>
/// Use the following links for complete information about the exposed methods:
/// <list type="bullet">
/// <item>
/// <description><a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/ipc/base/pipe_functions.asp" target="_blank">Named Pipe Functions</a></description>
/// </item>
/// <item>
/// <description><a href="http://msdn.microsoft.com/library/en-us/fileio/base/file_management_functions.asp" target="_blank">File Management Functions</a></description>
/// </item>
/// <item>
/// <description><a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sysinfo/base/handle_and_object_functions.asp" target="_blank">Handle and Object Functions</a></description>
/// </item>
/// <item>
/// <description><a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/debug/base/system_error_codes.asp" target="_blank">System Error Codes</a></description>
/// </item>
/// </list>
/// </remarks>
#endregion
[SuppressUnmanagedCodeSecurity]
public sealed class NamedPipeNative {
#region Comments
/// <summary>
/// Outbound pipe access.
/// </summary>
#endregion
public const uint PIPE_ACCESS_OUTBOUND = 0x00000002;
#region Comments
/// <summary>
/// Duplex pipe access.
/// </summary>
#endregion
public const uint PIPE_ACCESS_DUPLEX = 0x00000003;
#region Comments
/// <summary>
/// Inbound pipe access.
/// </summary>
#endregion
public const uint PIPE_ACCESS_INBOUND = 0x00000001;
#region Comments
/// <summary>
/// Pipe blocking mode.
/// </summary>
#endregion
public const uint PIPE_WAIT = 0x00000000;
#region Comments
/// <summary>
/// Pipe non-blocking mode.
/// </summary>
#endregion
public const uint PIPE_NOWAIT = 0x00000001;
#region Comments
/// <summary>
/// Pipe read mode of type Byte.
/// </summary>
#endregion
public const uint PIPE_READMODE_BYTE = 0x00000000;
#region Comments
/// <summary>
/// Pipe read mode of type Message.
/// </summary>
#endregion
public const uint PIPE_READMODE_MESSAGE = 0x00000002;
#region Comments
/// <summary>
/// Byte pipe type.
/// </summary>
#endregion
public const uint PIPE_TYPE_BYTE = 0x00000000;
#region Comments
/// <summary>
/// Message pipe type.
/// </summary>
#endregion
public const uint PIPE_TYPE_MESSAGE = 0x00000004;
#region Comments
/// <summary>
/// Pipe client end.
/// </summary>
#endregion
public const uint PIPE_CLIENT_END = 0x00000000;
#region Comments
/// <summary>
/// Pipe server end.
/// </summary>
#endregion
public const uint PIPE_SERVER_END = 0x00000001;
#region Comments
/// <summary>
/// Unlimited server pipe instances.
/// </summary>
#endregion
public const uint PIPE_UNLIMITED_INSTANCES = 255;
#region Comments
/// <summary>
/// Waits indefinitely when connecting to a pipe.
/// </summary>
#endregion
public const uint NMPWAIT_WAIT_FOREVER = 0xffffffff;
#region Comments
/// <summary>
/// Does not wait for the named pipe.
/// </summary>
#endregion
public const uint NMPWAIT_NOWAIT = 0x00000001;
#region Comments
/// <summary>
/// Uses the default time-out specified in a call to the CreateNamedPipe method.
/// </summary>
#endregion
public const uint NMPWAIT_USE_DEFAULT_WAIT = 0x00000000;
#region Comments
/// <summary>
///
/// </summary>
#endregion
public const uint GENERIC_READ = (0x80000000);
#region Comments
/// <summary>
/// Generic write access to the pipe.
/// </summary>
#endregion
public const uint GENERIC_WRITE = (0x40000000);
#region Comments
/// <summary>
/// Generic execute access to the pipe.
/// </summary>
#endregion
public const uint GENERIC_EXECUTE = (0x20000000);
#region Comments
/// <summary>
/// Read, write, and execute access.
/// </summary>
#endregion
public const uint GENERIC_ALL = (0x10000000);
#region Comments
/// <summary>
/// Create new file. Fails if the file exists.
/// </summary>
#endregion
public const uint CREATE_NEW = 1;
#region Comments
/// <summary>
/// Create new file. Overrides an existing file.
/// </summary>
#endregion
public const uint CREATE_ALWAYS = 2;
#region Comments
/// <summary>
/// Open existing file.
/// </summary>
#endregion
public const uint OPEN_EXISTING = 3;
#region Comments
/// <summary>
/// Open existing file. If the file does not exist, creates it.
/// </summary>
#endregion
public const uint OPEN_ALWAYS = 4;
#region Comments
/// <summary>
/// Opens the file and truncates it so that its size is zero bytes.
/// </summary>
#endregion
public const uint TRUNCATE_EXISTING = 5;
#region Comments
/// <summary>
/// Invalid operating system handle.
/// </summary>
#endregion
public const int INVALID_HANDLE_VALUE = -1;
#region Comments
/// <summary>
/// The operation completed successfully.
/// </summary>
#endregion
public const ulong ERROR_SUCCESS = 0;
#region Comments
/// <summary>
/// The system cannot find the file specified.
/// </summary>
#endregion
public const ulong ERROR_CANNOT_CONNECT_TO_PIPE = 2;
#region Comments
/// <summary>
/// All pipe instances are busy.
/// </summary>
#endregion
public const ulong ERROR_PIPE_BUSY = 231;
#region Comments
/// <summary>
/// The pipe is being closed.
/// </summary>
#endregion
public const ulong ERROR_NO_DATA = 232;
#region Comments
/// <summary>
/// No process is on the other end of the pipe.
/// </summary>
#endregion
public const ulong ERROR_PIPE_NOT_CONNECTED = 233;
#region Comments
/// <summary>
/// More data is available.
/// </summary>
#endregion
public const ulong ERROR_MORE_DATA = 234;
#region Comments
/// <summary>
/// There is a process on other end of the pipe.
/// </summary>
#endregion
public const ulong ERROR_PIPE_CONNECTED = 535;
#region Comments
/// <summary>
/// Waiting for a process to open the other end of the pipe.
/// </summary>
#endregion
public const ulong ERROR_PIPE_LISTENING = 536;
#region Comments
/// <summary>
///
/// </summary>
#endregion
public const int TOKEN_QUERY = 0X00000008;
public enum TOKEN_INFORMATION_CLASS
{
TokenUser = 1,
TokenGroups,
TokenPrivileges,
TokenOwner,
TokenPrimaryGroup,
TokenDefaultDacl,
TokenSource,
TokenType,
TokenImpersonationLevel,
TokenStatistics,
TokenRestrictedSids,
TokenSessionId
}
[StructLayout(LayoutKind.Sequential)]
public struct TOKEN_USER
{
public _SID_AND_ATTRIBUTES User;
}
[StructLayout(LayoutKind.Sequential)]
public struct _SID_AND_ATTRIBUTES
{
public IntPtr Sid;
public int Attributes;
}
[StructLayout(LayoutKind.Sequential)]
public struct _LUID
{
public int LowPart ;
public int HighPart;
} //LUID, *PLUID;
[StructLayout(LayoutKind.Sequential)]
public struct TOKEN_STATISTICS
{
public _LUID TokenId;
public _LUID AuthenticationId;
public int ExpirationTime;
public int TokenType; // enum ini in 1 TOKEN_TYPE
public int ImpersonationLevel; //SECURITY_IMPERSONATION_LEVEL ImpersonationLevel;
public int DynamicCharged; ////DWORD
public int DynamicAvailable; //DWORD
public int GroupCount; //DWORD
public int PrivilegeCount; //DWORD
public _LUID ModifiedId;
}// TOKEN_STATISTICS, *PTOKEN_STATISTICS;
#region Comments
/// <summary>
/// Creates an instance of a named pipe and returns a handle for
/// subsequent pipe operations.
/// </summary>
/// <param name="lpName">Pointer to the null-terminated string that
/// uniquely identifies the pipe.</param>
/// <param name="dwOpenMode">Pipe access mode, the overlapped mode,
/// the write-through mode, and the security access mode of the pipe handle.</param>
/// <param name="dwPipeMode">Type, read, and wait modes of the pipe handle.</param>
/// <param name="nMaxInstances">Maximum number of instances that can be
/// created for this pipe.</param>
/// <param name="nOutBufferSize">Number of bytes to reserve for the output buffer.</param>
/// <param name="nInBufferSize">Number of bytes to reserve for the input buffer.</param>
/// <param name="nDefaultTimeOut">Default time-out value, in milliseconds.</param>
/// <param name="pipeSecurityDescriptor">Pointer to a
/// <see cref="AppModule.NamedPipes.SecurityAttributes">SecurityAttributes</see>
/// object that specifies a security descriptor for the new named pipe.</param>
/// <returns>If the function succeeds, the return value is a handle
/// to the server end of a named pipe instance.</returns>
#endregion
[DllImport("kernel32.dll")]
public static extern IntPtr CreateNamedPipe(
String lpName, // pipe name
uint dwOpenMode, // pipe open mode
uint dwPipeMode, // pipe-specific modes
uint nMaxInstances, // maximum number of instances
uint nOutBufferSize, // output buffer size
uint nInBufferSize, // input buffer size
uint nDefaultTimeOut, // time-out interval
IntPtr pipeSecurityDescriptor // SD
);
#region Comments
/// <summary>
/// Enables a named pipe server process to wait for a client
/// process to connect to an instance of a named pipe.
/// </summary>
/// <param name="hHandle">Handle to the server end of a named pipe instance.</param>
/// <param name="lpOverlapped">Pointer to an
/// <see cref="AppModule.NamedPipes.Overlapped">Overlapped</see> object.</param>
/// <returns>If the function succeeds, the return value is nonzero.</returns>
#endregion
[DllImport("kernel32.dll")]
public static extern bool ConnectNamedPipe(
IntPtr hHandle, // handle to named pipe
Overlapped lpOverlapped // overlapped structure
);
#region Comments
/// <summary>
/// Connects to a message-type pipe (and waits if an instance of the
/// pipe is not available), writes to and reads from the pipe, and then closes the pipe.
/// </summary>
/// <param name="lpNamedPipeName">Pointer to a null-terminated string
/// specifying the pipe name.</param>
/// <param name="lpInBuffer">Pointer to the buffer containing the data written
/// to the pipe.</param>
/// <param name="nInBufferSize">Size of the write buffer, in bytes.</param>
/// <param name="lpOutBuffer">Pointer to the buffer that receives the data
/// read from the pipe.</param>
/// <param name="nOutBufferSize">Size of the read buffer, in bytes.</param>
/// <param name="lpBytesRead">Pointer to a variable that receives the number
/// of bytes read from the pipe.</param>
/// <param name="nTimeOut">Number of milliseconds to wait for the
/// named pipe to be available.</param>
/// <returns>If the function succeeds, the return value is nonzero.</returns>
#endregion
[DllImport("kernel32.dll")]
public static extern bool CallNamedPipe(
string lpNamedPipeName,
byte[] lpInBuffer,
uint nInBufferSize,
byte[] lpOutBuffer,
uint nOutBufferSize,
byte[] lpBytesRead,
int nTimeOut
);
#region Comments
/// <summary>
/// Creates or opens a file, directory, physical disk, volume, console buffer,
/// tape drive, communications resource, mailslot, or named pipe.
/// </summary>
/// <param name="lpFileName">Pointer to a null-terminated string that
/// specifies the name of the object to create or open.</param>
/// <param name="dwDesiredAccess">Access to the object (reading, writing, or both).</param>
/// <param name="dwShareMode">Sharing mode of the object (reading, writing, both, or neither).</param>
/// <param name="attr">Pointer to a
/// <see cref="AppModule.NamedPipes.SecurityAttributes">SecurityAttributes</see>
/// object that determines whether the returned handle can be inherited
/// by child processes.</param>
/// <param name="dwCreationDisposition">Action to take on files that exist,
/// and which action to take when files do not exist.</param>
/// <param name="dwFlagsAndAttributes">File attributes and flags.</param>
/// <param name="hTemplateFile">Handle to a template file, with the GENERIC_READ access right.</param>
/// <returns>If the function succeeds, the return value is an open handle to the specified file.</returns>
#endregion
[DllImport("kernel32.dll")]
public static extern IntPtr CreateFile(
String lpFileName, // file name
uint dwDesiredAccess, // access mode
uint dwShareMode, // share mode
SecurityAttributes attr, // SD
uint dwCreationDisposition, // how to create
uint dwFlagsAndAttributes, // file attributes
uint hTemplateFile); // handle to template file
#region Comments
/// <summary>
/// Reads data from a file, starting at the position indicated by the file pointer.
/// </summary>
/// <param name="hHandle">Handle to the file to be read.</param>
/// <param name="lpBuffer">Pointer to the buffer that receives the data read from the file.</param>
/// <param name="nNumberOfBytesToRead">Number of bytes to be read from the file.</param>
/// <param name="lpNumberOfBytesRead">Pointer to the variable that receives the number of bytes read.</param>
/// <param name="lpOverlapped">Pointer to an
/// <see cref="AppModule.NamedPipes.Overlapped">Overlapped</see> object.</param>
/// <returns>The ReadFile function returns when one of the following
/// conditions is met: a write operation completes on the write end of
/// the pipe, the number of bytes requested has been read, or an error occurs.</returns>
#endregion
[DllImport("kernel32.dll")]
public static extern bool ReadFile(
IntPtr hHandle, // handle to file
byte[] lpBuffer, // data buffer
uint nNumberOfBytesToRead, // number of bytes to read
byte[] lpNumberOfBytesRead, // number of bytes read
uint lpOverlapped // overlapped buffer
);
#region Comments
/// <summary>
/// Writes data to a file at the position specified by the file pointer.
/// </summary>
/// <param name="hHandle">Handle to the file.</param>
/// <param name="lpBuffer">Pointer to the buffer containing the data to be written to the file.</param>
/// <param name="nNumberOfBytesToWrite"></param>
/// <param name="lpNumberOfBytesWritten">Pointer to the variable that receives the number of bytes written.</param>
/// <param name="lpOverlapped">Pointer to an
/// <see cref="AppModule.NamedPipes.Overlapped">Overlapped</see> object.</param>
/// <returns>If the function succeeds, the return value is nonzero.</returns>
#endregion
[DllImport("kernel32.dll")]
public static extern bool WriteFile(
IntPtr hHandle, // handle to file
byte[] lpBuffer, // data buffer
uint nNumberOfBytesToWrite, // number of bytes to write
byte[] lpNumberOfBytesWritten, // number of bytes written
uint lpOverlapped // overlapped buffer
);
#region Comments
/// <summary>
/// Retrieves information about a specified named pipe.
/// </summary>
/// <param name="hHandle">Handle to the named pipe for which information is wanted.</param>
/// <param name="lpState">Pointer to a variable that indicates the current
/// state of the handle.</param>
/// <param name="lpCurInstances">Pointer to a variable that receives the
/// number of current pipe instances.</param>
/// <param name="lpMaxCollectionCount">Pointer to a variable that receives
/// the maximum number of bytes to be collected on the client's computer
/// before transmission to the server.</param>
/// <param name="lpCollectDataTimeout">Pointer to a variable that receives
/// the maximum time, in milliseconds, that can pass before a remote named
/// pipe transfers information over the network.</param>
/// <param name="lpUserName">Pointer to a buffer that receives the
/// null-terminated string containing the user name string associated
/// with the client application. </param>
/// <param name="nMaxUserNameSize">Size of the buffer specified by the
/// lpUserName parameter.</param>
/// <returns>If the function succeeds, the return value is nonzero.</returns>
#endregion
[DllImport("kernel32.dll")]
public static extern bool GetNamedPipeHandleState(
IntPtr hHandle,
IntPtr lpState,
ref uint lpCurInstances,
IntPtr lpMaxCollectionCount,
IntPtr lpCollectDataTimeout,
IntPtr lpUserName,
IntPtr nMaxUserNameSize
);
#region Comments
/// <summary>
/// Cancels all pending input and output (I/O) operations that were
/// issued by the calling thread for the specified file handle.
/// </summary>
/// <param name="hHandle">Handle to a file.</param>
/// <returns>If the function succeeds, the return value is nonzero.</returns>
#endregion
[DllImport("kernel32.dll")]
public static extern bool CancelIo(
IntPtr hHandle
);
#region Comments
/// <summary>
/// Waits until either a time-out interval elapses or an instance
/// of the specified named pipe is available for connection.
/// </summary>
/// <param name="name">Pointer to a null-terminated string that specifies
/// the name of the named pipe.</param>
/// <param name="timeout">Number of milliseconds that the function will
/// wait for an instance of the named pipe to be available.</param>
/// <returns>If an instance of the pipe is available before the
/// time-out interval elapses, the return value is nonzero.</returns>
#endregion
[DllImport("kernel32.dll")]
public static extern bool WaitNamedPipe(
String name,
int timeout);
#region Comments
/// <summary>
/// Retrieves the calling thread's last-error code value.
/// </summary>
/// <returns>The return value is the calling thread's last-error code value.</returns>
#endregion
[DllImport("kernel32.dll")]
public static extern uint GetLastError();
#region Comments
/// <summary>
/// Flushes the buffers of the specified file and causes all buffered data to be written to the file.
/// </summary>
/// <param name="hHandle">Handle to an open file.</param>
/// <returns>If the function succeeds, the return value is nonzero.</returns>
#endregion
[DllImport("kernel32.dll")]
public static extern bool FlushFileBuffers(
IntPtr hHandle);
#region Comments
/// <summary>
/// Disconnects the server end of a named pipe instance from a client process.
/// </summary>
/// <param name="hHandle">Handle to an instance of a named pipe.</param>
/// <returns>If the function succeeds, the return value is nonzero.</returns>
#endregion
[DllImport("kernel32.dll")]
public static extern bool DisconnectNamedPipe(
IntPtr hHandle);
#region Comments
/// <summary>
/// Sets the read mode and the blocking mode of the specified named pipe.
/// </summary>
/// <remarks>
/// If the specified handle is to the client end of a named pipe and if
/// the named pipe server process is on a remote computer, the function
/// can also be used to control local buffering.
/// </remarks>
/// <param name="hHandle">Handle to the named pipe instance.</param>
/// <param name="mode">Pointer to a variable that supplies the new mode.</param>
/// <param name="cc">Pointer to a variable that specifies the maximum
/// number of bytes collected on the client computer before
/// transmission to the server.</param>
/// <param name="cd">Pointer to a variable that specifies the
/// maximum time, in milliseconds, that can pass before a remote
/// named pipe transfers information over the network.</param>
/// <returns>If the function succeeds, the return value is nonzero.</returns>
#endregion
[DllImport("kernel32.dll")]
public static extern bool SetNamedPipeHandleState(
IntPtr hHandle,
ref uint mode,
IntPtr cc,
IntPtr cd);
#region Comments
/// <summary>
/// Closes an open object handle.
/// </summary>
/// <param name="hHandle">Handle to an open object.</param>
/// <returns>If the function succeeds, the return value is nonzero.</returns>
#endregion
[DllImport("kernel32.dll")]
public static extern bool CloseHandle(
IntPtr hHandle);
[DllImport("kernel32.dll")]
public static extern IntPtr GetCurrentThread();
// native for named pipes
#region Comments
/// <summary>
/// Closes an open object handle.
/// </summary>
/// <param name="hHandle">Handle to an open object.</param>
/// <returns>If the function succeeds, the return value is nonzero.</returns>
#endregion
[DllImport("advapi32" )]
public static extern int ImpersonateNamedPipeClient(
IntPtr hHandle);
[DllImport("advapi32" )]
public static extern bool RevertToSelf();
[DllImport("advapi32", SetLastError=true)]
public static extern bool OpenThreadToken(
IntPtr hThread,
uint desiredInfo,
bool openAsSelf,
out IntPtr TokenHandle); // handle to open access token
[DllImport("advapi32")]
public static extern bool OpenProcessToken(
IntPtr ProcessHandle, // handle to process
int DesiredAccess, // desired access to process
ref IntPtr TokenHandle // handle to open access token
);
[DllImport("advapi32", CharSet=CharSet.Auto)]
public static extern bool GetTokenInformation(
IntPtr hToken,
TOKEN_INFORMATION_CLASS tokenInfoClass,
IntPtr TokenInformation,
int tokeInfoLength,
ref int reqLength);
[DllImport("advapi32", CharSet=CharSet.Auto)]
public static extern bool LookupAccountSid
(
[In,MarshalAs(UnmanagedType.LPTStr)] string lpSystemName, // name of local or remote computer
IntPtr pSid, // security identifier
StringBuilder Account, // account name buffer
ref int cbName, // size of account name buffer
StringBuilder DomainName, // domain name
ref int cbDomainName, // size of domain name buffer
ref int peUse // SID type
// ref _SID_NAME_USE peUse // SID type
);
[DllImport("advapi32", CharSet=CharSet.Auto)]
public static extern bool ConvertSidToStringSid(
IntPtr pSID,
[In,Out,MarshalAs(UnmanagedType.LPTStr)] ref string pStringSid);
#region Comments
/// <summary>
/// Private constructor.
/// </summary>
#endregion
private NamedPipeNative() {}
}
#region Comments
/// <summary>
/// This class is used as a dummy parameter only.
/// </summary>
#endregion
[StructLayout(LayoutKind.Sequential)]
public class SecurityAttributes {
}
#region Comments
/// <summary>
/// This class is used as a dummy parameter only.
/// </summary>
#endregion
[StructLayout(LayoutKind.Sequential)]
public class Overlapped {
}
}

View File

@@ -0,0 +1,628 @@
//////////////////////////////////////////////////
// Created by Ivan Latunov - IvanWeb.com //
//----------------------------------------------//
// This program is free software. You can //
// redistribute it and/or modify it as you wish //
//////////////////////////////////////////////////
using System;
using sscs.communication.win.InterProcessComm;
using System.Runtime.InteropServices;
using System.Text;
using HANDLE = System.IntPtr;
namespace sscs.communication.win.NamedPipes
{
#region Comments
/// <summary>
/// A utility class that exposes named pipes operations.
/// </summary>
/// <remarks>
/// This class uses the exposed exposed kernel32.dll methods by the
/// <see cref="AppModule.NamedPipes.NamedPipeNative">NamedPipeNative</see> class
/// to provided controlled named pipe functionality.
/// </remarks>
#endregion
public sealed class NamedPipeWrapper
{
public const int TOKEN_QUERY = 0X00000008;
const int ERROR_NO_MORE_ITEMS = 259;
#region Comments
/// <summary>
/// The number of retries when creating a pipe or connecting to a pipe.
/// </summary>
#endregion
private const int ATTEMPTS = 2;
#region Comments
/// <summary>
/// Wait time for the
/// <see cref="AppModule.NamedPipes.NamedPipeNative.WaitNamedPipe">NamedPipeNative.WaitNamedPipe</see>
/// operation.
/// </summary>
#endregion
private const int WAIT_TIME = 5000;
#region Comments
/// <summary>
/// Reads a string from a named pipe using the UTF8 encoding.
/// </summary>
/// <param name="handle">The pipe handle.</param>
/// <param name="maxBytes">The maximum bytes to read.</param>
/// <returns>A UTF8 string.</returns>
/// <remarks>This function uses
/// <see cref="AppModule.NamedPipes.NamedPipeWrapper.ReadBytes">AppModule.NamedPipes.ReadBytes</see>
/// to read the bytes from the pipe and then converts them to string.<br/><br/>
/// The first four bytes of the pipe data are expected to contain
/// the data length of the message. This method first reads those four
/// bytes and converts them to integer. It then continues to read from the pipe using
/// the extracted data length.
/// </remarks>
#endregion
public static string Read(PipeHandle handle, int maxBytes)
{
string returnVal = "";
byte[] bytes = ReadBytes(handle, maxBytes);
if (bytes != null)
{
returnVal = System.Text.Encoding.UTF8.GetString(bytes);
}
return returnVal;
}
#region Comments
/// <summary>
/// Reads the bytes from a named pipe.
/// </summary>
/// <param name="handle">The pipe handle.</param>
/// <param name="maxBytes">The maximum bytes to read.</param>
/// <returns>An array of bytes.</returns>
/// <remarks>This method expects that the first four bytes in the pipe define
/// the length of the data to read. If the data length is greater than
/// <b>maxBytes</b> the method returns null.<br/><br/>
/// The first four bytes of the pipe data are expected to contain
/// the data length of the message. This method first reads those four
/// bytes and converts them to integer. It then continues to read from the pipe using
/// the extracted data length.
/// </remarks>
#endregion
public static byte[] ReadBytes(PipeHandle handle, int maxBytes)
{
byte[] numReadWritten = new byte[4];
byte[] intBytes = new byte[4];
byte[] msgBytes = null;
int len;
// Set the Handle state to Reading
handle.State = InterProcessConnectionState.Reading;
// Read the first four bytes and convert them to integer
bool bReadSuccessful = true;
try
{
bReadSuccessful = NamedPipeNative.ReadFile(handle.Handle, intBytes, 4, numReadWritten, 0);
}
catch (Exception)
{
// Console.WriteLine("Error on ReadFile "+e.ToString());
}
if (bReadSuccessful)
{
len = BitConverter.ToInt32(intBytes, 0);
msgBytes = new byte[len];
// Read the rest of the data
if (!NamedPipeNative.ReadFile(handle.Handle, msgBytes, (uint)len, numReadWritten, 0))
{
handle.State = InterProcessConnectionState.Error;
throw new NamedPipeIOException("Error reading from pipe. Internal error: " + NamedPipeNative.GetLastError().ToString(), NamedPipeNative.GetLastError());
}
}
else
{
handle.State = InterProcessConnectionState.Error;
throw new NamedPipeIOException("Error reading from pipe. Internal error: " + NamedPipeNative.GetLastError().ToString(), NamedPipeNative.GetLastError());
}
handle.State = InterProcessConnectionState.ReadData;
if (len > maxBytes)
{
return null;
}
return msgBytes;
}
#region Comments
/// <summary>
/// Writes a string to a named pipe.
/// </summary>
/// <param name="handle">The pipe handle.</param>
/// <param name="text">The text to write to the pipe.</param>
/// <remarks>This method converts the text into an array of bytes, using the
/// UTF8 encoding and the uses
/// <see cref="AppModule.NamedPipes.NamedPipeWrapper.WriteBytes">AppModule.NamedPipes.WriteBytes</see>
/// to write to the pipe.<br/><br/>
/// When writing to a pipe the method first writes four bytes that define the data length.
/// It then writes the whole message.</remarks>
#endregion
public static void Write(PipeHandle handle, string text)
{
WriteBytes(handle, System.Text.Encoding.UTF8.GetBytes(text));
}
#region Comments
/// <summary>
/// Writes an array of bytes to a named pipe.
/// </summary>
/// <param name="handle">The pipe handle.</param>
/// <param name="bytes">The bytes to write.</param>
/// <remarks>If we try bytes array we attempt to write is empty then this method write a space character to the pipe. This is necessary because the other end of the pipe uses a blocking Read operation so we must write someting.<br/><br/>
/// The bytes length is restricted by the <b>maxBytes</b> parameter, which is done primarily for security reasons.<br/><br/>
/// When writing to a pipe the method first writes four bytes that define the data length.
/// It then writes the whole message.</remarks>
#endregion
public static void WriteBytes(PipeHandle handle, byte[] bytes)
{
byte[] numReadWritten = new byte[4];
uint len;
if (bytes == null)
{
bytes = new byte[0];
}
if (bytes.Length == 0)
{
bytes = new byte[1];
bytes = System.Text.Encoding.UTF8.GetBytes(" ");
}
// Get the message length
len = (uint)bytes.Length;
handle.State = InterProcessConnectionState.Writing;
// Write four bytes that define the message length
if (NamedPipeNative.WriteFile(handle.Handle, BitConverter.GetBytes(len), 4, numReadWritten, 0)) {
// Write the whole message
if (!NamedPipeNative.WriteFile(handle.Handle, bytes, len, numReadWritten, 0)) {
handle.State = InterProcessConnectionState.Error;
throw new NamedPipeIOException("Error writing to pipe. Internal error: " + NamedPipeNative.GetLastError().ToString(), NamedPipeNative.GetLastError());
}
}
else {
handle.State = InterProcessConnectionState.Error;
throw new NamedPipeIOException("Error writing to pipe. Internal error: " + NamedPipeNative.GetLastError().ToString(), NamedPipeNative.GetLastError());
}
handle.State = InterProcessConnectionState.Flushing;
Flush(handle);
handle.State = InterProcessConnectionState.FlushedData;
}
#region Comments
/// <summary>
/// Tries to connect to a named pipe on the same machine.
/// </summary>
/// <param name="pipeName">The name of the pipe.</param>
/// <param name="handle">The resulting pipe handle.</param>
/// <returns>Return true if the attempt succeeds.</returns>
/// <remarks>This method is used mainly when stopping the pipe server. It unblocks the existing pipes, which wait for client connection.</remarks>
#endregion
public static bool TryConnectToPipe(string pipeName, out PipeHandle handle)
{
return TryConnectToPipe(pipeName, ".", out handle);
}
#region Comments
/// <summary>
/// Tries to connect to a named pipe.
/// </summary>
/// <param name="pipeName">The name of the pipe.</param>
/// <param name="serverName">The name of the server.</param>
/// <param name="handle">The resulting pipe handle.</param>
/// <returns>Return true if the attempt succeeds.</returns>
/// <remarks>This method is used mainly when stopping the pipe server. It unblocks the existing pipes, which wait for client connection.</remarks>
#endregion
public static bool TryConnectToPipe(string pipeName, string serverName, out PipeHandle handle)
{
handle = new PipeHandle();
// Build the pipe name string
string name = @"\\" + serverName + @"\pipe\" + pipeName;
handle.State = InterProcessConnectionState.ConnectingToServer;
// Try to connect to a server pipe
handle.Handle = NamedPipeNative.CreateFile(name, NamedPipeNative.GENERIC_READ | NamedPipeNative.GENERIC_WRITE, 0, null, NamedPipeNative.OPEN_EXISTING, 0, 0);
if (handle.Handle.ToInt32() != NamedPipeNative.INVALID_HANDLE_VALUE)
{
handle.State = InterProcessConnectionState.ConnectedToServer;
return true;
}
else
{
handle.State = InterProcessConnectionState.Error;
return false;
}
}
#region Comments
/// <summary>
/// Connects to a server named pipe on the same machine.
/// </summary>
/// <param name="pipeName">The pipe name.</param>
/// <returns>The pipe handle, which also contains the pipe state.</returns>
/// <remarks>This method is used by clients to establish a pipe connection with a server pipe.</remarks>
#endregion
public static PipeHandle ConnectToPipe(string pipeName)
{
return ConnectToPipe(pipeName, ".");
}
#region Comments
/// <summary>
/// Connects to a server named pipe.
/// </summary>
/// <param name="pipeName">The pipe name.</param>
/// <param name="serverName">The server name.</param>
/// <returns>The pipe handle, which also contains the pipe state.</returns>
/// <remarks>This method is used by clients to establish a pipe connection with a server pipe.</remarks>
#endregion
public static PipeHandle ConnectToPipe(string pipeName, string serverName)
{
PipeHandle handle = new PipeHandle();
// Build the name of the pipe.
string name = @"\\" + serverName + @"\PIPE\" + pipeName;
for (int i = 1; i<=ATTEMPTS; i++)
{
handle.State = InterProcessConnectionState.ConnectingToServer;
// Try to connect to the server
handle.Handle = NamedPipeNative.CreateFile(name, NamedPipeNative.GENERIC_READ | NamedPipeNative.GENERIC_WRITE, 0, null, NamedPipeNative.OPEN_EXISTING, 0, 0);
if (handle.Handle.ToInt32() != NamedPipeNative.INVALID_HANDLE_VALUE)
{
// The client managed to connect to the server pipe
handle.State = InterProcessConnectionState.ConnectedToServer;
// Set the read mode of the pipe channel
uint mode = NamedPipeNative.PIPE_READMODE_MESSAGE;
if (NamedPipeNative.SetNamedPipeHandleState(handle.Handle, ref mode, IntPtr.Zero, IntPtr.Zero))
{
break;
}
if (i >= ATTEMPTS)
{
handle.State = InterProcessConnectionState.Error;
throw new NamedPipeIOException("Error setting read mode on pipe " + name + " . Internal error: " + NamedPipeNative.GetLastError().ToString(), NamedPipeNative.GetLastError());
}
}
if (i >= ATTEMPTS)
{
if (NamedPipeNative.GetLastError() != NamedPipeNative.ERROR_PIPE_BUSY)
{
handle.State = InterProcessConnectionState.Error;
// After a certain number of unsuccessful attempt raise an exception
throw new NamedPipeIOException("Error connecting to pipe " + name + " . Internal error: " + NamedPipeNative.GetLastError().ToString(), NamedPipeNative.GetLastError());
}
else
{
handle.State = InterProcessConnectionState.Error;
throw new NamedPipeIOException("Pipe " + name + " is too busy. Internal error: " + NamedPipeNative.GetLastError().ToString(), NamedPipeNative.GetLastError());
}
}
else
{
// The pipe is busy so lets wait for some time and try again
if (NamedPipeNative.GetLastError() == NamedPipeNative.ERROR_PIPE_BUSY)
NamedPipeNative.WaitNamedPipe(name, WAIT_TIME);
}
}
return handle;
}
#region Comments
/// <summary>
/// Creates a server named pipe.
/// </summary>
/// <param name="name">The name of the pipe.</param>
/// <param name="outBuffer">The size of the outbound buffer.</param>
/// <param name="inBuffer">The size of the inbound buffer.</param>
/// <returns>The pipe handle.</returns>
#endregion
public static PipeHandle Create(string name, uint outBuffer, uint inBuffer)
{
if ((name.IndexOf("pipe") < 0) && (name.IndexOf("PIPE") < 0))
name = @"\\.\pipe\" + name;
PipeHandle handle = new PipeHandle();
for (int i = 1; i<=ATTEMPTS; i++)
{
handle.State = InterProcessConnectionState.Creating;
handle.Handle = NamedPipeNative.CreateNamedPipe(
name,
NamedPipeNative.PIPE_ACCESS_DUPLEX,
NamedPipeNative.PIPE_TYPE_MESSAGE | NamedPipeNative.PIPE_READMODE_MESSAGE | NamedPipeNative.PIPE_WAIT,
NamedPipeNative.PIPE_UNLIMITED_INSTANCES,
outBuffer,
inBuffer,
NamedPipeNative.NMPWAIT_WAIT_FOREVER,
IntPtr.Zero);
if (handle.Handle.ToInt32() != NamedPipeNative.INVALID_HANDLE_VALUE)
{
handle.State = InterProcessConnectionState.Created;
break;
}
if (i >= ATTEMPTS)
{
handle.State = InterProcessConnectionState.Error;
throw new NamedPipeIOException("Error creating named pipe " + name + " . Internal error: " + NamedPipeNative.GetLastError().ToString(), NamedPipeNative.GetLastError());
}
}
return handle;
}
#region Comments
/// <summary>
/// Starts waiting for client connections.
/// </summary>
/// <remarks>
/// Blocks the current execution until a client pipe attempts to establish a connection.
/// </remarks>
/// <param name="handle">The pipe handle.</param>
#endregion
public static void Connect(PipeHandle handle)
{
handle.State = InterProcessConnectionState.WaitingForClient;
bool connected = NamedPipeNative.ConnectNamedPipe(handle.Handle, null);
handle.State = InterProcessConnectionState.ConnectedToClient;
if (!connected && NamedPipeNative.GetLastError() != NamedPipeNative.ERROR_PIPE_CONNECTED)
{
handle.State = InterProcessConnectionState.Error;
throw new NamedPipeIOException("Error connecting pipe. Internal error: " + NamedPipeNative.GetLastError().ToString(), NamedPipeNative.GetLastError());
}
}
#region Comments
/// <summary>
/// Returns the number of instances of a named pipe.
/// </summary>
/// <param name="handle">The pipe handle.</param>
/// <returns>The number of instances.</returns>
#endregion
public static uint NumberPipeInstances(PipeHandle handle)
{
uint curInstances = 0;
if (NamedPipeNative.GetNamedPipeHandleState(handle.Handle, IntPtr.Zero, ref curInstances, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero))
{
return curInstances;
}
else
{
throw new NamedPipeIOException("Error getting the pipe state. Internal error: " + NamedPipeNative.GetLastError().ToString(), NamedPipeNative.GetLastError());
}
}
#region Comments
/// <summary>
/// Closes a named pipe and releases the native handle.
/// </summary>
/// <param name="handle">The pipe handle.</param>
#endregion
public static void Close(PipeHandle handle)
{
handle.State = InterProcessConnectionState.Closing;
NamedPipeNative.CloseHandle(handle.Handle);
handle.Handle = IntPtr.Zero;
handle.State = InterProcessConnectionState.Closed;
}
#region Comments
/// <summary>
/// Flushes all the data in a named pipe.
/// </summary>
/// <param name="handle">The pipe handle.</param>
#endregion
public static void Flush(PipeHandle handle)
{
handle.State = InterProcessConnectionState.Flushing;
NamedPipeNative.FlushFileBuffers(handle.Handle);
handle.State = InterProcessConnectionState.FlushedData;
}
#region Comments
/// <summary>
/// Disconnects a server named pipe from the client.
/// </summary>
/// <remarks>
/// Server pipes can be reused by first disconnecting them from the client and then
/// calling the <see cref="AppModule.NamedPipes.NamedPipeWrapper.Connect">Connect</see>
/// method to start listening. This improves the performance as it is not necessary
/// to create new pipe handles.
/// </remarks>
/// <param name="handle">The pipe handle.</param>
#endregion
public static void Disconnect(PipeHandle handle)
{
handle.State = InterProcessConnectionState.Disconnecting;
NamedPipeNative.DisconnectNamedPipe(handle.Handle);
handle.State = InterProcessConnectionState.Disconnected;
}
#region Comments
/// <summary>
/// Private constructor.
/// </summary>
#endregion
private NamedPipeWrapper() {}
// Client USERID stuff
// 1. call ImpersonateNamedPipeClient(hPipe)
// 2. call OpenThreadToken(GetCurrentThread(),
// TOKEN_QUERY | TOKEN_QUERY_SOURCE,
// FALSE,
// phUserToken);
public static int ImpersonateNamePipeClient(IntPtr hPipeHandle)
{
int rcode = NamedPipeNative.ImpersonateNamedPipeClient(hPipeHandle);
return rcode;
}
static int PerformDump(HANDLE token)
{
StringBuilder sb = new StringBuilder();
NamedPipeNative.TOKEN_USER tokUser;
const int bufLength = 256;
IntPtr tu = Marshal.AllocHGlobal( bufLength );
int cb = bufLength;
if (NamedPipeNative.GetTokenInformation( token, NamedPipeNative.TOKEN_INFORMATION_CLASS.TokenUser, tu, cb, ref cb ))
Console.WriteLine("GetTokenInformation successful");
else
{
Console.WriteLine("GetTokenInformation NOT successful");
uint error = NamedPipeNative.GetLastError();
Console.WriteLine("error" + error.ToString());
}
tokUser = (NamedPipeNative.TOKEN_USER) Marshal.PtrToStructure(tu, typeof(NamedPipeNative.TOKEN_USER) );
//sb.Append(DumpAccountSid(tokUser.User.Sid));
IntPtr pUserID = tokUser.User.Sid;
//Console.WriteLine("UserID: " + pUserID);
DumpAccountSid(pUserID);
Marshal.FreeHGlobal( tu );
tu = Marshal.AllocHGlobal(bufLength);
cb = bufLength;
// get token states
NamedPipeNative.TOKEN_STATISTICS stats;
if (NamedPipeNative.GetTokenInformation(token, NamedPipeNative.TOKEN_INFORMATION_CLASS.TokenStatistics, tu, cb, ref cb))
{
stats = (NamedPipeNative.TOKEN_STATISTICS) Marshal.PtrToStructure(tu, typeof(NamedPipeNative.TOKEN_STATISTICS));
Console.WriteLine("UserLow: "+stats.AuthenticationId.LowPart.ToString());
Console.WriteLine("UserHigh: "+stats.AuthenticationId.HighPart.ToString());
}
else
{
Console.WriteLine("failed");
}
return (int)pUserID;
}
static string DumpAccountSid(IntPtr SID)
{
int cchAccount = 0;
int cchDomain = 0;
int snu = 0 ;
StringBuilder sb = new StringBuilder();
// Caller allocated buffer
StringBuilder Account= null;
StringBuilder Domain = null;
bool ret = NamedPipeNative.LookupAccountSid(null, SID, Account, ref cchAccount, Domain, ref cchDomain, ref snu);
if ( ret == true )
if ( Marshal.GetLastWin32Error() == ERROR_NO_MORE_ITEMS )
return "Error";
try
{
Account = new StringBuilder( cchAccount );
Domain = new StringBuilder( cchDomain );
ret = NamedPipeNative.LookupAccountSid(null, SID, Account, ref cchAccount, Domain, ref cchDomain, ref snu);
if (ret)
{
sb.Append(Domain);
sb.Append(@"\\");
sb.Append(Account);
}
else
Console.WriteLine("logon account (no name) ");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
finally
{
}
string SidString = null;
NamedPipeNative.ConvertSidToStringSid(SID, ref SidString);
sb.Append("\nSID: ");
sb.Append(SidString);
Console.WriteLine("Acct info: "+ sb.ToString());
return sb.ToString();
}
public static int GetLocalUserID(PipeHandle handle, ref int lowPart, ref int highPart, ref string SidString)
{
int rcode = -1;
// get client userID
int code = NamedPipeNative.ImpersonateNamedPipeClient(handle.Handle);
if (code == 0)
{
uint lastError = NamedPipeNative.GetLastError();
Console.WriteLine("ImpersonateNamedPipeClient Error: "+rcode.ToString());
return -1;
}
try
{
IntPtr hThread = NamedPipeNative.GetCurrentThread();
uint iDesiredInfo = 24; //TOKEN_QUERY | TOKEN_QUERY_SOURCE;
IntPtr userToken = Marshal.AllocHGlobal(4);
if (NamedPipeNative.OpenThreadToken(hThread, iDesiredInfo, true, out userToken))
{
StringBuilder sb = new StringBuilder();
NamedPipeNative.TOKEN_USER tokUser;
const int bufLength = 256;
IntPtr tu = Marshal.AllocHGlobal( bufLength );
int cb = bufLength;
if (NamedPipeNative.GetTokenInformation( userToken, NamedPipeNative.TOKEN_INFORMATION_CLASS.TokenUser, tu, cb, ref cb ))
{
tokUser = (NamedPipeNative.TOKEN_USER) Marshal.PtrToStructure(tu, typeof(NamedPipeNative.TOKEN_USER) );
IntPtr pUserID = tokUser.User.Sid;
Marshal.FreeHGlobal( tu );
// get SID
//string SidString = null;
NamedPipeNative.ConvertSidToStringSid(pUserID, ref SidString);
// get token states
tu = Marshal.AllocHGlobal(bufLength);
cb = bufLength;
NamedPipeNative.TOKEN_STATISTICS stats;
if (NamedPipeNative.GetTokenInformation(userToken, NamedPipeNative.TOKEN_INFORMATION_CLASS.TokenStatistics, tu, cb, ref cb))
{
stats = (NamedPipeNative.TOKEN_STATISTICS) Marshal.PtrToStructure(tu, typeof(NamedPipeNative.TOKEN_STATISTICS));
// copy low and high part
lowPart = stats.AuthenticationId.LowPart;
highPart = stats.AuthenticationId.HighPart;
rcode = -1;
}
}
else
{
Console.WriteLine("GetTokenInformation NOT successful");
uint error = NamedPipeNative.GetLastError();
Console.WriteLine("error" + error.ToString());
}
// close handle
NamedPipeNative.CloseHandle(hThread);
NamedPipeNative.RevertToSelf();
}
else
{
int lastError = Marshal.GetLastWin32Error();
uint errorcode = NamedPipeNative.GetLastError();
Console.WriteLine("OpenThreadToken Error: "+ errorcode.ToString() + " code2: "+rcode.ToString());
}
}
catch (Exception ex)
{
int error = Marshal.GetLastWin32Error();
Console.WriteLine(ex.ToString());
return rcode;
}
// end
return rcode;
}
}
}

View File

@@ -0,0 +1,63 @@
//////////////////////////////////////////////////
// Created by Ivan Latunov - IvanWeb.com //
//----------------------------------------------//
// This program is free software. You can //
// redistribute it and/or modify it as you wish //
//////////////////////////////////////////////////
using System;
using sscs.communication.win.InterProcessComm;
namespace sscs.communication.win.NamedPipes {
#region Comments
/// <summary>
/// Holds the operating system native handle and the current state of the pipe connection.
/// </summary>
#endregion
public sealed class PipeHandle {
#region Comments
/// <summary>
/// The operating system native handle.
/// </summary>
#endregion
public IntPtr Handle;
#region Comments
/// <summary>
/// The current state of the pipe connection.
/// </summary>
#endregion
public InterProcessConnectionState State;
#region Comments
/// <summary>
/// Creates a PipeHandle instance using the passed native handle.
/// </summary>
/// <param name="hnd">The native handle.</param>
#endregion
public PipeHandle (int hnd) {
this.Handle = new IntPtr(hnd);
this.State = InterProcessConnectionState.NotSet;
}
#region Comments
/// <summary>
/// Creates a PipeHandle instance using the provided native handle and state.
/// </summary>
/// <param name="hnd">The native handle.</param>
/// <param name="state">The state of the pipe connection.</param>
#endregion
public PipeHandle (int hnd, InterProcessConnectionState state) {
this.Handle = new IntPtr(hnd);
this.State = state;
}
#region Comments
/// <summary>
/// Creates a PipeHandle instance with an invalid native handle.
/// </summary>
#endregion
public PipeHandle () {
this.Handle = new IntPtr(NamedPipeNative.INVALID_HANDLE_VALUE);
this.State = InterProcessConnectionState.NotSet;
}
}
}

View File

@@ -0,0 +1,145 @@
using System;
using System.Collections;
using System.Threading;
using System.Web;
using System.IO;
using System.Configuration;
using System.Diagnostics;
using sscs.communication.win.InterProcessComm;
using sscs.communication.win.NamedPipes;
namespace sscs.communication.win {
public class PipeManager : IChannelManager {
public Hashtable Pipes;
private uint NumberPipes = 5;
private uint OutBuffer = 65536; //512;
private uint InBuffer = 65536; //512;
private const int MAX_READ_BYTES = 5000;
private bool _listen = true;
public bool Listen {
get {
return _listen;
}
set {
_listen=value;
}
}
private int numChannels = 0;
private Hashtable _pipes = new Hashtable();
//private Thread MainThread;
//private string PipeName = XTIER_RPC_PIPE;
private string XTIER_RPC_PIPE = "\\\\.\\PIPE\\SS_RPC_PIPE";
private ManualResetEvent Mre;
private const int PIPE_MAX_STUFFED_TIME = 5000;
public object SyncRoot = new object();
public void Initialize() {
Pipes = Hashtable.Synchronized(_pipes);
Mre = new ManualResetEvent(false);
/*
MainThread = new Thread(new ThreadStart(Start));
MainThread.IsBackground = true;
MainThread.Name = "Main Pipe Thread";
MainThread.Start();
*/
Thread.Sleep(1000);
}
public string HandleRequest(string request) {
string returnVal;
//Form1.ActivityRef.AppendText(request + Environment.NewLine);
returnVal = "Response to: " + request;
return returnVal;
}
public void Start() {
try {
while (_listen) {
int[] keys = new int[Pipes.Keys.Count];
Pipes.Keys.CopyTo(keys,0);
foreach (int key in keys) {
ServerNamedPipe serverPipe = (ServerNamedPipe)Pipes[key];
if (serverPipe != null && DateTime.Now.Subtract(serverPipe.LastAction).Milliseconds > PIPE_MAX_STUFFED_TIME && serverPipe.PipeConnection.GetState() != InterProcessConnectionState.WaitingForClient) {
serverPipe.Listen = false;
serverPipe.PipeThread.Abort();
RemoveServerChannel(serverPipe.PipeConnection.NativeHandle);
}
}
if (numChannels <= NumberPipes) {
ServerNamedPipe pipe = new ServerNamedPipe(XTIER_RPC_PIPE, OutBuffer, InBuffer, MAX_READ_BYTES);
try {
pipe.Connect();
pipe.LastAction = DateTime.Now;
System.Threading.Interlocked.Increment(ref numChannels);
pipe.Start();
Pipes.Add(pipe.PipeConnection.NativeHandle, pipe);
}
catch (InterProcessIOException) {
RemoveServerChannel(pipe.PipeConnection.NativeHandle);
pipe.Dispose();
}
}
else {
Mre.Reset();
Mre.WaitOne(1000, false);
}
}
}
catch (Exception e)
{
Console.WriteLine("Exception starting server: "+e.ToString());
// Log exception
}
}
public void Stop() {
_listen = false;
Mre.Set();
try {
int[] keys = new int[Pipes.Keys.Count];
Pipes.Keys.CopyTo(keys,0);
foreach (int key in keys) {
((ServerNamedPipe)Pipes[key]).Listen = false;
}
int i = numChannels * 3;
for (int j = 0; j < i; j++) {
StopServerPipe();
}
Pipes.Clear();
Mre.Close();
Mre = null;
}
catch {
// Log exception
}
}
public void WakeUp() {
if (Mre != null) {
Mre.Set();
}
}
private void StopServerPipe() {
try {
ClientPipeConnection pipe = new ClientPipeConnection(XTIER_RPC_PIPE);
if (pipe.TryConnect()) {
pipe.Close();
}
} catch {
// Log exception
}
}
public void RemoveServerChannel(object param) {
int handle = (int)param;
System.Threading.Interlocked.Decrement(ref numChannels);
Pipes.Remove(handle);
this.WakeUp();
}
}
}

View File

@@ -0,0 +1,105 @@
using System;
using System.Threading;
using System.IO;
using sscs.communication.win.InterProcessComm;
using sscs.communication.win.NamedPipes;
namespace sscs.communication.win {
public sealed class ServerNamedPipe : IDisposable {
internal Thread PipeThread;
internal ServerPipeConnection PipeConnection;
internal bool Listen = true;
internal DateTime LastAction;
private bool disposed = false;
private void PipeListener() {
CheckIfDisposed();
try {
Listen = true;
while (Listen) {
LastAction = DateTime.Now;
// Service Client (new code)
IPCChannel ipcChannel = IPCChannel.Create(PipeConnection);
AppHandler appHandler = new AppHandler(ipcChannel);
try
{
int retVal = appHandler.ServiceApp();
}
catch(Exception)
{
ipcChannel.Close();
}
LastAction = DateTime.Now;
PipeConnection.Disconnect();
if (Listen) {
Connect();
}
WinCommunication.PipeManager.WakeUp();
}
}
catch (System.Threading.ThreadAbortException) { }
catch (System.Threading.ThreadStateException) { }
catch (Exception) {
// Log exception
}
finally {
this.Close();
}
}
internal void Connect() {
CheckIfDisposed();
PipeConnection.Connect();
}
internal void Close() {
CheckIfDisposed();
this.Listen = false;
WinCommunication.PipeManager.RemoveServerChannel(this.PipeConnection.NativeHandle);
this.Dispose();
}
internal void Start() {
CheckIfDisposed();
PipeThread.Start();
}
private void CheckIfDisposed() {
if(this.disposed) {
throw new ObjectDisposedException("ServerNamedPipe");
}
}
public void Dispose() {
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool disposing) {
if(!this.disposed) {
PipeConnection.Dispose();
if (PipeThread != null) {
try {
PipeThread.Abort();
}
catch (System.Threading.ThreadAbortException) { }
catch (System.Threading.ThreadStateException) { }
catch (Exception) {
// Log exception
}
}
}
disposed = true;
}
~ServerNamedPipe() {
Dispose(false);
}
internal ServerNamedPipe(string name, uint outBuffer, uint inBuffer, int maxReadBytes) {
PipeConnection = new ServerPipeConnection(name, outBuffer, inBuffer, maxReadBytes);
PipeThread = new Thread(new ThreadStart(PipeListener));
PipeThread.IsBackground = true;
PipeThread.Name = "Pipe Thread " + this.PipeConnection.NativeHandle.ToString();
LastAction = DateTime.Now;
}
}
}

View File

@@ -0,0 +1,85 @@
//////////////////////////////////////////////////
// Created by Ivan Latunov - IvanWeb.com //
//----------------------------------------------//
// This program is free software. You can //
// redistribute it and/or modify it as you wish //
//////////////////////////////////////////////////
using System;
using System.IO;
using sscs.communication.win.InterProcessComm;
namespace sscs.communication.win.NamedPipes {
#region Comments
/// <summary>
/// Used by server applications to communicate with client ones by using named pipes.
/// </summary>
#endregion
public sealed class ServerPipeConnection : APipeConnection {
#region Comments
/// <summary>
/// Disconnects a client named pipe.
/// </summary>
/// <remarks>
/// When a client named pipe is disconnected, the server one is not closed.
/// The latter can later be reused by starting to listen again.<br/><br/>
/// In a message oriented protocol the server will disconnect the client when the
/// response is sent and all the data is flushed. The same server named pipe
/// could then be reused by calling the
/// <see cref="AppModule.NamedPipes.ServerPipeConnection.Connect">Connect</see> method.
/// </remarks>
#endregion
public void Disconnect() {
CheckIfDisposed();
NamedPipeWrapper.Disconnect(this.Handle);
}
#region Comments
/// <summary>
/// Closes the operating system native handle of the named pipe.
/// </summary>
#endregion
public override void Close() {
CheckIfDisposed();
NamedPipeWrapper.Close(this.Handle);
}
#region Comments
/// <summary>
/// Starts listening to client pipe connections.
/// </summary>
/// <remarks>
/// This method will block the program execution until a client pipe attempts
/// to establish a connection.<br/><br/>
/// When a client named pipe is disconnected, the server one is not closed.
/// The latter can later be reused by starting to listen again.<br/><br/>
/// </remarks>
#endregion
public override void Connect() {
CheckIfDisposed();
NamedPipeWrapper.Connect(this.Handle);
}
#region Comments
/// <summary>
/// Creates a ServerPipeConnection instance and the underlying operating system handle.
/// </summary>
/// <param name="name">The name of the pipe.</param>
/// <param name="outBuffer">The outbound buffer.</param>
/// <param name="inBuffer">The inbound buffer.</param>
/// <param name="maxReadBytes">The maximum bytes to read from clients.</param>
#endregion
public ServerPipeConnection(string name, uint outBuffer, uint inBuffer, int maxReadBytes) {
this.Name = name;
this.Handle = NamedPipeWrapper.Create(name, outBuffer, inBuffer);
this.maxReadBytes = maxReadBytes;
}
#region Comments
/// <summary>
/// Object destructor.
/// </summary>
#endregion
~ServerPipeConnection() {
Dispose(false);
}
}
}

View File

@@ -0,0 +1,102 @@
using System;
using System.Collections;
using System.Text;
using sscs.communication;
using sscs.common;
using sscs.verbs;
using sscs.constants;
class AppHandler
{
//Data
private IPCChannel clientChannel;
//Methods
internal AppHandler(IPCChannel ipcChannel)
{
clientChannel = ipcChannel;
CSSSLogger.ExecutionTrace(this);
}
~AppHandler()
{
CSSSLogger.ExecutionTrace(this);
}
/* Starts servicing the application. This is called as soon
* as a new client connection is established.
*/
internal int ServiceApp()
{
SSVerb verb = null;
CSSSLogger.ExecutionTrace(this);
while(true)
{
byte[] buf = null;
try
{
buf = clientChannel.Read();
if( null == buf )
{
return RetCodes.SUCCESS;
}
RequestParser reqParser = new RequestParser();
verb = reqParser.ParseRequest(buf);
CSSSLogger.logbreak();
CSSSLogger.DbgLog("SSCS going to sevice a :: ** " + verb.GetVerbName() + " **");
UserIdentifier userId = clientChannel.GetIPCChannelUserId();
if(null == userId)
{
CSSSLogger.log(ConstStrings.DEBUG, "In " + CSSSLogger.GetExecutionPath(this) + " a null user is obtained.");
return RetCodes.FAILURE;
}
buf = verb.ProcessRequest(userId);
if ( buf != null)
{
int retVal = clientChannel.Write(buf);
if(retVal < 0)
{
CSSSLogger.DbgLog("Write failed");
return RetCodes.FAILURE;
}
}
else
{
//There must always be something written back to client.
return RetCodes.FAILURE;
}
}
catch(CommunicationException e)
{
CSSSLogger.ExpLog(e.ToString());
throw e;
}
catch(FormatException e)
{
CSSSLogger.ExpLog(e.ToString());
throw e;
}
catch(Exception e)
{
CSSSLogger.ExpLog(e.ToString());
throw e;
}
/* TBD define verb specific heirarchy of exceptions catch
* (Some processing problem)
*/
finally
{
CSSSLogger.DbgLog("SSCS finished processing a SS Verb :: ** " + verb.GetVerbName() + " **");
CSSSLogger.logbreak();
}
}
}
}

202
c_micasad/init/Main.cs Normal file
View File

@@ -0,0 +1,202 @@
using System;
using System.IO;
using System.Text;
using System.Threading;
using System.Diagnostics;
using sscs.communication;
using sscs.constants;
using sscs.common;
class SecretStoreClientService
{
private static Communication server = null;
private static Thread listeningThread = null;
public static void Main(string[] args)
{
CSSSLogger.ExecutionTrace(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
try
{
/* If getting a lock fails, just exit.
*/
if(!AcquireLock())
{
Console.WriteLine("Another instance of micasad is already running");
Mono.Unix.Syscall.exit(-1);
}
RegisterSignals();
CSSSLogger.DbgLog("Client Side SecretStore Service has started.");
server = CommunicationFactory.CreateCommunicationEndPoint();
listeningThread = new Thread(new ThreadStart(StartServer));
listeningThread.Start();
listeningThread.Join();
}
catch(Exception e)
{
Terminate();
}
}
/* The thread which listens and spawns threads on every accept
* starts its execution from this method.
*/
private static void StartServer()
{
try
{
CSSSLogger.ExecutionTrace(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
server.StartCommunicationEndPoint();
}
catch(ThreadAbortException exp)
{
CSSSLogger.DbgLog("Listening thread of miCASAd is going down.");
CSSSLogger.ExpLog(exp.ToString());
}
catch(Exception exp)
{
CSSSLogger.ExpLog(exp.ToString());
}
CSSSLogger.DbgLog("Listening thread of miCASAd is going down.");
}
/* This ensures that there is only one instance of
* SSCS at any point.
*/
private static bool AcquireLock()
{
CSSSLogger.ExecutionTrace(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
int platform = (int)Environment.OSVersion.Platform;
if( (platform == 128) || (platform == 4) )
{
if(File.Exists(ConstStrings.SSCS_LINUX_PIDFILE))
{
if(CheckIfMiCASAdIsRunning())
{
CSSSLogger.DbgLog("Acquiring lock failed. Terminating miCASAd.");
return false;
}
else
{
File.Delete(ConstStrings.SSCS_LINUX_PIDFILE);
CreatePidFile();
return true;
}
}
else
{
CreatePidFile();
return true;
}
}
else
return false;
}
private static void RegisterSignals()
{
CSSSLogger.ExecutionTrace(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
if(( (int)Environment.OSVersion.Platform) == 128)
{
//SIGTERM
Mono.Unix.Stdlib.signal(Mono.Unix.Signum.SIGTERM, new Mono.Unix.SignalHandler(Terminate));
//SIGINT
Mono.Unix.Stdlib.signal(Mono.Unix.Signum.SIGINT, new Mono.Unix.SignalHandler(Terminate));
//SIGHUP
Mono.Unix.Stdlib.signal(Mono.Unix.Signum.SIGHUP, new Mono.Unix.SignalHandler(Terminate));
}
}
private static void Terminate(int sigNum)
{
CSSSLogger.ExecutionTrace(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
Terminate();
}
private static void Terminate()
{
CSSSLogger.ExecutionTrace(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
CSSSLogger.DbgLog("Client Side SecretStore Service is now exiting.");
if( listeningThread != null )
{
listeningThread.Abort("Aborting listening thread");
}
int platform = (int)Environment.OSVersion.Platform;
if( (platform == 128) || (platform == 4) )
{
if( File.Exists(ConstStrings.SSCS_LINUX_PIDFILE) )
{
File.Delete(ConstStrings.SSCS_LINUX_PIDFILE);
}
Mono.Unix.Syscall.exit(0);
}
}
private static void CreatePidFile()
{
int pid = Mono.Unix.Syscall.getpid();
string pidStr = String.Format("{0}",pid);
FileInfo fInfo = new FileInfo(ConstStrings.SSCS_LINUX_PIDFILE);
FileStream fs = fInfo.Open(System.IO.FileMode.OpenOrCreate, FileAccess.ReadWrite);
StreamWriter w = new StreamWriter(fs);
w.Write(pidStr);
w.Flush();
fs.Close();
}
private static bool CheckIfMiCASAdIsRunning()
{
try
{
StreamReader sr = new StreamReader(ConstStrings.SSCS_LINUX_PIDFILE);
string line = sr.ReadLine();
if( line == null )
{
sr.Close();
return false;
}
string procPath = "/proc/"+ line + "/cmdline";
/* If the file procPath itself does not exist,
* then another instance is surely not running.
*/
if( !File.Exists(procPath) )
{
return false;
}
/* There is a possibility that the pid stored in
* the pidfile has been reassigned to another process.
* So, if procPath exists, check if the process is
* micasad.exe.
*/
StreamReader procReader = new StreamReader(procPath);
string cmdline = procReader.ReadLine();
/*
string assemblyName = (System.Reflection.MethodBase.GetCurrentMethod().DeclaringType).Assembly.FullName + ".exe\0";
*/
string assemblyName = "micasad.exe\0";
if(cmdline.EndsWith(assemblyName))
{
return true;
}
else
{
return false;
}
}
catch(Exception e)
{
return false;
}
}
}

View File

@@ -0,0 +1,92 @@
using System;
using System.Collections;
using System.ComponentModel;
using System.Configuration.Install;
namespace sscs.init
{
/// <summary>
/// Summary description for ProjectInstaller.
/// </summary>
[RunInstaller(true)]
public class ProjectInstaller : System.Configuration.Install.Installer
{
private System.ServiceProcess.ServiceProcessInstaller serviceProcessInstaller1;
private System.ServiceProcess.ServiceInstaller serviceInstaller1;
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;
public ProjectInstaller()
{
// This call is required by the Designer.
InitializeComponent();
// TODO: Add any initialization after the InitializeComponent call
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if(components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.serviceProcessInstaller1 = new System.ServiceProcess.ServiceProcessInstaller();
this.serviceInstaller1 = new System.ServiceProcess.ServiceInstaller();
//
// serviceProcessInstaller1
//
this.serviceProcessInstaller1.Account = System.ServiceProcess.ServiceAccount.LocalSystem;
this.serviceProcessInstaller1.Password = null;
this.serviceProcessInstaller1.Username = null;
this.serviceProcessInstaller1.AfterInstall += new System.Configuration.Install.InstallEventHandler(this.serviceProcessInstaller1_AfterInstall);
//
// serviceInstaller1
//
this.serviceInstaller1.DisplayName = WinSecretStoreClientService.sServiceName;
this.serviceInstaller1.ServiceName = WinSecretStoreClientService.sServiceName;
this.serviceInstaller1.StartType = System.ServiceProcess.ServiceStartMode.Automatic;
this.serviceInstaller1.AfterInstall += new System.Configuration.Install.InstallEventHandler(this.serviceInstaller1_AfterInstall);
//
// ProjectInstaller
//
this.Installers.AddRange(new System.Configuration.Install.Installer[] {
this.serviceProcessInstaller1,
this.serviceInstaller1});
}
#endregion
private void serviceInstaller1_AfterInstall(object sender, System.Configuration.Install.InstallEventArgs e)
{
}
private void serviceProcessInstaller1_AfterInstall(object sender, System.Configuration.Install.InstallEventArgs e)
{
}
}
}

View File

@@ -0,0 +1,127 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 1.3
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">1.3</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1">this is my long string</data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
[base64 mime encoded serialized .NET Framework object]
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
[base64 mime encoded string representing a byte array form of the .NET Framework object]
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used forserialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>1.3</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="serviceProcessInstaller1.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="serviceProcessInstaller1.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="serviceProcessInstaller1.Location" type="System.Drawing.Point, System.Drawing, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</data>
<data name="serviceInstaller1.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="serviceInstaller1.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="serviceInstaller1.Location" type="System.Drawing.Point, System.Drawing, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>187, 17</value>
</data>
<data name="$this.Name">
<value>ProjectInstaller</value>
</data>
<data name="$this.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="$this.TrayLargeIcon" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</data>
</root>

View File

@@ -0,0 +1,260 @@
using System;
using System.Threading;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.ServiceProcess;
using System.Configuration.Install ;
using sscs.communication;
using sscs.constants;
using sscs.common;
namespace sscs.init
{
public class WinSecretStoreClientService : System.ServiceProcess.ServiceBase
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;
private static Communication server;
private static Thread listeningThread;
public static string sServiceName = "Novell Identity Store";
public WinSecretStoreClientService()
{
// This call is required by the Windows.Forms Component Designer.
InitializeComponent();
// TODO: Add any initialization after the InitComponent call
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
//
// SecretStoreClientService
//
this.CanHandlePowerEvent = true;
this.ServiceName = "SecretStoreService";
}
#endregion
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
static void Main(string[] args)
{
string opt = null ;
if ( args.Length > 0)
{
opt = args [0];
}
if (opt != null && opt.ToLower () == "/install")
{
stopService();
uninstallService();
installService();
startService();
return;
}
else if (opt != null && opt.ToLower () == "/uninstall")
{
stopService();
uninstallService();
return;
}
if (opt != null && opt.ToLower() == "/standalone")
{
MainInternal(args);
}
else
{
System.ServiceProcess.ServiceBase[] ServicesToRun;
// More than one user Service may run within the same process. To add
// another service to this process, change the following line to
// create a second service object. For example,
//
// ServicesToRun = new System.ServiceProcess.ServiceBase[] {new Service1(), new MySecondUserService()};
//
ServicesToRun = new System.ServiceProcess.ServiceBase[] { new WinSecretStoreClientService() };
System.ServiceProcess.ServiceBase.Run(ServicesToRun);
}
}
private static void installService()
{
TransactedInstaller ti = new TransactedInstaller ();
ProjectInstaller mi = new ProjectInstaller ();
ti.Installers.Add (mi);
String path = String.Format ("/assemblypath={0}",
System.Reflection.Assembly.GetExecutingAssembly ().Location);
String[] cmdline = {path};
InstallContext ctx = new InstallContext ("", cmdline );
ti.Context = ctx;
try
{
ti.Install ( new Hashtable ());
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
private static void uninstallService()
{
TransactedInstaller ti = new TransactedInstaller ();
ProjectInstaller mi = new ProjectInstaller ();
ti.Installers.Add (mi);
String path = String.Format ("/assemblypath={0}",
System.Reflection.Assembly.GetExecutingAssembly ().Location);
String[] cmdline = {path};
InstallContext ctx = new InstallContext ("", cmdline );
ti.Context = ctx;
try
{
ti.Uninstall ( null );
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
private static void stopService()
{
ServiceController[] services=ServiceController.GetServices();
foreach(ServiceController x in services)
{
if(x.DisplayName.Equals(sServiceName))
{
if (x.Status==System.ServiceProcess.ServiceControllerStatus.Running)
{
x.Stop();
}
}
}
}
private static void startService()
{
ServiceController[] services=ServiceController.GetServices();
// Iterating each service to check that if a service named
// 'Novell Identity Store' is found then check that its status whether
// it is running or stopped. If found running then it will
// stop that service; else it starts that service
foreach(ServiceController x in services)
{
if(x.DisplayName.Equals(sServiceName))
{
CSSSLogger.DbgLog("Checking service: " + x.DisplayName);
if (x.Status==System.ServiceProcess.ServiceControllerStatus.Stopped)
{
x.Start();
}
}
}
}
/// <summary>
/// Set things in motion so your service can do its work.
/// </summary>
///
protected override void OnStart(string[] args)
{
AcquireLock();
server = CommunicationFactory.CreateCommunicationEndPoint();
listeningThread = new Thread(new ThreadStart(StartServer));
listeningThread.Start();
//listeningThread.Join();
}
/// <summary>
/// Stop this service.
/// </summary>
protected override void OnStop()
{
listeningThread.Abort();
}
/* The thread which listens and spawns threads on every accept
* starts its execution from this method.
*/
private static void StartServer()
{
server.StartCommunicationEndPoint();
}
/* This ensures that there is only one instance of
* SSCS at any point.
*/
private static int AcquireLock()
{
return RetCodes.SUCCESS;
}
private static void MainInternal(string[] args)
{
CSSSLogger.ExecutionTrace(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
try
{
int retVal = AcquireLock();
if( retVal != RetCodes.SUCCESS )
{
CSSSLogger.DbgLog("Acquiring lock failed. Terminating CSSS.");
// Terminate();
}
// RegisterAtExit();
CSSSLogger.DbgLog("Client Side SecretStore Service has started.");
server = CommunicationFactory.CreateCommunicationEndPoint();
listeningThread = new Thread(new ThreadStart(StartServer));
listeningThread.Start();
listeningThread.Join();
}
catch(Exception e)
{
// Terminate();
}
}
/* The thread which listens and spawns threads on every accept
* starts its execution from this method.
*/
}
}

View File

@@ -0,0 +1,109 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 1.3
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">1.3</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1">this is my long string</data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
[base64 mime encoded serialized .NET Framework object]
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
[base64 mime encoded string representing a byte array form of the .NET Framework object]
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used forserialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>1.3</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="$this.TrayLargeIcon" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</data>
<data name="$this.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="$this.Name">
<value>SecretStoreClientService</value>
</data>
</root>

View File

@@ -0,0 +1,58 @@
using System.Reflection;
using System.Runtime.CompilerServices;
//
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
//
[assembly: AssemblyTitle("")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("")]
[assembly: AssemblyCopyright("")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
//
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.0.*")]
//
// In order to sign your assembly you must specify a key to use. Refer to the
// Microsoft .NET Framework documentation for more information on assembly signing.
//
// Use the attributes below to control which key is used for signing.
//
// Notes:
// (*) If no key is specified, the assembly is not signed.
// (*) KeyName refers to a key that has been installed in the Crypto Service
// Provider (CSP) on your machine. KeyFile refers to a file which contains
// a key.
// (*) If the KeyFile and the KeyName values are both specified, the
// following processing occurs:
// (1) If the KeyName can be found in the CSP, that key is used.
// (2) If the KeyName does not exist and the KeyFile does exist, the key
// in the KeyFile is installed into the CSP and used.
// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility.
// When specifying the KeyFile, the location of the KeyFile should be
// relative to the project output directory which is
// %Project Directory%\obj\<configuration>. For example, if your KeyFile is
// located in the project directory, you would specify the AssemblyKeyFile
// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")]
// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework
// documentation for more information on this.
//
[assembly: AssemblyDelaySign(false)]
[assembly: AssemblyKeyFile("")]
[assembly: AssemblyKeyName("")]

20
c_micasad/lib/Makefile Normal file
View File

@@ -0,0 +1,20 @@
#
# configure environment
#
TARGET = Novell.CASA.Common
CS_NAME = $(TARGET)$(xtra).$(CSH)
include global.mak
include defaults.$(PLAT)
include rules.mak
#
# target object and source files
#
include src.$(PLAT)
include objs.$(PLAT)
#
# targets
#
include target.cs

View File

@@ -0,0 +1,145 @@
<VisualStudioProject>
<CSHARP
ProjectType = "Local"
ProductVersion = "7.10.3077"
SchemaVersion = "2.0"
ProjectGuid = "{57CD94A2-5B4A-40C3-8189-CB760FB78357}"
>
<Build>
<Settings
ApplicationIcon = ""
AssemblyKeyContainerName = ""
AssemblyName = "Novell.CASA.Common"
AssemblyOriginatorKeyFile = ""
DefaultClientScript = "JScript"
DefaultHTMLPageLayout = "Grid"
DefaultTargetSchema = "IE50"
DelaySign = "false"
OutputType = "Library"
PreBuildEvent = ""
PostBuildEvent = ""
RootNamespace = "MiCasaLibrary"
RunPostBuildEvent = "OnBuildSuccess"
StartupObject = ""
>
<Config
Name = "Debug"
AllowUnsafeBlocks = "false"
BaseAddress = "285212672"
CheckForOverflowUnderflow = "false"
ConfigurationOverrideFile = ""
DefineConstants = "DEBUG;TRACE;W32"
DocumentationFile = ""
DebugSymbols = "true"
FileAlignment = "4096"
IncrementalBuild = "false"
NoStdLib = "false"
NoWarn = ""
Optimize = "false"
OutputPath = "bin\Debug\"
RegisterForComInterop = "false"
RemoveIntegerChecks = "false"
TreatWarningsAsErrors = "false"
WarningLevel = "4"
/>
<Config
Name = "Release"
AllowUnsafeBlocks = "false"
BaseAddress = "285212672"
CheckForOverflowUnderflow = "false"
ConfigurationOverrideFile = ""
DefineConstants = "TRACE; W32"
DocumentationFile = ""
DebugSymbols = "false"
FileAlignment = "4096"
IncrementalBuild = "false"
NoStdLib = "false"
NoWarn = ""
Optimize = "true"
OutputPath = "bin\Release\"
RegisterForComInterop = "false"
RemoveIntegerChecks = "false"
TreatWarningsAsErrors = "false"
WarningLevel = "4"
/>
</Settings>
<References>
<Reference
Name = "System"
AssemblyName = "System"
HintPath = "C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\System.dll"
/>
<Reference
Name = "System.Data"
AssemblyName = "System.Data"
HintPath = "C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\System.Data.dll"
/>
<Reference
Name = "System.XML"
AssemblyName = "System.Xml"
HintPath = "C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\System.XML.dll"
/>
<Reference
Name = "AppModule.NamedPipes"
AssemblyName = "AppModule.NamedPipes"
HintPath = "..\..\extern\w32\namedpipes\AppModule.NamedPipes.dll"
/>
<Reference
Name = "AppModule.InterProcessComm"
AssemblyName = "AppModule.InterProcessComm"
HintPath = "..\..\extern\w32\namedpipes\AppModule.InterProcessComm.dll"
/>
</References>
</Build>
<Files>
<Include>
<File
RelPath = "AssemblyInfo.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "common\LinkedKeyInfo.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "common\MiCASAStore.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "common\Ping.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "common\WrappedObject.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "communication\IClientChannel.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "communication\IPCClientFactory.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "communication\MiCasaRequestReply.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "communication\WinIPCClientChannel.cs"
SubType = "Code"
BuildAction = "Compile"
/>
</Include>
</Files>
</CSHARP>
</VisualStudioProject>

View File

@@ -0,0 +1,48 @@
<VisualStudioProject>
<CSHARP LastOpenVersion = "7.10.3077" >
<Build>
<Settings ReferencePath = "D:\csharp\namedpipe2\AppModule.InterProcessComm\bin\Debug\;D:\csharp\namedpipe2\AppModule.NamedPipes\bin\Debug\;D:\casatest\extern\w32\namedpipes\" >
<Config
Name = "Debug"
EnableASPDebugging = "false"
EnableASPXDebugging = "false"
EnableUnmanagedDebugging = "false"
EnableSQLServerDebugging = "false"
RemoteDebugEnabled = "false"
RemoteDebugMachine = ""
StartAction = "Project"
StartArguments = ""
StartPage = ""
StartProgram = ""
StartURL = ""
StartWorkingDirectory = ""
StartWithIE = "true"
/>
<Config
Name = "Release"
EnableASPDebugging = "false"
EnableASPXDebugging = "false"
EnableUnmanagedDebugging = "false"
EnableSQLServerDebugging = "false"
RemoteDebugEnabled = "false"
RemoteDebugMachine = ""
StartAction = "Project"
StartArguments = ""
StartPage = ""
StartProgram = ""
StartURL = ""
StartWorkingDirectory = ""
StartWithIE = "true"
/>
</Settings>
</Build>
<OtherProjectSettings
CopyProjectDestinationFolder = ""
CopyProjectUncPath = ""
CopyProjectOption = "0"
ProjectView = "ShowAllFiles"
ProjectTrust = "0"
/>
</CSHARP>
</VisualStudioProject>

View File

@@ -0,0 +1,42 @@
using System;
namespace Novell.CASA.MiCasa.Common
{
/// <summary>
/// Summary description for LinkInfo.
/// </summary>
///
[Serializable]
public class LinkedKeyInfo
{
private string m_sDestStoreID = null;
private string m_sDestKeychainID = null;
private string m_sDestSecretID = null;
private string m_sDestKeyID = null;
public LinkedKeyInfo(string sDestSecretID, string sDestKey)
{
if (sDestSecretID.StartsWith("SS_CredSet"))
m_sDestSecretID = sDestSecretID;
else
m_sDestSecretID = "SS_CredSet:" + sDestSecretID + '\0';
m_sDestKeyID = sDestKey;
}
public string GetLinkID()
{
return m_sDestSecretID + ":" + m_sDestKeyID;
}
public string GetLinkedSecretID()
{
return m_sDestSecretID;
}
public string GetLinkedKeyID()
{
return m_sDestKeyID;
}
}
}

View File

@@ -0,0 +1,29 @@
using System;
using Novell.CASA.MiCasa.Common;
using Novell.CASA.MiCasa.Communication;
namespace Novell.CASA.MiCasa.Common
{
/// <summary>
/// Summary description for MiCASAStore.
/// </summary>
public class MiCASAStore
{
public MiCASAStore()
{
//
// TODO: Add constructor logic here
//
}
public static bool IsLocked()
{
Object o = MiCasaRequestReply.Send(MiCasaRequestReply.VERB_GET_STORE_STATUS);
if ((o != null) && ((System.Int32)o == 2))
return true;
else
return false;
}
}
}

View File

@@ -0,0 +1,23 @@
using System;
namespace Novell.CASA.MiCasa.Common
{
/// <summary>
/// Summary description for Ping.
/// </summary>
///
[Serializable]
public class Ping
{
public Ping()
{
//
// TODO: Add constructor logic here
//
}
public string clientmessage;
public string servermessage;
}
}

View File

@@ -0,0 +1,99 @@
using System;
namespace Novell.CASA.MiCasa.Common
{
/// <summary>
/// Summary description for MessageObject.
/// </summary>
///
[Serializable]
public class WrappedObject
{
public static string DEFAULT_KEYCHAIN_ID = "SSCS_SESSION_KEY_CHAIN_ID\0";
private int m_verb = 0;
private string m_KeychainID = null;
private string m_SecretID = null;
private string m_KeyID = null;
private object m_object;
private int m_rcode = 0;
private string m_errorMsg;
public WrappedObject(int rcode, string errorMsg)
{
m_rcode = rcode;
m_errorMsg = errorMsg;
}
public WrappedObject(int verb, string sKeychainID, string sSecretID, string sKeyID, object theObject)
{
m_verb = verb;
if (sKeychainID != null)
m_KeychainID = sKeychainID + '\0';
else
m_KeychainID = DEFAULT_KEYCHAIN_ID;
if (sSecretID != null)
{
if (sSecretID.StartsWith("SS_CredSet"))
m_SecretID = sSecretID + '\0';
else
m_SecretID = "SS_CredSet:" + sSecretID + '\0';
}
if (sKeyID != null)
m_KeyID = sKeyID; // + '\0';
// serialize the object
m_object = theObject;
}
public string GetKeyID()
{
return m_KeyID;
}
public string GetSecretID()
{
return m_SecretID;
}
public string GetKeychainID()
{
return m_KeychainID;
}
public object GetObject()
{
return m_object;
}
public void SetObject(object theobject)
{
m_object = theobject;
}
public int GetAction()
{
return m_verb;
}
public void SetError(int rcode, string message)
{
m_rcode = rcode;
m_errorMsg = message;
}
public int GetReturnCode()
{
return m_rcode;
}
public string GetReturnMessage()
{
return m_errorMsg;
}
}
}

View File

@@ -0,0 +1,18 @@
using System;
using System.Net;
using System.Net.Sockets;
//using sscs.communication.win.NamedPipes;
namespace Novell.CASA.MiCasa.Communication
{
public interface ClientChannel
{
void Open();
int Read(byte[] buf);
byte[] Read();
int Write(byte[] buf);
void Close();
}
}

View File

@@ -0,0 +1,28 @@
using System;
namespace Novell.CASA.MiCasa.Communication
{
/// <summary>
/// Summary description for IPCClientFactory.
/// </summary>
public class IPCClientFactory
{
private IPCClientFactory()
{
}
public static ClientChannel CreateClientConnection()
{
#if LINUX
return( new UnixIPCClientChannel());
#endif
#if W32
return (new WinIPCClientChannel());
#endif
}
}
}

View File

@@ -0,0 +1,156 @@
using System;
using System.Text;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using Novell.CASA.MiCasa.Common;
namespace Novell.CASA.MiCasa.Communication
{
/// <summary>
/// Summary description for MiCasaRequestReply.
/// </summary>
public class MiCasaRequestReply
{
//public const int VERB_GET_SECRET = 1;
//public const int VERB_SET_SECRET = 2;
//public const int VERB_GET_KEYCHAIN = 3;
//public const int VERB_GET_STORE = 4;
//public const int VERB_SET_KEYVALUE = 5;
//public const int VERB_GET_KEYVALUE = 6;
public const int VERB_SET_LINKED_KEY = 7;
public const int VERB_GET_LINKED_KEYS = 8;
public const int VERB_REMOVE_LINKED_KEY = 9;
public const int VERB_WRITE_KEY = 10;
public const int VERB_REMOVE_ALL_SECRETS = 11;
public const int VERB_LOCK_STORE = 12;
public const int VERB_UNLOCK_STORE = 13;
public const int VERB_GET_STORE_STATUS = 14;
public const int VERB_REMOVE_KEY = 15;
public const int VERB_READ_KEY = 16;
public const int VERB_GET_KEY_LIST = 17;
public const int VERB_DUMP_LINKED_KEYS = 96;
public const int VERB_CREATE_TEST_SECRETS = 97;
public const int VERB_REMOVE_TEST_SECRETS = 98;
public const int VERB_PING_MICASAD = 99;
public MiCasaRequestReply()
{
//
// TODO: Add constructor logic here
//
}
public static object Send(int verb)
{
return Send(verb, null, null, null, null);
}
public static object Send(int verb, object wo)
{
return Send(verb, null, null, null, wo);
}
public static object Send(int verb,
string sKeyChainID,
string sSecretID,
string sKeyID,
object theObject)
{
// Lengths of message fields
int MSGID_LEN = 2;
int MSG_LEN = 4;
WrappedObject request;
WrappedObject reply = null;
// open a client connection
//IInterProcessConnection clientConnection = null;
ClientChannel ipcChannel = IPCClientFactory.CreateClientConnection();
ipcChannel.Open();
try
{
// contruct and serialize the Message Object
request = new WrappedObject(verb, sKeyChainID, sSecretID, sKeyID, theObject);
BinaryFormatter formatter = new BinaryFormatter();
MemoryStream ms = new MemoryStream();
formatter.Serialize(ms, request);
ms.Flush();
ms.Position = 0;
byte[] rawBytes = new byte[2+4+ms.Length];
byte[] t = new byte[10];
// set message id
int destIndex = 0;
ushort msgId = 20;
t = BitConverter.GetBytes((ushort)msgId);
Array.Copy(t,0,rawBytes,destIndex,MSGID_LEN);
destIndex += MSGID_LEN;
// set the object length
//Poorna
int msgLen = 2+4+(int)ms.Length;
// int msgLen = (int)ms.Length;
t = BitConverter.GetBytes(msgLen);
// t = BitConverter.GetBytes(ms.Length);
Array.Copy(t,0,rawBytes,destIndex,MSG_LEN);
destIndex += MSG_LEN;
// copy in the object
Array.Copy(ms.GetBuffer(), 0, rawBytes, destIndex, ms.Length);
//clientConnection = new ClientPipeConnection("MyPipe", ".");
//clientConnection = new ClientPipeConnection(XTIER_RPC_PIPE, ".");
//clientConnection.Connect();
// write the bytes
//clientConnection.WriteBytes(rawBytes);
ipcChannel.Write(rawBytes);
// read the bytes
//byte[] returnBuffer = clientConnection.ReadBytes();
byte[] returnBuffer = ipcChannel.Read();
if (returnBuffer != null)
{
// deserialize MessageObject
uint iMsgLen = BitConverter.ToUInt32(returnBuffer,0);
ms = new MemoryStream(returnBuffer, 4, (int)iMsgLen);
ms.Position = 0;
reply = (WrappedObject)formatter.Deserialize(ms);
if (reply.GetReturnCode() != 0)
throw new Exception(reply.GetReturnCode().ToString());
}
// close the connection
//clientConnection.Close();
ipcChannel.Close();
}
catch (Exception e1)
{
Console.WriteLine(e1.ToString());
//clientConnection.Dispose();
//throw new Exception(e1.ToString());
}
if (reply != null)
return reply.GetObject();
else
return null;
}
}
}

View File

@@ -0,0 +1,122 @@
using System;
using System.Net;
using System.IO;
using System.Net.Sockets;
using Mono.Unix;
namespace Novell.CASA.MiCasa.Communication
{
/// <summary>
/// Summary description for UnixIPCClientChannel.
/// </summary>
public class UnixIPCClientChannel : ClientChannel
{
private Socket mSocket = null;
private string socketFileName = "/tmp/.novellCASA";
private EndPoint sockEndPoint;
public UnixIPCClientChannel()
{
}
public void Open()
{
mSocket = new Socket( AddressFamily.Unix,
SocketType.Stream,
ProtocolType.IP );
if (mSocket == null) throw new Exception("could not get socket");
sockEndPoint = new UnixEndPoint(socketFileName);
mSocket.Connect(sockEndPoint);
}
public int Read(byte[] buf)
{
buf = Read();
if (buf != null)
{
Console.WriteLine("Bytes read = " + buf.Length);
return buf.Length;
}
else
return 0;
}
public byte[] Read()
{
byte[] returnBuffer = null;
int bytesRecvd = 0;
try
{
/* We need to read 'msgLen' to know how many bytes to
* allocate.
*/
byte[] msgIdBytes = new byte[2];
bytesRecvd = mSocket.Receive(msgIdBytes);
if( 0 == bytesRecvd )
{
return null;
}
byte[] msgLenBytes = new byte[4];
bytesRecvd = mSocket.Receive(msgLenBytes);
if( 0 == bytesRecvd )
{
return null;
}
uint msgLen = BitConverter.ToUInt32(msgLenBytes,0);
if( msgLen > 6 )
{
byte[] buf = new byte[msgLen - 6];
bytesRecvd = mSocket.Receive (buf);
if( 0 == bytesRecvd )
{
return null;
}
returnBuffer = new byte[msgLen];
Array.Copy(msgIdBytes,returnBuffer,2);
Array.Copy(msgLenBytes,0,returnBuffer,2,4);
Array.Copy(buf,0,returnBuffer,6,buf.Length);
return returnBuffer;
}
else
{
returnBuffer = new byte[6];
Array.Copy(msgIdBytes,returnBuffer,2);
Array.Copy(msgLenBytes,0,returnBuffer,2,4);
return returnBuffer;
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
return null;
}
}
public int Write(byte[] buf)
{
try
{
mSocket.Send(buf);
Console.WriteLine("Bytes written = " + buf.Length);
return buf.Length;
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
return 0;
}
}
public void Close()
{
mSocket.Close();
}
}
}

View File

@@ -0,0 +1,80 @@
using System;
using AppModule.InterProcessComm;
using AppModule.NamedPipes;
namespace Novell.CASA.MiCasa.Communication
{
/// <summary>
/// Summary description for WinIPCClientChannel.
/// </summary>
public class WinIPCClientChannel : ClientChannel
{
private static IInterProcessConnection clientConnection = null;
private static string XTIER_RPC_PIPE = "SS_RPC_PIPE";
public WinIPCClientChannel()
{
}
public void Open()
{
if (clientConnection == null)
{
clientConnection = new ClientPipeConnection(XTIER_RPC_PIPE, ".");
clientConnection.Connect();
}
}
public int Read(byte[] buf)
{
buf = Read();
if (buf != null)
return 0;
else
return -1;
}
public byte[] Read()
{
byte[] returnBuffer;
try
{
returnBuffer = clientConnection.ReadBytes();
return returnBuffer;
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
return null;
}
}
public int Write(byte[] buf)
{
try
{
clientConnection.WriteBytes(buf);
return 0;
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
return -1;
}
}
public void Close()
{
//clientConnection.Close();
//clientConnection.Dispose();
}
}
}

11
c_micasad/lib/objs.lux Normal file
View File

@@ -0,0 +1,11 @@
OBJS=\
AssemblyInfo \
common/LinkedKeyInfo \
common/Ping \
common/WrappedObject \
common/MiCASAStore \
communication/IClientChannel \
communication/IPCClientFactory \
communication/MiCasaRequestReply \
communication/UnixIPCClientChannel

11
c_micasad/lib/src.lux Normal file
View File

@@ -0,0 +1,11 @@
SRC=\
AssemblyInfo.cs \
common/LinkedKeyInfo.cs \
common/Ping.cs \
common/WrappedObject.cs \
common/MiCASAStore.cs \
communication/IClientChannel.cs \
communication/IPCClientFactory.cs \
communication/MiCasaRequestReply.cs \
communication/UnixIPCClientChannel.cs

497
c_micasad/lss/CASACrypto.cs Normal file
View File

@@ -0,0 +1,497 @@
using System;
using System.IO;
using System.Text;
using System.Security.Cryptography;
using sscs.common;
using sscs.constants;
namespace sscs.crypto
{
public class CASACrypto
{
internal static byte[] Generate16ByteKeyFromString(string TheString)
{
byte[] baKey = new byte[16]; //return value
try
{
Random rand = new Random(TheString.GetHashCode());
rand.NextBytes(baKey);
}
catch(Exception e)
{
CSSSLogger.ExpLog(e.ToString());
CSSSLogger.DbgLog("Key generation failed");
baKey = null;
}
return baKey;
}
internal static bool StoreKeySetUsingMasterPasscode(byte[] key,
byte[] IV, byte[] baMasterPasscode, string fileName)
{
bool bRet = false;
try
{
//Get an encryptor.
RijndaelManaged myRijndael = new RijndaelManaged();
ICryptoTransform encryptor;
encryptor = myRijndael.CreateEncryptor(baMasterPasscode, baMasterPasscode);
//Encrypt the data to a file
FileStream fsEncrypt = new FileStream(fileName, FileMode.Create);
SHA256 sha = new SHA256Managed();
byte[] hash = sha.ComputeHash(key);
fsEncrypt.Write(hash,0,hash.Length);
fsEncrypt.Flush();
CryptoStream csEncrypt = new CryptoStream(fsEncrypt, encryptor, CryptoStreamMode.Write);
//Write all data to the crypto stream and flush it.
csEncrypt.Write(key, 0, key.Length);
csEncrypt.FlushFinalBlock();
fsEncrypt.Close();
bRet = true;
}
catch(Exception e)
{
CSSSLogger.ExpLog(e.ToString());
CSSSLogger.DbgLog("Unable to store the generated key");
bRet = false;
}
return bRet;
}
internal static byte[] GetKeySetFromFile(byte[] baMasterPasscode,
string fileName )
{
byte[] baSavedKey = null;
try
{
if(!File.Exists(fileName))
{
return null;
}
/* Get a decryptor that uses the same key and IV
* as the encryptor.
*/
RijndaelManaged myRijndael = new RijndaelManaged();
ICryptoTransform decryptor = myRijndael.CreateDecryptor(baMasterPasscode, baMasterPasscode);
//Now decrypt
FileStream fsDecrypt = new FileStream(fileName, FileMode.Open);
byte[] storedHash = new byte[32];
fsDecrypt.Read(storedHash,0,storedHash.Length);
CryptoStream csDecrypt = new CryptoStream(fsDecrypt, decryptor, CryptoStreamMode.Read);
baSavedKey = new byte[32];
//Read the data out of the crypto stream.
csDecrypt.Read(baSavedKey, 0, baSavedKey.Length);
fsDecrypt.Close();
SHA256 sha = new SHA256Managed();
byte[] newHash = sha.ComputeHash(baSavedKey);
for( int i = 0 ; i < 32; i++ )
{
if(storedHash[i] != newHash[i])
{
CSSSLogger.DbgLog("Hash doesnot match");
return null;
}
}
return baSavedKey;
}
catch(Exception e)
{
CSSSLogger.ExpLog(e.ToString());
CSSSLogger.DbgLog("Unable to get the stored key");
baSavedKey = null;
}
return baSavedKey;
}
internal static void EncryptDataAndWriteToFile(byte[] xmlData,
byte[] key, string fileName)
{
try
{
byte[] IV = new byte[16];
for(int z = 0 ; z < 16; z++ )
IV[z] = key[z];
//Get an encryptor.
RijndaelManaged myRijndael = new RijndaelManaged();
ICryptoTransform encryptor = myRijndael.CreateEncryptor(key, IV);
//Encrypt the data to a file
FileStream fsEncrypt = new FileStream(fileName, FileMode.Create);
SHA256 sha = new SHA256Managed();
byte[] hash = sha.ComputeHash(xmlData);
fsEncrypt.Write(hash,0,hash.Length);
fsEncrypt.Flush();
CryptoStream 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();
fsEncrypt.Close();
}
catch(Exception e)
{
CSSSLogger.ExpLog(e.ToString());
CSSSLogger.DbgLog("Encrypting and storing to file failed.");
}
}
internal static byte[] ReadFileAndDecryptData(byte[] key,
string fileName)
{
FileStream fsDecrypt = null;
try
{
byte[] IV = new byte[16];
for(int z = 0 ; z < 16; z++ )
IV[z] = key[z];
//Get a decryptor that uses the same key and IV as the encryptor.
RijndaelManaged myRijndael = new RijndaelManaged();
ICryptoTransform decryptor = myRijndael.CreateDecryptor(key, IV);
if(!File.Exists(fileName))
{
return null;
}
//Now decrypt
fsDecrypt = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read);
byte[] storedHash = new byte[32];
fsDecrypt.Read(storedHash,0,storedHash.Length);
CryptoStream csDecrypt = new CryptoStream(fsDecrypt, decryptor, CryptoStreamMode.Read);
long fileLen = fsDecrypt.Length - 32;
byte[] fromEncrypt = new byte[fileLen];
//Read the data out of the crypto stream.
int bytesRead = csDecrypt.Read(fromEncrypt, 0, fromEncrypt.Length);
byte[] tmpEncrypt = new byte[bytesRead];
for(int i = 0 ; i < bytesRead; i++ )
tmpEncrypt[i] = fromEncrypt[i];
SHA256 sha = new SHA256Managed();
byte[] newHash = sha.ComputeHash(tmpEncrypt);
for( int i = 0 ; i < 32; i++ )
{
if(storedHash[i] != newHash[i])
{
CSSSLogger.DbgLog("Hash doesnot match");
return null;
}
}
fsDecrypt.Close();
return tmpEncrypt;
}
catch(Exception e)
{
Console.WriteLine(e.ToString());
}
if(fsDecrypt != null)
{
fsDecrypt.Close();
}
return null;
}
/* The methods EncryptData() and DecryptData() would be
* required when we use a database to store secrets.
*/
/* Encrypts the data with the key and returns the encrypted buffer.
*/
internal static byte[] EncryptData(byte[] data, byte[] key)
{
try
{
byte[] IV = new byte[16];
int i = 0;
for(i = 0 ; i < 16; i++ )
IV[i] = key[i];
//Get an encryptor.
RijndaelManaged myRijndael = new RijndaelManaged();
ICryptoTransform encryptor = myRijndael.CreateEncryptor(key, IV);
MemoryStream ms1 = new MemoryStream();
CryptoStream csEncrypt = new CryptoStream(ms1, encryptor, CryptoStreamMode.Write);
//Write all data to the crypto stream and flush it.
csEncrypt.Write(data, 0, data.Length);
csEncrypt.FlushFinalBlock();
return ms1.ToArray();
}
catch(Exception e)
{
CSSSLogger.ExpLog(e.ToString());
}
return null;
}
/* Decrypts the buffer(encrypted) with the key and returns the
* decrypted data.
*/
internal static byte[] DecryptData(byte[] buffer, byte[] key)
{
try
{
byte[] IV = new byte[16];
for(int i = 0 ; i < 16; i++ )
IV[i] = key[i];
//Get a decryptor that uses the same key and IV as the encryptor.
RijndaelManaged myRijndael = new RijndaelManaged();
ICryptoTransform decryptor = myRijndael.CreateDecryptor(key, IV);
MemoryStream ms1 = new MemoryStream(buffer);
CryptoStream csDecrypt = new CryptoStream(ms1, decryptor, CryptoStreamMode.Read);
byte[] fromEncrypt = new byte[buffer.Length];
//Read the data out of the crypto stream.
csDecrypt.Read(fromEncrypt, 0, fromEncrypt.Length);
return fromEncrypt;
}
catch(Exception e)
{
CSSSLogger.ExpLog(e.ToString());
}
return null;
}
/* This method checks if we can get the master passcode by
* decrypting the passwds file ( where we store all possible
* passwds cross-encrypted.
*
* TBD : As we are storing master passcode and the keys in 2
* different files, we need to take care of cases when 1 of the files
* is deleted.
*/
internal static bool CheckIfMasterPasscodeIsAvailable(string desktopPasswd, string fileName)
{
return (File.Exists(fileName));
}
internal static byte[] GetMasterPasscode(string desktopPasswd, string fileName)
{
byte[] mp = DecryptMasterPasscodeUsingString(desktopPasswd, fileName);
return mp;
}
/* TBD - There must be a way, where we establish the integrity of
* the files where we store the keys and master passcode.
* Use a marker ?
*/
// Used to save the MasterPasscode encrypted with Desktop login, etc
internal static void EncryptAndStoreMasterPasscodeUsingString(
byte[] baMasterPasscode,
string passwd,
string fileName)
{
try
{
if(File.Exists(fileName))
File.Delete(fileName);
byte[] baKey = Generate16ByteKeyFromString(passwd);
//Get an encryptor.
RijndaelManaged myRijndael = new RijndaelManaged();
ICryptoTransform encryptor;
encryptor = myRijndael.CreateEncryptor(baKey, baKey);
//Encrypt the data to a file
FileStream fsEncrypt = new FileStream(fileName,FileMode.Create);
CryptoStream csEncrypt = new CryptoStream(fsEncrypt, encryptor,
CryptoStreamMode.Write);
//Write all data to the crypto stream and flush it.
csEncrypt.Write(baMasterPasscode, 0, baMasterPasscode.Length);
csEncrypt.FlushFinalBlock();
fsEncrypt.Close();
}
catch(Exception e)
{
CSSSLogger.ExpLog(e.ToString());
}
}
public static byte[] DecryptMasterPasscodeUsingString(string passwd,
string fileName)
{
try
{
byte[] baKey = Generate16ByteKeyFromString(passwd);
/* Get a decryptor that uses the same key and
* IV as the encryptor.
*/
RijndaelManaged myRijndael = new RijndaelManaged();
ICryptoTransform decryptor = myRijndael.CreateDecryptor(baKey,
baKey);
//Now decrypt
FileStream fsDecrypt = new FileStream(fileName, FileMode.Open);
CryptoStream csDecrypt = new CryptoStream(fsDecrypt, decryptor,
CryptoStreamMode.Read);
byte[] baSavedMasterPasscode = new byte[16];
//Read the data out of the crypto stream.
csDecrypt.Read(baSavedMasterPasscode, 0, 16);
fsDecrypt.Close();
return baSavedMasterPasscode;
}
catch(Exception e)
{
CSSSLogger.ExpLog(e.ToString());
CSSSLogger.DbgLog("Unable to decrypt master passode");
}
return null;
}
internal static byte[] GetMasterPasscodeUsingMasterPasswd(
string mPasswd,
string fileName)
{
byte[] baMasterPasscode;
try
{
if(File.Exists(fileName))
{
/* Decrypt the passcode from the file using master passwd.
* and return the decrypted passcode.
*/
baMasterPasscode = DecryptMasterPasscodeUsingString(mPasswd,
fileName);
return baMasterPasscode;
}
else
return null;
}
catch(Exception e)
{
CSSSLogger.ExpLog(e.ToString());
CSSSLogger.DbgLog("Failed to get master passcode from master password.");
}
return null;
}
internal static byte[] GetMasterPasscodeUsingDesktopPasswd(
string desktopPasswd,
string fileName)
{
byte[] passcode;
try
{
if(File.Exists(fileName))
{
/* Decrypt the passcode from the file using desktop passwd.
* and return the decrypted passcode.
*/
passcode = DecryptMasterPasscodeUsingString(desktopPasswd,
fileName);
return passcode;
}
else
return null;
}
catch(Exception e)
{
CSSSLogger.ExpLog(e.ToString());
CSSSLogger.DbgLog("Failed to get master passcode using desktop passwd");
}
return null;
}
//internal static string GenerateMasterPasscodeUsingDesktopPasswd(
internal static byte[] GenerateMasterPasscodeUsingString(
string desktopPasswd,
string fileName,
string validationFile,
UserIdentifier userId
)
{
try
{
/* Generate passcode using desktop passwd and store
* it in the passwd file encrypted with the desktop passwd.
* Encrypt a well-known with the passcode and store it.
* Return the generated passcode.
*/
Random random = new Random(desktopPasswd.GetHashCode());
int randNum = random.Next();
string randStr = randNum.ToString() + userId.GetUID().ToString();
byte[] baPasscode = Generate16ByteKeyFromString(randStr);
EncryptAndStoreMasterPasscodeUsingString(baPasscode,
desktopPasswd,
fileName);
EncryptDataAndWriteToFile(
Encoding.Default.GetBytes(
ConstStrings.MICASA_VALIDATION_STRING),
baPasscode,
validationFile);
return baPasscode;
}
catch(Exception e)
{
CSSSLogger.ExpLog(e.ToString());
CSSSLogger.DbgLog("Generation of master passcode failed.");
}
return null;
}
public static bool ValidatePasscode(byte[] baPasscode, string fileName)
{
/* Here we decrpyt a well known string, throw exception
* if not successful
* A well-known string is encrpyted by the Passcode and saved
*/
if ((baPasscode == null) || baPasscode.Length < 1 )
return false;
try
{
byte[] baString = ReadFileAndDecryptData(baPasscode, fileName);
string sString = Encoding.Default.GetString(baString);
char[] trimChars = {'\0'};
sString = sString.TrimEnd(trimChars);
if( ConstStrings.MICASA_VALIDATION_STRING.Equals(sString))
{
return true;
}
else
{
return false;
}
}
catch(Exception e)
{
CSSSLogger.ExpLog(e.ToString());
CSSSLogger.DbgLog("Validation of passcode failed.");
}
return false;
}
}
}

View File

@@ -0,0 +1,396 @@
using System;
using System.IO;
using System.Text;
using System.Collections;
using System.Threading;
using System.Security.Cryptography;
using System.Xml;
using sscs.cache;
using sscs.crypto;
using sscs.common;
using sscs.constants;
using Novell.CASA.MiCasa.Common;
namespace sscs.lss
{
/// <summary>
/*
* This class is a service to store data persistently.
* How it does this is determined by implementation within the
* private methods (File system using file(s), database, etc)
* The MasterPasscode can be used to generate the key for
* encyption and decryption.
* If encrpytion is used, the private methods will also manage
* how the encyption key is to be stored and retrieved.
* 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.
*/
/// </summary>
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 static string LINUXID = "Unix";
internal LocalStorage(SecretStore store,byte[] baMasterPasscode)
{
userStore = store;
m_baGeneratedKey = baMasterPasscode;
LoadPersistentStore();
userStore.DumpSecretstore();
persistThread = new Thread(new ThreadStart(PersistStoreThreadFn));
persistThread.Start();
}
~LocalStorage()
{
if(persistThread != null)
{
persistThread.Abort();
persistThread.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();
userStore.DumpSecretstore();
persistThread = new Thread(new ThreadStart(PersistStoreThreadFn));
persistThread.Start();
}
public void StorePersistentData(string sDataID, byte[] baData)
{
}
public byte[] RetrievePersistentData(string sDataID)
{
return null;
}
public bool StopPersistence()
{
if(persistThread != null)
{
persistThread.Abort();
persistThread.Join();
}
return true;
}
private string GetDecryptedXml()
{
try
{
string fileName = userStore.GetPersistenceFilePath();
if(!File.Exists(fileName))
return null;
byte[] 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;
char[] chArr = new char[decryptedBuffer.Length];
for(int z = 0; z < decryptedBuffer.Length; z++ )
{
chArr[z] = (char)decryptedBuffer[z];
}
string toReturn = new string(chArr);
return toReturn;
}
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()
{
try
{
string xpath = "";
XmlDocument doc = new XmlDocument();
string xmlToLoad = GetDecryptedXml();
if(xmlToLoad != null)
{
doc.LoadXml(xmlToLoad);
#if false
XmlTextWriter writer = new XmlTextWriter("/home/poorna/.miCASA.xml",null);
writer.Formatting = Formatting.Indented;
doc.Save(writer);
writer.Close();
#endif
}
else
{
return false;
}
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);
}
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);
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;
try
{
key = (attrColl[XmlConsts.idAttr]).Value;
}
catch (Exception)
{
// LinkedKey node, continue
continue;
}
xpath = "descendant::" + XmlConsts.keyValueNode;
XmlNode keyValNode = keyNode.SelectSingleNode(xpath);
string keyValue = keyValNode.InnerText;
secret.SetKeyValue(key,keyValue);
// 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);
KeyValue kv = secret.GetKeyValue(key);
kv.AddLink(lki);
}
}
}//if ends
}
}//end of traversing keyChainNodeList
}
}
catch(Exception e)
{
CSSSLogger.ExpLog(e.ToString());
}
return true;
}
private void PersistStoreThreadFn()
{
while(true)
{
Thread.Sleep(persistThreadSleepTime);
PersistStore();
}
}
/* Persists the store to an xml file.
* TBD : Would we require any form of encoding?
*/
internal void PersistStore()
{
// userStore.DumpSecretstore();
try
{
string fileName = userStore.GetPersistenceFilePath();
if(File.Exists(fileName))
{
File.Delete(fileName);
}
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;
writer.WriteStartElement(XmlConsts.keyChainNode);
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);
writer.WriteAttributeString(XmlConsts.idAttr,sTmpId);
/* If we need to store time
writer.WriteStartElement(XmlConsts.timeNode);
writer.WriteAttributeString(XmlConsts.createdTimeNode,kc.CreatedTime.ToString());
writer.WriteAttributeString(XmlConsts.modifiedTimeNode,kc.ModifiedTime.ToString());
writer.WriteEndElement();
*/
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);
writer.WriteAttributeString(XmlConsts.idAttr,sTmpId);
/* If we need to store time
writer.WriteStartElement(XmlConsts.timeNode);
writer.WriteAttributeString(XmlConsts.createdTimeNode,secret.CreatedTime.ToString());
writer.WriteAttributeString(XmlConsts.modifiedTimeNode,secret.ModifiedTime.ToString());
writer.WriteEndElement();
*/
writer.WriteStartElement(XmlConsts.valueNode);
// byte[] byteArr = secret.GetValue();
IDictionaryEnumerator etor = (IDictionaryEnumerator)secret.GetKeyValueEnumerator();
while(etor.MoveNext())
{
string sKey = (string)etor.Key;
string value = secret.GetKeyValue(sKey).GetValue();
writer.WriteStartElement(XmlConsts.keyNode);
writer.WriteAttributeString(XmlConsts.idAttr, sKey);
writer.WriteStartElement(XmlConsts.keyValueNode);
writer.WriteString(value);
writer.WriteEndElement();
/* If we need to store time
writer.WriteStartElement(XmlConsts.timeNode);
writer.WriteAttributeString(XmlConsts.createdTimeNode,(secret.GetKeyValueCreatedTime(sKey)).ToString());
writer.WriteAttributeString(XmlConsts.modifiedTimeNode,(secret.GetKeyValueModifiedTime(sKey)).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++)
chArr[z] = (char)byteArr[z];
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();
byte[] key = CASACrypto.GetKeySetFromFile(CASACrypto.GetMasterPasscode(userStore.GetDesktopPasswd(),userStore.GetPasscodeByDesktopFilePath()),userStore.GetKeyFilePath());
CASACrypto.EncryptDataAndWriteToFile(ms1.ToArray(),key,fileName);
}
catch(Exception e)
{
CSSSLogger.ExpLog(e.ToString());
}
}
}
}

426
c_micasad/micasad.csproj Normal file
View File

@@ -0,0 +1,426 @@
<VisualStudioProject>
<CSHARP
ProjectType = "Local"
ProductVersion = "7.10.3077"
SchemaVersion = "2.0"
ProjectGuid = "{E39D2266-AB30-430E-A466-AC909363A830}"
>
<Build>
<Settings
ApplicationIcon = ""
AssemblyKeyContainerName = ""
AssemblyName = "micasad"
AssemblyOriginatorKeyFile = ""
DefaultClientScript = "JScript"
DefaultHTMLPageLayout = "Grid"
DefaultTargetSchema = "IE50"
DelaySign = "false"
OutputType = "Exe"
PreBuildEvent = ""
PostBuildEvent = ""
RootNamespace = "sscs"
RunPostBuildEvent = "OnBuildSuccess"
StartupObject = "sscs.init.WinSecretStoreClientService"
>
<Config
Name = "Debug"
AllowUnsafeBlocks = "false"
BaseAddress = "285212672"
CheckForOverflowUnderflow = "false"
ConfigurationOverrideFile = ""
DefineConstants = "DEBUG;TRACE;W32"
DocumentationFile = ""
DebugSymbols = "true"
FileAlignment = "4096"
IncrementalBuild = "false"
NoStdLib = "false"
NoWarn = ""
Optimize = "false"
OutputPath = "bin\Debug\"
RegisterForComInterop = "false"
RemoveIntegerChecks = "false"
TreatWarningsAsErrors = "false"
WarningLevel = "4"
/>
<Config
Name = "Release"
AllowUnsafeBlocks = "false"
BaseAddress = "285212672"
CheckForOverflowUnderflow = "false"
ConfigurationOverrideFile = ""
DefineConstants = "TRACE; W32"
DocumentationFile = ""
DebugSymbols = "false"
FileAlignment = "4096"
IncrementalBuild = "false"
NoStdLib = "false"
NoWarn = ""
Optimize = "true"
OutputPath = "bin\Release\"
RegisterForComInterop = "false"
RemoveIntegerChecks = "false"
TreatWarningsAsErrors = "false"
WarningLevel = "4"
/>
</Settings>
<References>
<Reference
Name = "System.Configuration.Install"
AssemblyName = "System.Configuration.Install"
HintPath = "C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\System.Configuration.Install.dll"
/>
<Reference
Name = "System.Data"
AssemblyName = "System.Data"
HintPath = "C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\System.Data.dll"
/>
<Reference
Name = "System"
AssemblyName = "System"
HintPath = "C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\System.dll"
/>
<Reference
Name = "System.Management"
AssemblyName = "System.Management"
HintPath = "C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\System.Management.dll"
/>
<Reference
Name = "System.ServiceProcess"
AssemblyName = "System.ServiceProcess"
HintPath = "C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\System.ServiceProcess.dll"
/>
<Reference
Name = "System.XML"
AssemblyName = "System.Xml"
HintPath = "C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\System.XML.dll"
/>
<Reference
Name = "System.Windows.Forms"
AssemblyName = "System.Windows.Forms"
HintPath = "C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\System.Windows.Forms.dll"
/>
<Reference
Name = "Accessibility"
AssemblyName = "Accessibility"
HintPath = "C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\Accessibility.dll"
/>
<Reference
Name = "System.Drawing"
AssemblyName = "System.Drawing"
HintPath = "C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\System.Drawing.dll"
/>
<Reference
Name = "System.Runtime.Serialization.Formatters.Soap"
AssemblyName = "System.Runtime.Serialization.Formatters.Soap"
HintPath = "C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\System.Runtime.Serialization.Formatters.Soap.dll"
/>
<Reference
Name = "Novell.CASA.Common"
Project = "{57CD94A2-5B4A-40C3-8189-CB760FB78357}"
Package = "{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}"
/>
</References>
</Build>
<Files>
<Include>
<File
RelPath = "cache\IKeychain.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "cache\ISecret.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "cache\KeyChain.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "cache\KeyValue.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "cache\Secret.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "cache\SecretStore.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "common\Constants.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "common\CSSSException.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "common\CSSSLogger.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "common\RequestParser.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "common\SessionManager.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "common\User.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "common\UserIdentifier.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "common\WinUser.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "common\WinUserIdentifier.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "communication\CommunicationFactory.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "communication\ICommunication.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "communication\IPCChannel.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "communication\WinCommunication.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "communication\WinIPCChannel.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "communication\win\InterProcessComm\IChannelManager.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "communication\win\InterProcessComm\IClientChannel.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "communication\win\InterProcessComm\IInterProcessConnection.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "communication\win\InterProcessComm\InterProcessConnectionState.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "communication\win\InterProcessComm\InterProcessIOException.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "communication\win\NamedPipes\APipeConnection.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "communication\win\NamedPipes\ClientPipeConnection.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "communication\win\NamedPipes\NamedPipeIOException.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "communication\win\NamedPipes\NamedPipeNative.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "communication\win\NamedPipes\NamedPipeWrapper.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "communication\win\NamedPipes\PipeHandle.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "communication\win\NamedPipes\PipeManager.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "communication\win\NamedPipes\ServerNamedPipe.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "communication\win\NamedPipes\ServerPipeConnection.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "init\AppHandler.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "init\ProjectInstaller.cs"
SubType = "Component"
BuildAction = "Compile"
/>
<File
RelPath = "init\ProjectInstaller.resx"
DependentUpon = "ProjectInstaller.cs"
BuildAction = "EmbeddedResource"
/>
<File
RelPath = "init\WinSecretStoreClientService.cs"
SubType = "Component"
BuildAction = "Compile"
/>
<File
RelPath = "init\WinSecretStoreClientService.resx"
DependentUpon = "WinSecretStoreClientService.cs"
BuildAction = "EmbeddedResource"
/>
<File
RelPath = "lss\CASACrypto.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "lss\LocalStorage.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<Folder RelPath = "startup\" />
<File
RelPath = "verbs\AddKeyChain.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "verbs\CloseSecretStore.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "verbs\EnumerateKeyChainIds.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "verbs\EnumerateSecretIds.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "verbs\GetSecretStoreInfo.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "verbs\IsSecretPersistent.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "verbs\ISSVerb.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "verbs\ObjectSerialization.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "verbs\OpenSecretStore.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "verbs\ReadKey.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "verbs\ReadSecret.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "verbs\RemoveKeyChain.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "verbs\RemoveSecret.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "verbs\RemoveSecretStore.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "verbs\SetMasterPasscode.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "verbs\SetMasterPassword.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "verbs\WriteKey.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "verbs\WriteSecret.cs"
SubType = "Code"
BuildAction = "Compile"
/>
</Include>
</Files>
</CSHARP>
</VisualStudioProject>

View File

@@ -0,0 +1,48 @@
<VisualStudioProject>
<CSHARP LastOpenVersion = "7.10.3077" >
<Build>
<Settings ReferencePath = "" >
<Config
Name = "Debug"
EnableASPDebugging = "false"
EnableASPXDebugging = "false"
EnableUnmanagedDebugging = "false"
EnableSQLServerDebugging = "false"
RemoteDebugEnabled = "false"
RemoteDebugMachine = ""
StartAction = "Project"
StartArguments = "/Standalone"
StartPage = ""
StartProgram = ""
StartURL = ""
StartWorkingDirectory = ""
StartWithIE = "true"
/>
<Config
Name = "Release"
EnableASPDebugging = "false"
EnableASPXDebugging = "false"
EnableUnmanagedDebugging = "false"
EnableSQLServerDebugging = "false"
RemoteDebugEnabled = "false"
RemoteDebugMachine = ""
StartAction = "Project"
StartArguments = "/Standalone"
StartPage = ""
StartProgram = ""
StartURL = ""
StartWorkingDirectory = ""
StartWithIE = "false"
/>
</Settings>
</Build>
<OtherProjectSettings
CopyProjectDestinationFolder = ""
CopyProjectUncPath = ""
CopyProjectOption = "0"
ProjectView = "ShowAllFiles"
ProjectTrust = "0"
/>
</CSHARP>
</VisualStudioProject>

56
c_micasad/objs.lux Normal file
View File

@@ -0,0 +1,56 @@
OBJS=\
init/Main \
init/AppHandler \
common/RequestParser \
common/SessionManager \
common/User \
common/UnixUser \
common/UserIdentifier \
common/UnixUserIdentifier \
common/Constants \
common/CSSSLogger \
common/CSSSException \
communication/IPCChannel \
communication/CommunicationFactory \
communication/UnixIPCChannel \
communication/ICommunication \
communication/UnixCommunication \
cache/KeyChain \
cache/Secret \
cache/SecretStore \
cache/KeyValue \
cache/IKeychain \
cache/ISecret \
lss/LocalStorage \
lss/CASACrypto \
verbs/ISSVerb \
verbs/GetSecretStoreInfo \
verbs/OpenSecretStore \
verbs/CloseSecretStore \
verbs/RemoveSecretStore \
verbs/AddKeyChain \
verbs/RemoveKeyChain \
verbs/WriteSecret \
verbs/ReadSecret \
verbs/RemoveSecret \
verbs/EnumerateKeyChainIds \
verbs/EnumerateSecretIds \
verbs/SetMasterPassword \
verbs/WriteKey \
verbs/ReadKey \
verbs/IsSecretPersistent \
verbs/ObjectSerialization \
test/cache/TestSecret \
test/cache/TestKeyChain \
test/cache/TestSecretStore \
test/common/TestSessionManager \
test/common/TestRequestParser \
test/communication/TestUnixCommunication \
test/verbs/TestOpenSecretStore \
test/verbs/TestCloseSecretStore \
test/verbs/TestEnumerateKeyChainIDs \
test/verbs/TestEnumerateSecIDs \
test/verbs/TestReadSecret \
test/verbs/TestRemoveKeyChain \
test/verbs/TestWriteSecret

75
c_micasad/objs.w32 Normal file
View File

@@ -0,0 +1,75 @@
OBJS=\
init/WinSecretStoreClientService \
init/ProjectInstaller \
init/AppHandler \
common/RequestParser \
common/SessionManager \
common/User \
common/WinUser \
common/UserIdentifier \
common/WinUserIdentifier \
common/NsscsFile \
common/Constants \
common/TrustedProcess \
common/CSSSLogger \
common/CSSSException \
communication/win/InterProcessComm/IChannelManager \
communication/win/InterProcessComm/IClientChannel \
communication/win/InterProcessComm/IInterProcessConnection \
communication/win/InterProcessComm/InterProcessConnectionState \
communication/win/InterProcessComm/InterProcessIOException \
communication/win/NamedPipes/APipeConnection \
communication/win/NamedPipes/ClientPipeConnection \
communication/win/NamedPipes/NamedPipeIOException \
communication/win/NamedPipes/NamedPipeNative \
communication/win/NamedPipes/NamedPipeWrapper \
communication/win/NamedPipes/PipeHandle \
communication/win/NamedPipes/PipeManager \
communication/win/NamedPipes/ServerNamedPipe \
communication/win/NamedPipes/ServerPipeConnection \
communication/IPCChannel \
communication/CommunicationFactory \
communication/WinIPCChannel \
communication/ICommunication \
communication/WinCommunication \
cache/KeyChain \
cache/Secret \
cache/SecretStore \
cache/Time \
cache/Value \
cache/Eprotect \
cache/IKeychain \
cache/ISecret \
lss/LocalSecretStore \
verbs/ISSVerb \
verbs/GetSecretStoreInfo \
verbs/OpenSecretStore \
verbs/CloseSecretStore \
verbs/RemoveSecretStore \
verbs/AddKeyChain \
verbs/RemoveKeyChain \
verbs/WriteSecret \
verbs/ReadSecret \
verbs/RemoveSecret \
verbs/WriteKey \
verbs/ReadKey \
verbs/SetWorkStationPasswd \
verbs/SetPassCode \
verbs/NotifyUserState \
verbs/GetUserState \
verbs/IsSecretPersistent.cs \
verbs/SetMasterPassword.cs \
verbs/EnumerateKeyChainIds \
verbs/EnumerateSecretIds \
test/cache/TestSecret.cs \
test/cache/TestKeyChain.cs \
test/cache/TestSecretStore.cs \
test/common/TestSessionManager.cs \
test/common/TestRequestParser.cs \
test/verbs/TestOpenSecretStore.cs \
test/verbs/TestCloseSecretStore.cs \
test/verbs/TestEnumerateKeyChainIDs.cs \
test/verbs/TestEnumerateSecIDs.cs \
test/verbs/TestReadSecret.cs \
test/verbs/TestRemoveKeyChain.cs \
test/verbs/TestWriteSecret.cs

57
c_micasad/src.lux Normal file
View File

@@ -0,0 +1,57 @@
SRC=\
init/Main.cs \
init/AppHandler.cs \
common/RequestParser.cs \
common/SessionManager.cs \
common/User.cs \
common/UnixUser.cs \
common/UserIdentifier.cs \
common/UnixUserIdentifier.cs \
common/Constants.cs \
common/CSSSLogger.cs \
common/CSSSException.cs \
communication/IPCChannel.cs \
communication/CommunicationFactory.cs \
communication/UnixIPCChannel.cs \
communication/ICommunication.cs \
communication/UnixCommunication.cs \
cache/KeyChain.cs \
cache/Secret.cs \
cache/SecretStore.cs \
cache/KeyValue.cs \
cache/IKeychain.cs \
cache/ISecret.cs \
lss/LocalStorage.cs \
lss/CASACrypto.cs \
verbs/ISSVerb.cs \
verbs/GetSecretStoreInfo.cs \
verbs/OpenSecretStore.cs \
verbs/CloseSecretStore.cs \
verbs/RemoveSecretStore.cs \
verbs/AddKeyChain.cs \
verbs/RemoveKeyChain.cs \
verbs/WriteSecret.cs \
verbs/ReadSecret.cs \
verbs/RemoveSecret.cs \
verbs/EnumerateKeyChainIds.cs \
verbs/EnumerateSecretIds.cs \
verbs/SetMasterPassword.cs \
verbs/WriteKey.cs \
verbs/ReadKey.cs \
verbs/IsSecretPersistent.cs \
verbs/ObjectSerialization.cs \
test/cache/TestSecret.cs \
test/cache/TestKeyChain.cs \
test/cache/TestSecretStore.cs \
test/common/TestSessionManager.cs \
test/common/TestRequestParser.cs \
test/communication/TestUnixCommunication.cs \
test/verbs/TestOpenSecretStore.cs \
test/verbs/TestCloseSecretStore.cs \
test/verbs/TestEnumerateKeyChainIDs.cs \
test/verbs/TestEnumerateSecIDs.cs \
test/verbs/TestReadSecret.cs \
test/verbs/TestRemoveKeyChain.cs \
test/verbs/TestWriteSecret.cs

56
c_micasad/src.w32 Normal file
View File

@@ -0,0 +1,56 @@
SRC=\
init\\WinSecretStoreClientService.cs \
init\\ProjectInstaller.cs \
init\\AppHandler.cs \
common\\RequestParser.cs \
common\\SessionManager.cs \
common\\User.cs \
common\\WinUser.cs \
common\\UserIdentifier.cs \
common\\WinUserIdentifier.cs \
common\\Constants.cs \
common\\CSSSLogger.cs \
common\\CSSSException.cs \
communication\\win\\InterProcessComm\\IChannelManager.cs \
communication\\win\\InterProcessComm\\IClientChannel.cs \
communication\\win\\InterProcessComm\\IInterProcessConnection.cs \
communication\\win\\InterProcessComm\\InterProcessConnectionState.cs \
communication\\win\\InterProcessComm\\InterProcessIOException.cs \
communication\\win\\NamedPipes\\APipeConnection.cs \
communication\\win\\NamedPipes\\ClientPipeConnection.cs \
communication\\win\\NamedPipes\\NamedPipeIOException.cs \
communication\\win\\NamedPipes\\NamedPipeNative.cs \
communication\\win\\NamedPipes\\NamedPipeWrapper.cs \
communication\\win\\NamedPipes\\PipeHandle.cs \
communication\\win\\NamedPipes\\PipeManager.cs \
communication\\win\\NamedPipes\\ServerNamedPipe.cs \
communication\\win\\NamedPipes\\ServerPipeConnection.cs \
communication\\IPCChannel.cs \
communication\\CommunicationFactory.cs \
communication\\WinIPCChannel.cs \
communication\\ICommunication.cs \
communication\\WinCommunication.cs \
lss\\LocalStorage.cs\
lss\\CASACrypto.cs\
cache\\KeyValue.cs\
cache\\KeyChain.cs \
cache\\Secret.cs \
cache\\SecretStore.cs \
cache\\IKeychain.cs \
cache\\ISecret.cs \
verbs\\ISSVerb.cs \
verbs\\GetSecretStoreInfo.cs \
verbs\\OpenSecretStore.cs \
verbs\\CloseSecretStore.cs \
verbs\\RemoveSecretStore.cs \
verbs\\AddKeyChain.cs \
verbs\\RemoveKeyChain.cs \
verbs\\WriteSecret.cs \
verbs\\ReadSecret.cs \
verbs\\RemoveSecret.cs \
verbs\\ReadKey.cs \
verbs\\WriteKey.cs \
verbs\\IsSecretPersistent.cs \
verbs\\SetMasterPassword.cs \
verbs\\EnumerateKeyChainIds.cs \
verbs\\EnumerateSecretIds.cs

58
c_micasad/startup/micasad Normal file
View File

@@ -0,0 +1,58 @@
#! /bin/sh
### BEGIN INIT INFO
#Default-Start: 1 2 3 5
#Description: miCASA daemon
### END INIT INFO
MICASAD_BIN=/opt/novell/CASA/bin/micasad.sh
test -x $MICASAD_BIN || exit 5
. /etc/rc.status
# Shell functions sourced from /etc/rc.status:
# rc_check check and set local and overall rc status
# rc_status check and set local and overall rc status
# rc_status -v ditto but be verbose in local rc status
# rc_status -v -r ditto and clear the local rc status
# rc_failed set local and overall rc status to failed
# rc_reset clear local rc status (overall remains)
# rc_exit exit appropriate to overall rc status
# First reset status of this service
rc_reset
case "$1" in
start)
echo -n "Starting miCASA daemon"
startproc -f $MICASAD_BIN
# Remember status and be verbose
rc_status -v
;;
stop)
echo -n "Shutting miCASA daemon down"
#killproc -TERM $MICASAD_BIN
pid=`cat /var/run/micasad.pid`
kill -s TERM $pid
# Remember status and be verbose
rc_status -v
;;
restart)
## Stop the service and regardless of whether it was
## running or not, start it again.
echo -n "Restarting miCASA daemon"
$0 stop
$0 start
# Remember status and be quiet
rc_status
;;
*)
echo "Usage: $0 {start|stop|restart}"
exit 1
;;
esac
rc_exit

View File

@@ -0,0 +1,3 @@
#!/bin/sh
export MONO_PATH=/opt/novell/CASA/lib
mono /opt/novell/CASA/bin/micasad.exe

14
c_micasad/test/ReadMe.txt Normal file
View File

@@ -0,0 +1,14 @@
Read Me:
-------
The current Directoy "test" is has unit test cases to test the miCASA daemon c# code.
It uses Nunit(nunit.org) to develop testcases and execute the same.
There is a directory structure similar to the daemon code inside the test dir.
For any function or aspect which needs to be tested in Daemon, add Test code here and
the Test stubs will appear in the Ddebug build of micasad.exe
usage mono /dependencies/nunit-console.exe ../../bin/lux/dbg/micasad.exe
Windows has a GUI tool, can be downloaded at nunit.org

123
c_micasad/test/cache/TestKeyChain.cs vendored Normal file
View File

@@ -0,0 +1,123 @@
#if DEBUG
using System;
using System.Text;
using System.Collections;
//using System.InvalidOperationException;
using NUnit.Framework;
using sscs.common;
namespace sscs.cache
{
[TestFixture]
public class TestKeyChain
{
Secret mysec;
KeyChain mykc;
string secval;
byte[] secbyte;
[SetUp]
public void Init()
{
mykc = new KeyChain("TestingID");
secval= "novell123";
secbyte = Encoding.ASCII.GetBytes(secval);
mysec = new Secret();
mysec.SetKey("testkey");
mysec.SetValue(secbyte);
}
[Test]
public void TestAddSecret()
{
mykc.AddSecret(mysec);
Secret returnsecret = mykc.GetSecret("testkey");
Assert.AreEqual("novell123", Encoding.ASCII.GetString(returnsecret.GetValue("testkey")));
}
[Test]
public void TestAddSecretWithDup()
{
//Add one more with same secret id
byte[] newvalue = Encoding.ASCII.GetBytes("miCASA");
mysec.SetValue(newvalue);
mykc.AddSecret(mysec);
Secret returnsecret = mykc.GetSecret("testkey");
Assert.AreEqual("miCASA", Encoding.ASCII.GetString(returnsecret.GetValue("testkey")));
}
[Test]
[ExpectedException(typeof(SecretNotFoundException))]
public void TestRemoveSecret()
{
mykc.RemoveSecret("testkey");
//Try and get the same.
//Secret sec = mykc.GetSecret("testkey");
}
[Test]
[ExpectedException(typeof(InvalidOperationException))]
public void TestGetAllSecretsWhenNone()
{
// IDictionaryEnumerator myenum = (IDictionaryEnumerator)mykc.GetAllSecrets();
//Object temp = myenum.Current;
}
[Test]
public void TestGetAllSecrets()
{
int count = 0;
byte[] val1 = Encoding.ASCII.GetBytes("val1");
byte[] val2 = Encoding.ASCII.GetBytes("val2");
byte[] val3 = Encoding.ASCII.GetBytes("val3");
Secret sec1 = new Secret("key1", val1);
Secret sec2 = new Secret("key2", val2);
Secret sec3 = new Secret("key3", val3);
mykc.AddSecret(sec1);
mykc.AddSecret(sec2);
mykc.AddSecret(sec3);
IDictionaryEnumerator myenum =(IDictionaryEnumerator) mykc.GetAllSecrets();
while(myenum.MoveNext())
{
count++;
}
Assert.AreEqual(3, mykc.GetNumSecrets());
Assert.AreEqual(3, count);
}
}
}
#endif

55
c_micasad/test/cache/TestSecret.cs vendored Normal file
View File

@@ -0,0 +1,55 @@
#if DEBUG
using System;
using System.Text;
using NUnit.Framework;
namespace sscs.cache
{
[TestFixture]
public class TestSecret
{
[Test]
public void DefaultAddSecret()
{
string someotherstr = "newvalue";
byte[] newval = Encoding.ASCII.GetBytes(someotherstr);
Secret mysec = new Secret();
mysec.SetKey("newkey");
mysec.SetValue(newval);
mysec.SetEpasswd("enhanced");
mysec.SetKey("alternatekey");
Assert.AreEqual("newvalue", Encoding.ASCII.GetString(mysec.GetValue("alternatekey")));
}
[Test]
public void TestAddSecret()
{
string somestr = "novell123";
string someotherstr = "newvalue";
byte[] mybyte = Encoding.ASCII.GetBytes(somestr);
byte[] newval = Encoding.ASCII.GetBytes(someotherstr);
Secret mysec = new Secret("mail", mybyte);
mysec.SetKey("newkey");
mysec.SetValue(newval);
Assert.AreEqual("newkey", mysec.GetKey());
Assert.AreEqual("newvalue", Encoding.ASCII.GetString(mysec.GetValue()));
}
//TBD: Need to Add Timestamp related cases, could be done when we use it
}
}
#endif

128
c_micasad/test/cache/TestSecretStore.cs vendored Normal file
View File

@@ -0,0 +1,128 @@
#if DEBUG
using System;
using System.Text;
using System.Collections;
//using System.InvalidOperationException;
using NUnit.Framework;
using sscs.common;
namespace sscs.cache
{
[TestFixture]
public class TestSecretStore
{
User theuser = null;
UnixUserIdentifier UserId = null;
SecretStore mysec = null;
KeyChain mykc = null;
byte[] secbyte = null;
Secret mysecret = null;
[SetUp]
public void Init()
{
mykc = new KeyChain("TestingID");
mysecret = new Secret();
mysecret.SetKey("testkey");
secbyte = Encoding.ASCII.GetBytes("NOVELL");
mysecret.SetValue(secbyte);
mykc.AddSecret(mysecret);
UserId = new UnixUserIdentifier(420);
theuser = new UnixUser(UserId);
mysec = new SecretStore(theuser);
}
[Test]
public void TestIntialState()
{
Assert.AreEqual(0, mysec.GetNumKeyChains());
// Assert.AreEqual(0, mysec.getRefCount());
Assert.AreEqual(0, mysec.GetSecretStoreState());
}
[Test]
public void TestAddKeyChain()
{
mysec.AddKeyChain(mykc);
Assert.AreEqual(1, mysec.GetNumKeyChains());
Secret returnsec = (mysec.GetKeyChain("TestingID")).GetSecret("testkey");;
Assert.AreEqual("NOVELL", Encoding.ASCII.GetString(returnsec.GetValue("testkey")));
}
[Test]
public void TestRemoveKeyChain()
{
mysec.RemoveKeyChain("TestingID");
Assert.AreEqual(0, mysec.GetNumKeyChains());
Assert.AreEqual(false, mysec.CheckIfKeyChainExists("TestingID"));
}
[Test]
[ExpectedException(typeof(KeyChainDoesNotExistException))]
public void TestRemoveKeyChainAgain()
{
mysec.GetKeyChain("TestingID");
}
[Test]
public void TestGetKeyChainEnumerator()
{
KeyChain mykc1 = new KeyChain("kc1");
KeyChain mykc2 = new KeyChain("kc2");
KeyChain mykc3 = new KeyChain("kc3");
Secret mysecret1 = new Secret("key1", secbyte);
Secret mysecret2 = new Secret("key2", secbyte);
Secret mysecret3 = new Secret("key3", secbyte);
mykc1.AddSecret(mysecret1);
mykc2.AddSecret(mysecret2);
mykc3.AddSecret(mysecret3);
mysec.AddKeyChain(mykc1);
mysec.AddKeyChain(mykc2);
mysec.AddKeyChain(mykc3);
Assert.AreEqual(3, mysec.GetNumKeyChains());
}
}
}
#endif

View File

@@ -0,0 +1,87 @@
#if DEBUG
using System;
using System.Text;
using System.Collections;
//using System.InvalidOperationException;
using NUnit.Framework;
using sscs.common;
using sscs.verbs;
namespace sscs.cache
{
[TestFixture]
public class TestRequestParser
{
RequestParser reqParser = null;
[SetUp]
public void Init()
{
reqParser = new RequestParser();
}
[Test]
[ExpectedException(typeof(FormatException))]
public void TestNullRequest()
{
// SSVerb verb = reqParser.ParseRequest(null);
reqParser.ParseRequest(null);
}
[Test]
public void TestParseRequest()
{
// byte[] buf = new byte[1024];
//buf[0] = 1;
// buf[1] = 1;
int i =1;
byte[] dummy = BitConverter.GetBytes(i);
SSVerb verb = reqParser.ParseRequest(dummy);
Assert.AreEqual("sscs.verbs.OpenSecretStore", verb.GetVerbName());
i = 18;
dummy = BitConverter.GetBytes(i);
verb = reqParser.ParseRequest(dummy);
Assert.AreEqual("sscs.verbs.GetUserState", verb.GetVerbName());
}
[Test]
[ExpectedException(typeof(ArgumentNullException))]
public void TestParseRequestInvalid()
{
byte[] buf = new byte[1024] ;
buf[0] = 25;
buf[1] = 25;
// SSVerb verb = reqParser.ParseRequest(buf);
reqParser.ParseRequest(buf);
}
}
}
#endif

View File

@@ -0,0 +1,154 @@
#if DEBUG
using System;
using System.Text;
using System.Collections;
//using System.InvalidOperationException;
using NUnit.Framework;
using sscs.common;
using sscs.cache;
namespace sscs.common
{
[TestFixture]
public class TestSessionManager
{
User theuser = null;
UnixUserIdentifier UserId = null;
UnixUserIdentifier root = null;
SecretStore mysec = null;
SecretStore anothersec = null;
KeyChain mykc1 = null;
KeyChain mykc2 = null;
byte[] secbyte1 = null;
byte[] secbyte2 = null;
Secret mysecret1 = null;
Secret mysecret2 = null;
SessionManager sesman ;
[SetUp]
public void Init()
{
sesman = SessionManager.GetSessionManager;
mykc1 = new KeyChain("k1");
mykc2 = new KeyChain("k2");
mysecret1 = new Secret();
mysecret2 = new Secret();
mysecret1.SetKey("key1");
mysecret2.SetKey("key2");
secbyte1 = Encoding.ASCII.GetBytes("NOVELL");
secbyte2 = Encoding.ASCII.GetBytes("IBM");
mysecret1.SetValue(secbyte1);
mysecret2.SetValue(secbyte2);
mykc1.AddSecret(mysecret1);
mykc2.AddSecret(mysecret2);
UserId = new UnixUserIdentifier(420);
root = new UnixUserIdentifier(0);
//theuser = new UnixUser(UserId);
}
[Test]
public void TestCreateUserSession()
{
anothersec = SessionManager.CreateUserSession(root);
mysec = SessionManager.CreateUserSession(UserId);
//Assert.AreEqual(1, mysec.getRefCount());
//Assert.AreEqual(1, anothersec.getRefCount());
Assert.AreEqual(true, SessionManager.CheckIfUserSessionExists(UserId));
Assert.AreEqual(true, SessionManager.CheckIfUserSessionExists(root));
}
[Test]
public void TestAddtoSession()
{
SecretStore s1 = SessionManager.GetUserSecretStore(UserId);
SecretStore s2 = SessionManager.GetUserSecretStore(root);
s1.AddKeyChain(mykc1);
s2.AddKeyChain(mykc2);
s1 = SessionManager.GetUserSecretStore(UserId);
s2 = SessionManager.GetUserSecretStore(root);
KeyChain returnK1 = s1.GetKeyChain("k1");
Secret returnS1 = returnK1.GetSecret("key1");
KeyChain returnK2 = s2.GetKeyChain("k2");
Secret returnS2 = returnK2.GetSecret("key2");
Assert.AreEqual("NOVELL", Encoding.ASCII.GetString(returnS1.GetValue()));
Assert.AreEqual("IBM",Encoding.ASCII.GetString(returnS2.GetValue()) );
}
[Test]
[ExpectedException(typeof(KeyChainDoesNotExistException))]
public void TestInvalidAccess()
{
SecretStore s1 = SessionManager.GetUserSecretStore(UserId);
//SecretStore s2 = SessionManager.GetUserSecretStore(root);
s1.GetKeyChain("k2");
}
[Test]
public void TestRemoveUserSession()
{
SessionManager.RemoveUserSession(UserId, true);
Assert.AreEqual(false, SessionManager.CheckIfUserSessionExists(UserId));
//TBD :Make the ref count more than one and delete call remove sesison once.
//The call it once more.. only second time it should remove the session entry.
}
}
}
#endif

View File

@@ -0,0 +1,56 @@
#if DEBUG
using System;
using System.Text;
using System.IO;
using System.Threading;
using NUnit.Framework;
using sscs.communication;
namespace sscs.communication
{
[TestFixture]
public class TestUnixCommunication
{
static Communication comm;
Thread listeningthread = null;
[SetUp]
public void Init()
{
}
[Test]
//[Ignore("That thread thing")]
public void TestCommunication()
{
comm = new UnixCommunication();
listeningthread = new Thread(new ThreadStart(StartServ));
listeningthread.Start();
//comm.StartCommunicationEndPoint();
comm.CloseCommunicationEndPoint();
Assert.AreEqual(false, File.Exists("/tmp/novellSSCS"));
}
private static void StartServ()
{
comm.StartCommunicationEndPoint();
}
}
}
#endif

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,47 @@
#if DEBUG
using System;
using System.Text;
using System.Collections;
//using System.InvalidOperationException;
using NUnit.Framework;
using sscs.common;
using sscs.cache;
using sscs.verbs;
namespace sscs.verbs
{
[TestFixture]
public class TestAddKeyChain
{
[SetUp]
public void Init()
{
}
// TBD: Need to construct the input buf and output buf and call the processRequest()
//As of now all internal functions are tested and the cachelib test code
// also indirectly tests this function.
}
}
#endif

View File

@@ -0,0 +1,43 @@
#if DEBUG
using System;
using System.Text;
using System.Collections;
//using System.InvalidOperationException;
using NUnit.Framework;
using sscs.common;
using sscs.cache;
using sscs.verbs;
namespace sscs.verbs
{
[TestFixture]
public class TestCloseSecretStore
{
[SetUp]
public void Init()
{
}
// TBD: Need to construct the input buf and output buf and call the processRequest()
//As of now all internal functions are tested and the cachelib test code
// also indirectly tests this function.
}
}
#endif

View File

@@ -0,0 +1,46 @@
#if DEBUG
using System;
using System.Text;
using System.Collections;
//using System.InvalidOperationException;
using NUnit.Framework;
using sscs.common;
using sscs.cache;
using sscs.verbs;
namespace sscs.verbs
{
[TestFixture]
public class TestEnumerateKeyChainID
{
[SetUp]
public void Init()
{
}
// TBD: Need to construct the input buf and output buf and call the processRequest()
//As of now all internal functions are tested and the cachelib test code
// also indirectly tests this function.
}
}
#endif

View File

@@ -0,0 +1,47 @@
#if DEBUG
using System;
using System.Text;
using System.Collections;
//using System.InvalidOperationException;
using NUnit.Framework;
using sscs.common;
using sscs.cache;
using sscs.verbs;
namespace sscs.verbs
{
[TestFixture]
public class TestEnumerateSecID
{
[SetUp]
public void Init()
{
}
// TBD: Need to construct the input buf and output buf and call the processRequest()
//As of now all internal functions are tested and the cachelib test code
// also indirectly tests this function.
}
}
#endif

View File

@@ -0,0 +1,62 @@
#if DEBUG
using System;
using System.Text;
using System.Collections;
//using System.InvalidOperationException;
using NUnit.Framework;
using sscs.common;
using sscs.cache;
using sscs.verbs;
namespace sscs.verbs
{
[TestFixture]
public class TestOpenSecretStore
{
[SetUp]
public void Init()
{
}
/*
[Test]
[ExpectedException(typeof(InvalidOperationException))]
public void TestNullVerb()
{
SSVerb verb = new OpenSecretStore();
verb.processRequest(UserId);
}
*/
// TBD: Need to construct the input buf and output buf and call the processRequest()
//As of now all internal functions are tested and the cachelib test code
// also indirectly tests this function.
}
}
#endif

View File

@@ -0,0 +1,47 @@
#if DEBUG
using System;
using System.Text;
using System.Collections;
//using System.InvalidOperationException;
using NUnit.Framework;
using sscs.common;
using sscs.cache;
using sscs.verbs;
namespace sscs.verbs
{
[TestFixture]
public class TestReadSecret
{
[SetUp]
public void Init()
{
}
// TBD: Need to construct the input buf and output buf and call the processRequest()
//As of now all internal functions are tested and the cachelib test code
// also indirectly tests this function.
}
}
#endif

View File

@@ -0,0 +1,48 @@
#if DEBUG
using System;
using System.Text;
using System.Collections;
//using System.InvalidOperationException;
using NUnit.Framework;
using sscs.common;
using sscs.cache;
using sscs.verbs;
namespace sscs.verbs
{
[TestFixture]
public class TestRemoveKeyChain
{
[SetUp]
public void Init()
{
}
// TBD: Need to construct the input buf and output buf and call the processRequest()
//As of now all internal functions are tested and the cachelib test code
// also indirectly tests this function.
}
}
#endif

View File

@@ -0,0 +1,48 @@
#if DEBUG
using System;
using System.Text;
using System.Collections;
//using System.InvalidOperationException;
using NUnit.Framework;
using sscs.common;
using sscs.cache;
using sscs.verbs;
namespace sscs.verbs
{
[TestFixture]
public class TestWriteSecret
{
[SetUp]
public void Init()
{
}
// TBD: Need to construct the input buf and output buf and call the processRequest()
//As of now all internal functions are tested and the cachelib test code
// also indirectly tests this function.
}
}
#endif

View File

@@ -0,0 +1,129 @@
using System;
using System.Collections;
using System.Text;
using System.Threading;
using sscs.verbs;
using sscs.common;
using sscs.cache;
using sscs.constants;
namespace sscs.verbs
{
/*
* This class is implementation of AddKeyChain call.
* There will be one instance existing for every call made by the client.
*/
internal class AddKeyChain : SSVerb
{
private ushort msgId = 0;
private uint inMsgLen = 0;
private uint keyChainFlags = 0;
private uint keyChainIdLen = 0;
private string keyChainId;
private uint outMsgLen = 0;
private byte[] inBuf;
private byte[] outBuf;
private int retCode = 0;
/*
* This method sets the class member with the byte array received.
*/
public void SetMessageContent(byte[] ipcBytes)
{
CSSSLogger.ExecutionTrace(this);
inBuf = ipcBytes;
}
/*
* This method does the actual implementation of AddKeyChain
*/
public byte[] ProcessRequest(UserIdentifier userId)
{
/* If an exception occurs in message format decoding,
* it is handled by AppHandler
*/
CSSSLogger.ExecutionTrace(this);
// Message Format decipher - Start
msgId = BitConverter.ToUInt16(inBuf,0);
inMsgLen = BitConverter.ToUInt32(inBuf,2);
if( inMsgLen != inBuf.Length )
throw new FormatException(" MsgLen sent does not match the length of the message received.");
keyChainFlags = BitConverter.ToUInt32(inBuf,6);
keyChainIdLen = BitConverter.ToUInt32(inBuf,10);
byte[] tempArr = new byte[keyChainIdLen];
Array.Copy(inBuf,14,tempArr,0,keyChainIdLen);
keyChainId = Encoding.UTF8.GetString(tempArr);
// Message Format decipher - End
try
{
SecretStore ssStore = null;
KeyChain keyChain = null;
keyChain = new KeyChain(keyChainId);
ssStore = SessionManager.GetUserSecretStore(userId);
if( ssStore.CheckIfKeyChainExists(keyChainId) == false )
{
ssStore.AddKeyChain(keyChain);
}
else
{
CSSSLogger.DbgLog("In " + CSSSLogger.GetExecutionPath(this) + " Keychain already present for keychain id " +keyChainId );
retCode = IPCRetCodes.SSCS_E_KEYCHAIN_ALREADY_EXISTS;
}
}
catch(UserNotInSessionException)
{
CSSSLogger.DbgLog("In " + CSSSLogger.GetExecutionPath(this) + " Unable to get user's secretstore" );
retCode = IPCRetCodes.SSCS_E_SYSTEM_ERROR;
}
catch(Exception e)
{
CSSSLogger.ExpLog(e.ToString());
retCode = IPCRetCodes.SSCS_E_SYSTEM_ERROR;
}
try
{
msgId = 5;
outMsgLen = 10;
outBuf = new byte[10];
byte[] t = new byte[10];
t = BitConverter.GetBytes((ushort)msgId);
Array.Copy(t,0,outBuf,0,2);
t = BitConverter.GetBytes((uint)outMsgLen);
Array.Copy(t,0,outBuf,2,4);
t = BitConverter.GetBytes(retCode);
Array.Copy(t,0,outBuf,6,4);
}
catch(Exception e)
{
CSSSLogger.ExpLog(e.ToString());
throw new FormatException("Unable to form the response " + e.ToString());
}
return outBuf;
}
/*
* Gives the name of operation performed. Will be used in case
* of error.
*/
public string GetVerbName()
{
CSSSLogger.ExecutionTrace(this);
return (this.ToString());
}
}
}

View File

@@ -0,0 +1,117 @@
using System;
using System.Collections;
using System.Text;
using System.Threading;
using sscs.verbs;
using sscs.common;
using sscs.cache;
using sscs.constants;
namespace sscs.verbs
{
/*
* This class is implementation of CloseSecretStore call.
* There will be one instance existing for every call made by the client.
*/
internal class CloseSecretStore : SSVerb
{
private ushort msgId = 0;
private uint inMsgLen = 0;
private uint outMsgLen = 0;
private byte[] inBuf;
private byte[] outBuf;
private int retCode = 0;
/*
* This method sets the class member with the byte array received.
*/
public void SetMessageContent(byte[] ipcBytes)
{
CSSSLogger.ExecutionTrace(this);
inBuf = ipcBytes;
}
/*
* This method does the actual implementation of CloseSecretStore
*
*/
public byte[] ProcessRequest(UserIdentifier userId)
{
/* If an exception occurs in message format decoding,
* it is handled by AppHandler
*/
CSSSLogger.ExecutionTrace(this);
// Message Format decipher - Start
msgId = BitConverter.ToUInt16(inBuf,0);
inMsgLen = BitConverter.ToUInt32(inBuf,2);
if( inMsgLen != inBuf.Length )
throw new FormatException(" MsgLen sent does not match the length of the message received.");
uint ssFlags = BitConverter.ToUInt32(inBuf,6);
// Message Format decipher - End
try
{
if ((ssFlags & ConstFlags.SSFLAGS_DESTROY_SESSION_F) == ConstFlags.SSFLAGS_DESTROY_SESSION_F)
{
#if W32
SessionManager.RemoveUserSession(userId, true);
#else
SessionManager.CheckAndDestroySession(userId, true);
#endif
}
else
SessionManager.RemoveUserSession(userId, false);
}
catch(Exception)
{
CSSSLogger.DbgLog("In " + CSSSLogger.GetExecutionPath(this) + " Exception encountered in removing user session.");
retCode = IPCRetCodes.SSCS_E_SYSTEM_ERROR;
}
// Construct a Reply.
try
{
msgId = 2;
outMsgLen = 10;
outBuf = new byte[10];
byte[] t = new byte[10];
t = BitConverter.GetBytes((ushort)msgId);
Array.Copy(t,0,outBuf,0,2);
t = BitConverter.GetBytes((uint)outMsgLen);
Array.Copy(t,0,outBuf,2,4);
t = BitConverter.GetBytes(retCode);
Array.Copy(t,0,outBuf,6,4);
}
catch(Exception e)
{
CSSSLogger.ExpLog(e.ToString());
throw new FormatException("Unable to form the response " + e.ToString());
}
return outBuf;
}
/*
* Gives the name of operation performed. Will be used in case
* of error.
*/
public string GetVerbName()
{
CSSSLogger.ExecutionTrace(this);
return this.ToString();
}
}
}

View File

@@ -0,0 +1,131 @@
using System;
using System.Collections;
using System.Text;
using System.Threading;
using sscs.verbs;
using sscs.cache;
using sscs.common;
using sscs.constants;
namespace sscs.verbs
{
/*
* This class is implementation of EnumerateKeyChainIds call.
* There will be one instance existing for every call made by the client.
*/
internal class EnumerateKeyChainIds : SSVerb
{
private ushort msgId = 0;
private uint inMsgLen = 0;
private uint outMsgLen = 0;
private int retCode = 0;
private byte[] inBuf;
private byte[] outBuf;
/*
* This method sets the class member with the byte array received.
*/
public void SetMessageContent(byte[] ipcBytes)
{
CSSSLogger.ExecutionTrace(this);
inBuf = ipcBytes;
}
/*
* This method does the actual implementation of EnumerateKeyChainIds
*
*/
public byte[] ProcessRequest(UserIdentifier userId)
{
CSSSLogger.ExecutionTrace(this);
int keyChainIdsLen = 0;
StringBuilder keyChainIds = new StringBuilder();
/* If an exception occurs in message format decoding,
* it is handled by AppHandler
*/
// Message Format decipher - Start
msgId = BitConverter.ToUInt16(inBuf,0);
inMsgLen = BitConverter.ToUInt32(inBuf,2);
if( inMsgLen != inBuf.Length )
throw new FormatException(" MsgLen sent does not match the length of the message received.");
// Message Format decipher - End
try
{
int index = 0;
SecretStore ssStore = SessionManager.GetUserSecretStore(userId);
int numKeyChains = ssStore.GetNumKeyChains();
IDictionaryEnumerator etor = (IDictionaryEnumerator)ssStore.GetKeyChainEnumerator();
while(etor.MoveNext())
{
index++;
keyChainIds.Append((string)etor.Key,0,(((string)(etor.Key)).Length)-1);
keyChainIdsLen += ((string)(etor.Key)).Length-1;
if( index != numKeyChains )
{
keyChainIds.Append("*");
keyChainIdsLen += 1;
}
}
}
catch(UserNotInSessionException)
{
CSSSLogger.DbgLog("In " + CSSSLogger.GetExecutionPath(this) + " Unable to get user's secretstore" );
retCode = IPCRetCodes.SSCS_E_SYSTEM_ERROR;
}
catch(Exception e)
{
CSSSLogger.ExpLog(e.ToString());
retCode = IPCRetCodes.SSCS_E_SYSTEM_ERROR;
}
// Construct a Reply.
try
{
msgId = 4;
outMsgLen = 14 + (uint)keyChainIds.Length;
outBuf = new byte[outMsgLen];
byte[] t = new byte[10];
t = BitConverter.GetBytes((ushort)msgId);
Array.Copy(t,0,outBuf,0,2);
t = BitConverter.GetBytes((uint)outMsgLen);
Array.Copy(t,0,outBuf,2,4);
t = BitConverter.GetBytes(keyChainIdsLen);
Array.Copy(t,0,outBuf,6,4);
Encoding.UTF8.GetBytes(keyChainIds.ToString(),0,keyChainIds.Length,outBuf,10);
t = BitConverter.GetBytes(retCode);
Array.Copy(t,0,outBuf,(10+keyChainIds.Length),4);
}
catch(Exception e)
{
CSSSLogger.ExpLog(e.ToString());
throw new FormatException("Unable to form the response " + e.ToString());
}
return outBuf;
}
/*
* Gives the name of operation performed. Will be used in case
* of error.
*/
public string GetVerbName()
{
return this.ToString();
}
}
}

View File

@@ -0,0 +1,147 @@
using System;
using System.Collections;
using System.Text;
using System.Threading;
using sscs.verbs;
using sscs.cache;
using sscs.common;
using sscs.constants;
namespace sscs.verbs
{
/*
* This class is implementation of EnumerateSecretIds call.
* There will be one instance existing for every call made by the client.
*/
internal class EnumerateSecretIds : SSVerb
{
private ushort msgId = 0;
private uint inMsgLen = 0;
private uint outMsgLen = 0;
private uint keyChainIdLen = 0;
private string keyChainId;
private int retCode = 0;
private byte[] inBuf;
private byte[] outBuf;
/*
* This method sets the class member with the byte array received.
*/
public void SetMessageContent(byte[] ipcBytes)
{
CSSSLogger.ExecutionTrace(this);
inBuf = ipcBytes;
}
/*
* This method does the actual implementation of EnumerateSecretIds
*
*/
public byte[] ProcessRequest(UserIdentifier userId)
{
/* If an exception occurs in message format decoding,
* it is handled by AppHandler
*/
int secretIdsLen = 0;
StringBuilder secretIds = new StringBuilder();
// Message Format decipher - Start
msgId = BitConverter.ToUInt16(inBuf,0);
inMsgLen = BitConverter.ToUInt32(inBuf,2);
if( inMsgLen != inBuf.Length )
throw new FormatException(" MsgLen sent does not match the length of the message received.");
keyChainIdLen = BitConverter.ToUInt32(inBuf,6);
byte[] keyChainIdArr = new byte[keyChainIdLen];
Array.Copy(inBuf,10,keyChainIdArr,0,keyChainIdLen);
keyChainId = Encoding.UTF8.GetString(keyChainIdArr);
// Message Format decipher - End
try
{
SecretStore ssStore = SessionManager.GetUserSecretStore(userId);
if( ssStore.CheckIfKeyChainExists(keyChainId) )
{
KeyChain keyChain = ssStore.GetKeyChain(keyChainId);
int numSecrets = keyChain.GetNumSecrets();
int index = 0;
IDictionaryEnumerator etor = (IDictionaryEnumerator)keyChain.GetAllSecrets();
while(etor.MoveNext())
{
index++;
secretIds.Append((string)etor.Key,0,(((string)(etor.Key)).Length)-1);
secretIdsLen += ((string)(etor.Key)).Length-1;
if( index != numSecrets )
{
secretIds.Append("*");
secretIdsLen += 1;
}
}
}
else
{
retCode = IPCRetCodes.SSCS_E_KEYCHAIN_DOES_NOT_EXIST;
}
}
catch(UserNotInSessionException)
{
CSSSLogger.DbgLog("In " + CSSSLogger.GetExecutionPath(this) + " Unable to get user's secretstore" );
retCode = IPCRetCodes.SSCS_E_SYSTEM_ERROR;
}
catch(Exception)
{
retCode = IPCRetCodes.SSCS_E_SYSTEM_ERROR;
}
//Construct a reply.
try
{
msgId = 7;
outMsgLen = 14 + (uint)secretIds.Length;
outBuf = new byte[outMsgLen];
byte[] t = new byte[10];
t = BitConverter.GetBytes((ushort)msgId);
Array.Copy(t,0,outBuf,0,2);
t = BitConverter.GetBytes((uint)outMsgLen);
Array.Copy(t,0,outBuf,2,4);
t = BitConverter.GetBytes(secretIdsLen);
Array.Copy(t,0,outBuf,6,4);
Encoding.UTF8.GetBytes(secretIds.ToString(),0,secretIds.Length,outBuf,10);
t = BitConverter.GetBytes(retCode);
Array.Copy(t,0,outBuf,(10+secretIds.Length),4);
}
catch(Exception e)
{
CSSSLogger.ExpLog(e.ToString());
throw new FormatException("Unable to form the response " + e.ToString());
}
return outBuf;
}
/*
* Gives the name of operation performed. Will be used in case
* of error.
*/
public string GetVerbName()
{
CSSSLogger.ExecutionTrace(this);
return this.ToString();
}
}
}

View File

@@ -0,0 +1,120 @@
using System;
using System.Collections;
using System.Text;
using System.Threading;
using sscs.verbs;
using sscs.common;
using sscs.cache;
using sscs.constants;
namespace sscs.verbs
{
/*
* This class is implementation of GetSecretStoreInfo call.
* There will be one instance existing for every call made by the client.
*/
internal class GetSecretStoreInfo : SSVerb
{
private ushort msgId = 0;
private uint inMsgLen = 0;
private uint outMsgLen = 0;
private uint numKeyChains = 0;
private byte[] inBuf;
private byte[] outBuf;
private int retCode = 0;
/*
* This method sets the class member with the byte array received.
*/
public void SetMessageContent(byte[] ipcBytes)
{
CSSSLogger.ExecutionTrace(this);
inBuf = ipcBytes;
}
/*
* This method does the actual implementation of GetSecretStoreInfo
*
*/
public byte[] ProcessRequest(UserIdentifier userId)
{
CSSSLogger.ExecutionTrace(this);
/* If an exception occurs in message format decoding,
* it is handled by AppHandler
*/
// Message Format decipher - Start
msgId = BitConverter.ToUInt16(inBuf,0);
inMsgLen = BitConverter.ToUInt32(inBuf,2);
if( inMsgLen != inBuf.Length )
throw new FormatException(" MsgLen sent does not match the length of the message received.");
// Message Format decipher - End
try
{
SecretStore ssStore = SessionManager.GetUserSecretStore(userId);
numKeyChains = (uint) ssStore.GetNumKeyChains();
}
catch(UserNotInSessionException)
{
CSSSLogger.DbgLog("In " + CSSSLogger.GetExecutionPath(this) + " Unable to get user's secretstore" );
retCode = IPCRetCodes.SSCS_E_SYSTEM_ERROR;
}
catch(Exception e)
{
CSSSLogger.ExpLog(e.ToString());
retCode = IPCRetCodes.SSCS_E_SYSTEM_ERROR;
}
// Construct Response
try
{
msgId = 11;
outMsgLen = 14;
outBuf = new byte[outMsgLen];
byte[] t = new byte[10];
t = BitConverter.GetBytes((ushort)msgId);
Array.Copy(t,0,outBuf,0,2);
t = BitConverter.GetBytes((uint)outMsgLen);
Array.Copy(t,0,outBuf,2,4);
t = BitConverter.GetBytes(numKeyChains);
Array.Copy(t,0,outBuf,6,4);
t = BitConverter.GetBytes(retCode);
Array.Copy(t,0,outBuf,10,4);
}
catch(Exception e)
{
CSSSLogger.ExpLog(e.ToString());
throw new FormatException("Unable to form the response " + e.ToString());
}
return outBuf;
}
/*
* Gives the name of operation performed. Will be used in case
* of error.
*/
public string GetVerbName()
{
CSSSLogger.ExecutionTrace(this);
return this.ToString();
}
}
}

View File

@@ -0,0 +1,34 @@
using System;
using System.Collections;
using System.Text;
using System.Threading;
using sscs.verbs;
using sscs.common;
namespace sscs.verbs
{
/*
* Defines the interfaces to be implemenetd by all Secret Store Verbs.
*/
interface SSVerb
{
/* Takes in the raw bytes and sets them for a Verb,
* so that the verb will execute in the bytes given.
* TBD: In case we are able to send the byte[] through constructor,
* we can avoid this interface.
*/
void SetMessageContent(byte[] rawbytes);
/* Takes in the SecretStore Reeference and returns the correct SSVerb
*/
byte[] ProcessRequest(UserIdentifier userId);
//Gives the name of operation performed.Can be used in case of error.
string GetVerbName();
}
}

View File

@@ -0,0 +1,156 @@
using System;
using System.Collections;
using System.Text;
using System.Threading;
using sscs.verbs;
using sscs.common;
using sscs.cache;
using sscs.constants;
namespace sscs.verbs
{
/*
* This class is implementation of IsSecretPersistent call.
* There will be one instance existing for every call made by the client.
*/
class IsSecretPersistent : SSVerb
{
private ushort msgId = 0;
private uint inMsgLen = 0;
private uint outMsgLen = 0;
private uint keyChainIdLen = 0;
private uint secretIdLen = 0;
private int ssFlags = 0;
private int retCode = 0;
private string keyChainId;
private string secretId;
private byte[] inBuf;
private byte[] outBuf;
/*
* This method sets the class member with the byte array received.
*/
public void SetMessageContent(byte[] ipcBytes)
{
CSSSLogger.ExecutionTrace(this);
inBuf = ipcBytes;
}
/*
* This method does the actual implementation of IsSecretPersistent
*
*/
public byte[] ProcessRequest(UserIdentifier userId)
{
CSSSLogger.ExecutionTrace(this);
// Message Format decipher - Start
msgId = BitConverter.ToUInt16(inBuf,0);
inMsgLen = BitConverter.ToUInt32(inBuf,2);
ssFlags = BitConverter.ToInt32(inBuf,6);
if( inMsgLen != inBuf.Length )
throw new FormatException(" MsgLen sent does not match the length of the message received.");
if(ssFlags == 0)
{
keyChainIdLen = BitConverter.ToUInt32(inBuf,10);
byte[] keyChainIdArr = new byte[keyChainIdLen];
Array.Copy(inBuf,14,keyChainIdArr,0,keyChainIdLen);
keyChainId = Encoding.UTF8.GetString(keyChainIdArr);
secretIdLen = BitConverter.ToUInt32(inBuf,
(14 + (int)keyChainIdLen ));
byte[] secretIdArr = new byte[secretIdLen];
Array.Copy(inBuf,(14+keyChainIdLen+4),secretIdArr,0,secretIdLen);
secretId = Encoding.UTF8.GetString(secretIdArr);
}
try
{
KeyChain keyChain = null;
SecretStore ssStore = SessionManager.GetUserSecretStore(userId);
if(ssFlags != 0)
{
if(ssStore.IsStorePersistent())
retCode = IPCRetCodes.SSCS_STORE_IS_PERSISTENT;
else
retCode = IPCRetCodes.SSCS_STORE_IS_NOT_PERSISTENT;
}
else
{
if( ssStore.CheckIfKeyChainExists(keyChainId) )
{
keyChain = ssStore.GetKeyChain(keyChainId);
if( keyChain.CheckIfSecretExists(secretId) == false)
{
if(ssStore.IsStorePersistent())
retCode = IPCRetCodes.SSCS_SECRET_IS_PERSISTENT;
else
retCode = IPCRetCodes.SSCS_SECRET_IS_NOT_PERSISTENT;
}
else
{
retCode = IPCRetCodes.SSCS_E_SECRETID_DOES_NOT_EXIST;
}
}
else
{
retCode = IPCRetCodes.SSCS_E_KEYCHAIN_DOES_NOT_EXIST;
}
}
}
catch(UserNotInSessionException)
{
CSSSLogger.DbgLog("In " + CSSSLogger.GetExecutionPath(this) + " Unable to get user's secretstore" );
retCode = IPCRetCodes.SSCS_E_SYSTEM_ERROR;
}
catch(Exception e )
{
CSSSLogger.ExpLog(e.ToString());
retCode = IPCRetCodes.SSCS_E_SYSTEM_ERROR;
}
try
{
msgId = 19;
outMsgLen = 10;
outBuf = new byte[10];
byte[] t = new byte[10];
t = BitConverter.GetBytes((ushort)msgId);
Array.Copy(t,0,outBuf,0,2);
t = BitConverter.GetBytes((uint)outMsgLen);
Array.Copy(t,0,outBuf,2,4);
t = BitConverter.GetBytes(retCode);
Array.Copy(t,0,outBuf,6,4);
}
catch(Exception e)
{
CSSSLogger.ExpLog(e.ToString());
throw new FormatException("Unable to form the response " + e.ToString());
}
return outBuf;
}
/*
* Gives the name of operation performed. Will be used in case
* of error.
*/
public string GetVerbName()
{
CSSSLogger.ExecutionTrace(this);
return this.ToString();
}
}
}

View File

@@ -0,0 +1,772 @@
using System;
using System.Collections;
using System.Text;
using System.Threading;
using sscs.verbs;
using sscs.cache;
using sscs.common;
using sscs.constants;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using Novell.CASA.MiCasa.Common;
using Novell.CASA.MiCasa.Communication;
namespace sscs.verbs
{
/*
* There will be one instance existing for every call made by the client.
*/
internal class ObjectSerialization : SSVerb
{
private ushort msgId = 0;
private uint inMsgLen = 0;
private byte[] inBuf;
private byte[] outBuf;
/*
* This method sets the class member with the byte array received.
*/
public void SetMessageContent(byte[] ipcBytes)
{
CSSSLogger.ExecutionTrace(this);
inBuf = ipcBytes;
}
/*
* This method does the actual implementation of ReadSecret
*
*/
public byte[] ProcessRequest(UserIdentifier userId)
{
CSSSLogger.ExecutionTrace(this);
/* If an exception occurs in message format decoding,
* it is handled by AppHandler
*/
// Message Format decipher - Start
msgId = BitConverter.ToUInt16(inBuf,0);
inMsgLen = BitConverter.ToUInt32(inBuf,2);
//Console.WriteLine("Serialization verb: msgId is " + msgId + " inMsgLen = " + inMsgLen + "inBuf.Length is " + inBuf.Length);
// if( inMsgLen != inBuf.Length )
// Console.WriteLine("inMsgLen != inBuf.Length");
// throw new FormatException(" MsgLen sent does not match the length of the message received.");
// deserialize the data
BinaryFormatter formatter = new BinaryFormatter();
MemoryStream ms = new MemoryStream(inBuf, 6, (int)inMsgLen - 6);
// MemoryStream ms = new MemoryStream(inBuf, 6, (int)inMsgLen);
WrappedObject request;
WrappedObject reply;
try
{
request = (WrappedObject)formatter.Deserialize(ms);
reply = ProcessMessage(request, userId);
}
catch (Exception e)
{
reply = new WrappedObject(-1, null);
}
// Serialize the WrappedObject and send the reply
ms = new MemoryStream();
formatter.Serialize(ms, reply);
int msLen = (int)ms.Length;
outBuf = new byte[4+msLen];
byte[] t = new byte[10];
t = BitConverter.GetBytes(ms.Length);
Array.Copy(t,0,outBuf,0,4);
Array.Copy(ms.GetBuffer(), 0, outBuf, 4, msLen);
SessionManager.RemoveUserSession(userId, false);
return outBuf;
}
internal WrappedObject ProcessMessage(WrappedObject wo, UserIdentifier userId)
{
//Console.WriteLine("ObjectSerialization Called");
SecretStore ssStore = SessionManager.CreateUserSession(userId);
try
{
int action = wo.GetAction();
switch (action)
{
case MiCasaRequestReply.VERB_PING_MICASAD:
{
return DoPing(wo);
}
case MiCasaRequestReply.VERB_SET_LINKED_KEY:
{
return DoSetLinkedKey(ssStore, wo);
}
case MiCasaRequestReply.VERB_REMOVE_LINKED_KEY:
{
return DoRemoveLinkedKey(ssStore, wo);
}
case MiCasaRequestReply.VERB_GET_LINKED_KEYS:
{
return DoGetLinkedKeys(ssStore, wo);
}
case MiCasaRequestReply.VERB_CREATE_TEST_SECRETS:
{
return DoCreateTestSecrets(ssStore, wo);
}
case MiCasaRequestReply.VERB_REMOVE_TEST_SECRETS:
{
return DoRemoveTestSecrets(ssStore, wo);
}
case MiCasaRequestReply.VERB_DUMP_LINKED_KEYS:
{
return DoDumpLinkedKeys(ssStore, wo);
}
case MiCasaRequestReply.VERB_WRITE_KEY:
{
return DoWriteKey(ssStore, wo);
}
case MiCasaRequestReply.VERB_LOCK_STORE:
{
ssStore.LockStore();
return wo;
}
case MiCasaRequestReply.VERB_UNLOCK_STORE:
{
return DoUnlockStore(ssStore, wo);
}
case MiCasaRequestReply.VERB_REMOVE_ALL_SECRETS:
{
// stop persistence
ssStore.StopPersistence();
// remove secrets
return DoRemoveAllSecrets(ssStore, wo);
}
case MiCasaRequestReply.VERB_GET_STORE_STATUS:
{
wo.SetObject(ssStore.GetSecretStoreState());
return wo;
}
case MiCasaRequestReply.VERB_REMOVE_KEY:
{
return DoRemoveKey(ssStore, wo);
}
case MiCasaRequestReply.VERB_READ_KEY:
{
return DoReadKey(ssStore, wo);
}
case MiCasaRequestReply.VERB_GET_KEY_LIST:
{
return DoGetKeyList(ssStore, wo);
}
default:
{
wo.SetError(constants.RetCodes.FAILURE, "Verb Not Supported");
return wo;
}
}
}
catch (Exception e)
{
wo.SetError(constants.RetCodes.FAILURE, e.ToString());
}
return wo;
}
private WrappedObject DoRemoveAllSecrets(SecretStore ssStore, WrappedObject wo)
{
string sKeyChainID = wo.GetKeychainID();
if (sKeyChainID != null)
{
KeyChain kc = ssStore.GetKeyChain(sKeyChainID);
kc.RemoveAllSecrets();
}
return wo;
}
private WrappedObject DoUnlockStore(SecretStore ssStore, WrappedObject wo)
{
try
{
ssStore.UnlockStore("Desktop", "Master");
}
catch (Exception e)
{
wo.SetError(constants.RetCodes.FAILURE, e.ToString());
}
return wo;
}
private WrappedObject DoRemoveKey(SecretStore ssStore, WrappedObject wo)
{
try
{
string keychainID = wo.GetKeychainID();
string secretID = wo.GetSecretID();
string keyID = wo.GetKeyID();
KeyChain keyChain = ssStore.GetKeyChain(keychainID);
Secret secret = null;
if( keyChain.CheckIfSecretExists(secretID) == false)
{
wo.SetError(constants.RetCodes.FAILURE,"Secret does not exist");
}
else
{
secret = keyChain.GetSecret(secretID);
secret.RemoveKeyValue(keyID);
wo.SetError(constants.RetCodes.SUCCESS, null);
}
}
catch (Exception e)
{
wo.SetError(constants.RetCodes.FAILURE, e.ToString());
}
return wo;
}
private WrappedObject DoReadKey(SecretStore ssStore, WrappedObject wo)
{
try
{
string keychainID = wo.GetKeychainID();
string secretID = wo.GetSecretID();
string keyID = wo.GetKeyID();
// string sValue = (String)wo.GetObject();
KeyChain keyChain = ssStore.GetKeyChain(keychainID);
Secret secret = null;
if( keyChain.CheckIfSecretExists(secretID) == false)
{
wo.SetError(constants.RetCodes.FAILURE,"Secret does not exist");
}
else
{
secret = keyChain.GetSecret(secretID);
KeyValue kv = secret.GetKeyValue(keyID);
string value = kv.GetValue();
wo.SetObject(value);
wo.SetError(constants.RetCodes.SUCCESS, null);
}
}
catch (Exception e)
{
wo.SetError(constants.RetCodes.FAILURE, e.ToString());
}
return wo;
}
private WrappedObject DoGetKeyList(SecretStore ssStore, WrappedObject wo)
{
try
{
string keychainID = wo.GetKeychainID();
string secretID = wo.GetSecretID();
KeyChain keyChain = ssStore.GetKeyChain(keychainID);
Secret secret = null;
if( keyChain.CheckIfSecretExists(secretID) == false)
{
wo.SetError(constants.RetCodes.FAILURE,"Secret does not exist");
}
else
{
secret = keyChain.GetSecret(secretID);
if( null != secret )
{
ArrayList keyList = secret.GetKeyList();
wo.SetObject(keyList);
wo.SetError(constants.RetCodes.SUCCESS, null);
}
}
}
catch (Exception e)
{
wo.SetError(constants.RetCodes.FAILURE, e.ToString());
}
return wo;
}
private WrappedObject DoWriteKey(SecretStore ssStore, WrappedObject wo)
{
try
{
string keychainID = wo.GetKeychainID();
string secretID = wo.GetSecretID();
string keyID = wo.GetKeyID();
string sValue = (String)wo.GetObject();
KeyChain keyChain = ssStore.GetKeyChain(keychainID);
Secret secret;
if( keyChain.CheckIfSecretExists(secretID) == false)
{
secret = new Secret(secretID);
keyChain.AddSecret(secret);
}
else
{
secret = keyChain.GetSecret(secretID);
}
secret.SetKeyValue(keyID, sValue);
ChangeLinkedKeys(keyChain, secret, keyID, sValue);
wo.SetError(constants.RetCodes.SUCCESS, null);
}
catch (Exception e)
{
wo.SetError(constants.RetCodes.FAILURE, e.ToString());
}
return wo;
}
private void ChangeLinkedKeys(KeyChain keyChain, Secret secret, string key, string valStr)
{
Hashtable htLinkedkeys = secret.GetLinkedKeys(key);
if (htLinkedkeys != null)
{
// enumerate the hashtable, getting each secret/key and change it's value
ICollection coll = htLinkedkeys.Values;
IDictionaryEnumerator ienum = (IDictionaryEnumerator)coll.GetEnumerator();
LinkedKeyInfo linkedInfo; // = (LinkedKeyInfo)ienum.Current;
while (ienum.MoveNext())
{
linkedInfo = (LinkedKeyInfo)ienum.Value;
// Get the target Secret
Secret targetSecret = keyChain.GetSecret(linkedInfo.GetLinkedSecretID());
if (targetSecret != null)
{
// get target key value
string targetkv = targetSecret.GetKeyValue(linkedInfo.GetLinkedKeyID()).GetValue();
// if a change is required in the target, then call this method recursively using the TargetSecret
if (!targetkv.Equals(valStr))
{
// NOTE: ORDER IS IMPORTANT
// first change this one
targetSecret.SetKeyValue(linkedInfo.GetLinkedKeyID(), valStr);
// now call the traget to change it's linked ones
ChangeLinkedKeys(keyChain, targetSecret, key, valStr);
}
}
}
}
}
private WrappedObject DoDumpLinkedKeys(SecretStore ssStore, WrappedObject wo)
{
// create 2 secrets
string keychainID = wo.GetKeychainID();
KeyChain keyChain;
Console.WriteLine("\r\n*********Dumping Linked Keys");
try
{
keyChain = ssStore.GetKeyChain(keychainID);
}
catch (Exception)
{
keyChain = new KeyChain(keychainID);
ssStore.AddKeyChain(keyChain);
}
// enumerate all secrets
IDictionaryEnumerator ienum = (IDictionaryEnumerator)keyChain.GetAllSecrets();
ienum.Reset();
while (ienum.MoveNext())
{
string secretID = (string)ienum.Key;
Secret secret = keyChain.GetSecret(secretID);
IDictionaryEnumerator idenum = secret.GetKeyValueEnumerator();
idenum.Reset();
while (idenum.MoveNext())
{
KeyValue kv = (KeyValue)idenum.Value;
Hashtable htLKI = kv.GetLinkedKeys();
if (htLKI != null)
{
Console.WriteLine(secret.GetKey() + ":" + kv.Key + " is Linked to");
IDictionaryEnumerator htienum = (IDictionaryEnumerator)htLKI.GetEnumerator();
htienum.Reset();
while (htienum.MoveNext())
{
LinkedKeyInfo lki = (LinkedKeyInfo) htienum.Value;
Console.WriteLine(" " + lki.GetLinkID());
}
}
}
}
return wo;
}
string GW = "SS_CredSet:TestGroupwise\0";
string IFOLDER = "SS_CredSet:TestiFolder\0";
string GWIM = "SS_CredSet:TestGWIM\0";
private WrappedObject DoRemoveTestSecrets(SecretStore ssStore, WrappedObject wo)
{
string keychainID = wo.GetKeychainID();
KeyChain keyChain;
try
{
keyChain = ssStore.GetKeyChain(keychainID);
}
catch (Exception)
{
return wo;
}
try
{
keyChain.RemoveSecret(GW);
}
catch (Exception)
{}
try
{
keyChain.RemoveSecret(GWIM);
}
catch (Exception)
{}
try
{
keyChain.RemoveSecret(IFOLDER);
}
catch (Exception)
{}
return wo;
}
private WrappedObject DoCreateTestSecrets(SecretStore ssStore, WrappedObject wo)
{
// create 2 secrets
string keychainID = wo.GetKeychainID();
KeyChain keyChain;
try
{
keyChain = ssStore.GetKeyChain(keychainID);
}
catch (Exception)
{
keyChain = new KeyChain(keychainID);
ssStore.AddKeyChain(keyChain);
}
Secret secret1 = new Secret(GW);
secret1.SetKeyValue("CN", "User1");
secret1.SetKeyValue("Password", "GWPass");
try
{
keyChain.AddSecret(secret1);
}
catch (Exception)
{}
Secret secret2 = new Secret(IFOLDER);
secret2.SetKeyValue("CN", "User2");
secret2.SetKeyValue("Password", "IfolderPass");
secret2.SetKeyValue("EmployeeID", "123456");
try
{
keyChain.AddSecret(secret2);
}
catch (Exception)
{}
Secret secret3 = new Secret(GWIM);
secret3.SetKeyValue("CN", "User3");
secret3.SetKeyValue("Password", "GwimPass");
try
{
keyChain.AddSecret(secret3);
}
catch (Exception)
{}
try
{
// link password fields
KeyValue kv = secret1.GetKeyValue("Password");
KeyValue kv2 = secret2.GetKeyValue("Password");
KeyValue kv3 = secret3.GetKeyValue("Password");
kv.AddLink(new LinkedKeyInfo(IFOLDER, "Password"));
kv2.AddLink(new LinkedKeyInfo(GW, "Password"));
kv2.AddLink(new LinkedKeyInfo(GWIM, "Password"));
kv3.AddLink(new LinkedKeyInfo(IFOLDER, "Password"));
kv3.AddLink(new LinkedKeyInfo(GW, "Password"));
kv.AddLink(new LinkedKeyInfo(GWIM, "Password"));
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
DoDumpLinkedKeys(ssStore, wo);
return wo;
}
private WrappedObject DoGetLinkedKeys(SecretStore ssStore, WrappedObject wo)
{
string keychainID = wo.GetKeychainID();
string secretID = wo.GetSecretID();
string keyID = wo.GetKeyID();
KeyChain keyChain = ssStore.GetKeyChain(keychainID);
Secret secret = keyChain.GetSecret(secretID);
KeyValue kv = secret.GetKeyValue(keyID);
wo.SetObject(kv.GetLinkedKeys());
wo.SetError(constants.RetCodes.SUCCESS, null);
return wo;
}
private WrappedObject DoRemoveLinkedKey(SecretStore ssStore, WrappedObject wo)
{
string keychainID = wo.GetKeychainID();
string secretID = wo.GetSecretID();
string keyID = wo.GetKeyID();
KeyChain keyChain = ssStore.GetKeyChain(keychainID);
Secret secret = keyChain.GetSecret(secretID);
KeyValue kv = secret.GetKeyValue(keyID);
LinkedKeyInfo lki = (LinkedKeyInfo)wo.GetObject();
kv.RemoveLink(lki.GetLinkID());
// remove reverse link as well
Secret targetSecret = keyChain.GetSecret(lki.GetLinkedSecretID());
KeyValue targetkv = targetSecret.GetKeyValue(lki.GetLinkedKeyID());
targetkv.RemoveLink(secretID+":"+keyID);
return wo;
}
private WrappedObject DoSetLinkedKey(SecretStore ssStore, WrappedObject wo)
{
string keychainID = wo.GetKeychainID();
string secretID = wo.GetSecretID();
string keyID = wo.GetKeyID();
KeyChain keyChain = ssStore.GetKeyChain(keychainID);
Secret secret = keyChain.GetSecret(secretID);
KeyValue kv = secret.GetKeyValue(keyID);
LinkedKeyInfo lki = (LinkedKeyInfo)wo.GetObject();
kv.AddLink(lki);
// add reverse link
try
{
Secret target = keyChain.GetSecret(lki.GetLinkedSecretID());
KeyValue targetkv = target.GetKeyValue(lki.GetLinkedKeyID());
targetkv.AddLink(new LinkedKeyInfo(secretID, keyID));
}
catch (Exception e)
{
Console.WriteLine("Reverse Link error: " + e.ToString());
wo.SetError(constants.RetCodes.FAILURE, "Reverse Link: " + e.ToString());
}
return wo;
}
private WrappedObject DoPing(WrappedObject wo)
{
Console.WriteLine("MICASAD received Ping from Client");
wo.SetError(IPCRetCodes.SSCS_REPLY_SUCCESS, null);
Ping ping = (Ping)wo.GetObject();
ping.servermessage = "MICASAD echos client message: <" + ping.clientmessage + ">";
return wo;
}
/*
internal WrappedObject ProcessMessage(WrappedObject wo, UserIdentifier userId)
{
Console.WriteLine("ObjectSerialization Called");
SecretStore ssStore = SessionManager.CreateUserSession(userId);
Secret secret;
try
{
keyChainId = wo.GetKeychainID();
secretId = wo.GetSecretID();
keyId = wo.GetKeyID();
int action = wo.GetAction();
if (action == WrappedObject.VERB_PING_MICASAD)
{
Console.WriteLine("MICASAD received Ping from Client");
wo.SetError(IPCRetCodes.SSCS_REPLY_SUCCESS, null);
Ping ping = (Ping)wo.GetObject();
ping.servermessage = "MICASAD echos client message: <" + ping.clientmessage + ">";
return wo;
}
else if (action <= WrappedObject.VERB_REMOVE_LINKED_KEY)
{
wo.SetError(IPCRetCodes.SSCS_REPLY_SUCCESS, null);
if (action == WrappedObject.VERB_GET_STORE)
{
wo.SetObject(ssStore);
return wo;
}
// look up Keychain
KeyChain keyChain = new KeyChain(keyChainId);
// temporary
try
{
if (true)
ssStore.AddKeyChain(keyChain);
}
catch (Exception e)
{
}
if( ssStore.CheckIfKeyChainExists(keyChainId) )
{
keyChain = ssStore.GetKeyChain(keyChainId);
if (action == WrappedObject.VERB_GET_KEYCHAIN)
{
wo.SetObject(keyChain);
return wo;
}
if((action == WrappedObject.VERB_GET_SECRET) && (keyChain.CheckIfSecretExists(secretId) == false))
{
wo.SetError(IPCRetCodes.SSCS_E_SECRETID_DOES_NOT_EXIST, null);
return wo;
}
else
{
secret = keyChain.GetSecret(secretId);
if (action == WrappedObject.VERB_GET_SECRET)
{
wo.SetObject(secret);
return wo;
}
else if ((action == WrappedObject.VERB_SET_SECRET) && (null != wo.GetObject()))
{
keyChain.AddSecret((Secret)wo.GetObject());
}
else if (action == WrappedObject.VERB_SET_LINKED_KEY)
{
KeyValue kv = secret.GetKeyValue(keyId);
LinkedKeyInfo lki = (LinkedKeyInfo)wo.GetObject();
kv.AddLink(lki);
// add reverse link
try
{
Secret target = keyChain.GetSecret(lki.GetLinkedSecretID());
KeyValue targetkv = target.GetKeyValue(lki.GetLinkedKeyID());
targetkv.AddLink(new LinkedKeyInfo(secretId, keyId));
}
catch (Exception e)
{
Console.WriteLine("Reverse Link error: " + e.ToString());
}
}
}
}
else
{
wo.SetError(IPCRetCodes.SSCS_E_KEYCHAIN_DOES_NOT_EXIST, null);
}
}
else
{
wo.SetError(IPCRetCodes.SSCS_E_SYSTEM_ERROR, "Action not supported");
}
}
catch (Exception e)
{
String error = e.ToString();
Console.WriteLine(error);
wo = new WrappedObject(constants.RetCodes.FAILURE, error);
}
return wo;
}
*/
public string GetVerbName()
{
CSSSLogger.ExecutionTrace(this);
return this.ToString();
}
}
}

View File

@@ -0,0 +1,127 @@
using System;
using System.Collections;
using System.Text;
using System.Threading;
using sscs.verbs;
using sscs.cache;
using sscs.common;
using sscs.constants;
namespace sscs.verbs
{
/*
* This class is implementation of OpenSecretStore call.
* There will be one instance existing for every call made by the client.
*/
internal class OpenSecretStore : SSVerb
{
ushort msgId = 0;
uint inMsgLen = 0;
uint outMsgLen = 0;
uint ssVersion = 0;
uint ssNameLen = 0;
private string ssName; //Name of SecretStore to open
private byte[] inBuf;
private byte[] outBuf;
int retCode = 0;
/*
* This method sets the class member with the byte array received.
*/
public void SetMessageContent(byte[] ipcBytes)
{
CSSSLogger.ExecutionTrace(this);
inBuf = ipcBytes;
}
/*
* This method does the actual implementation of OpenSecretStore
*
*/
public byte[] ProcessRequest(UserIdentifier userId)
{
/* If an exception occurs in message format decoding,
* it is handled by AppHandler
*/
CSSSLogger.ExecutionTrace(this);
msgId = BitConverter.ToUInt16(inBuf,0);
inMsgLen = BitConverter.ToUInt32(inBuf,2);
if( inMsgLen != inBuf.Length )
throw new FormatException(" MsgLen sent does not match the length of the message received.");
ssVersion = BitConverter.ToUInt32(inBuf,6);
ssNameLen = BitConverter.ToUInt32(inBuf,10);
byte[] tempArr = new byte[ssNameLen];
Array.Copy(inBuf,14,tempArr,0,ssNameLen);
ssName = Encoding.UTF8.GetString(tempArr);
try
{
SecretStore ss = SessionManager.CreateUserSession(userId);
if( null == ss )
{
CSSSLogger.DbgLog("In " + CSSSLogger.GetExecutionPath(this) + " SecretStore instance is null");
retCode = IPCRetCodes.SSCS_E_SYSTEM_ERROR;
}
else
{
CSSSLogger.DbgLog("In " + CSSSLogger.GetExecutionPath(this) + " + - Created a new Session entry");
}
}
catch(Exception e)
{
CSSSLogger.ExpLog(e.ToString());
retCode = IPCRetCodes.SSCS_E_SYSTEM_ERROR;
}
try
{
msgId = 1;
outMsgLen = 14;
outBuf = new byte[14];
byte[] t = new byte[10];
t = BitConverter.GetBytes((ushort)msgId);
Array.Copy(t,0,outBuf,0,2);
t = BitConverter.GetBytes((uint)outMsgLen);
Array.Copy(t,0,outBuf,2,4);
t = BitConverter.GetBytes((uint)ssVersion);
Array.Copy(t,0,outBuf,6,4);
t = BitConverter.GetBytes(retCode);
Array.Copy(t,0,outBuf,10,4);
}
catch(Exception e)
{
CSSSLogger.ExpLog(e.ToString());
throw new FormatException("Unable to form the response " + e.ToString());
}
return outBuf;
}
/*
* Gives the name of operation performed. Will be used in case
* of error.
*/
public string GetVerbName()
{
CSSSLogger.ExecutionTrace(this);
return this.ToString();
}
}
}

Some files were not shown because too many files have changed in this diff Show More