Moving micasa 1.5 trunk to Novell forge.
This commit is contained in:
80
c_micasad/common/CSSSException.cs
Normal file
80
c_micasad/common/CSSSException.cs
Normal 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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
211
c_micasad/common/CSSSLogger.cs
Normal file
211
c_micasad/common/CSSSLogger.cs
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
125
c_micasad/common/Constants.cs
Normal file
125
c_micasad/common/Constants.cs
Normal 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";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
97
c_micasad/common/RequestParser.cs
Normal file
97
c_micasad/common/RequestParser.cs
Normal 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]));
|
||||
}
|
||||
}
|
||||
}
|
||||
343
c_micasad/common/SessionManager.cs
Normal file
343
c_micasad/common/SessionManager.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
42
c_micasad/common/UnixUser.cs
Normal file
42
c_micasad/common/UnixUser.cs
Normal 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);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
36
c_micasad/common/UnixUserIdentifier.cs
Normal file
36
c_micasad/common/UnixUserIdentifier.cs
Normal 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
49
c_micasad/common/User.cs
Normal 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;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
12
c_micasad/common/UserIdentifier.cs
Normal file
12
c_micasad/common/UserIdentifier.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace sscs.common
|
||||
{
|
||||
public interface UserIdentifier
|
||||
{
|
||||
void PrintIdentifier();
|
||||
int GetUID();
|
||||
|
||||
}
|
||||
}
|
||||
92
c_micasad/common/WinUser.cs
Normal file
92
c_micasad/common/WinUser.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
51
c_micasad/common/WinUserIdentifier.cs
Normal file
51
c_micasad/common/WinUserIdentifier.cs
Normal 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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user