From 04fb478810e6e269d327d97b1489cc1d05e162d9 Mon Sep 17 00:00:00 2001 From: Jim Norman Date: Tue, 1 Apr 2008 21:06:24 +0000 Subject: [PATCH] Bug 369296. Zen/Security issue. Adding global config setting support. --- CASA/micasad/common/CSSSUtils.cs | 80 +-- CASA/micasad/common/Config.cs | 216 ++++++ CASA/micasad/common/Constants.cs | 6 +- .../init/WinSecretStoreClientService.cs | 620 +++++++++--------- 4 files changed, 547 insertions(+), 375 deletions(-) create mode 100644 CASA/micasad/common/Config.cs diff --git a/CASA/micasad/common/CSSSUtils.cs b/CASA/micasad/common/CSSSUtils.cs index a6988958..37d433d1 100644 --- a/CASA/micasad/common/CSSSUtils.cs +++ b/CASA/micasad/common/CSSSUtils.cs @@ -38,81 +38,37 @@ namespace sscs.common { #if W32 - private static string CASA_REG_KEY = "SOFTWARE\\Novell\\CASA"; + private static string CASA_REG_KEY = "SOFTWARE\\Novell\\CASA"; - private static bool IsRegKeySet(string sPath, string sValue) - { - Microsoft.Win32.RegistryKey key; - try - { - key = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(sPath); - int iValue = (int)key.GetValue(sValue); - key.Close(); - if (iValue > 0) - { - return true; - } - } - catch (Exception e) - { - - } - return false; - } - internal static void SetAllowDesktopAccess() - { - // create a reg key - System.Diagnostics.Trace.WriteLine("CASA installer: SetAllowDesktopAccess start"); - try - { - Microsoft.Win32.RegistryKey key; - key = Microsoft.Win32.Registry.LocalMachine.CreateSubKey(CASA_REG_KEY); - key.SetValue("CacheDesktopPassword", 1, Microsoft.Win32.RegistryValueKind.DWord); - key.Close(); - } - catch (Exception e) - { - System.Diagnostics.Trace.WriteLine(e.ToString()); - } - - System.Diagnostics.Trace.WriteLine("CASA installer: SetAllowDesktopAccess done"); - } - - internal static void RemoveGlobalCASASettings() - { - // Delete CASA settings - try - { - Microsoft.Win32.Registry.LocalMachine.DeleteSubKeyTree(CASA_REG_KEY); - } - catch (Exception e) - { - System.Diagnostics.Debug.WriteLine(e.ToString()); - } - } #endif public static bool StoreDesktopPasswordInCache() { -#if LINUX - return true; -#else - return IsRegKeySet(CASA_REG_KEY, "CacheDesktopPassword"); -#endif + if (Config.GetGlobalConfigSetting("CacheDesktopPassword", "false").Equals("true")) + { + return true; + } + else + { + return false; + } } public static bool UseMasterPassword() { -#if LINUX - return true; -#else - //return false; - return IsRegKeySet(CASA_REG_KEY, "UseMasterPassword"); -#endif + if (Config.GetGlobalConfigSetting("UserMasterPassword", "false").Equals("true")) + { + return true; + } + else + { + return false; + } + } public static bool IsFileOwnedByRoot(string filePath) diff --git a/CASA/micasad/common/Config.cs b/CASA/micasad/common/Config.cs new file mode 100644 index 00000000..729b044c --- /dev/null +++ b/CASA/micasad/common/Config.cs @@ -0,0 +1,216 @@ +using System; +using System.Text; +using System.Collections; +using System.Collections.Specialized; +using System.IO; +using System.Xml; +using System.Xml.Serialization; + +using sscs.constants; + +namespace sscs.common +{ + class Config + { + private static string CASA_REG_KEY = "SOFTWARE\\Novell\\CASA"; + private static NameValueCollection m_nvc; + + public Config() + { + LoadConfigSettings(); + } + + public static void SetGlobalConfigSetting(string sName, string sValue) + { + if (m_nvc == null) + { + m_nvc = new NameValueCollection(); + } + m_nvc.Set(sName, sValue); + } + + public static string GetGlobalConfigSetting(string sName) + { + return GetGlobalConfigSetting(sName, null); + } + + public static string GetGlobalConfigSetting(string sName, string sDefaultValue) + { + string sValue = null; + + if (m_nvc == null) + { + LoadConfigSettings(); + } + + if (m_nvc != null) + { + sValue = m_nvc.Get(sName); + } + + if (sValue == null) + { + ReadRegSetting(sName); + sValue = sDefaultValue; + } + + return sValue; + + } + + public static void WriteGlobalConfig() + { +#if LINUX + XmlDocument doc = new XmlDocument(); + AppendToDoc(doc); + + XmlTextWriter writer = new XmlTextWriter(GetGlobalConfPath(), null); + writer.Formatting = Formatting.Indented; + doc.Save(writer); + writer.Close(); +#else + // Write to windows registry + for (int i = 0; i < m_nvc.Count; i++) + { + WriteRegSetting(m_nvc.GetKey(i), m_nvc.GetValues(i)[0]); + } +#endif + } + +#if W32 + + internal static void SetAllowDesktopAccess() + { + // create a reg key + System.Diagnostics.Trace.WriteLine("CASA installer: SetAllowDesktopAccess start"); + WriteRegSetting("CacheDesktopPassword", "true"); + System.Diagnostics.Trace.WriteLine("CASA installer: SetAllowDesktopAccess done"); + } + + internal static void WriteRegSetting(string sSubKey, string sValue) + { + try + { + Microsoft.Win32.RegistryKey key; + key = Microsoft.Win32.Registry.LocalMachine.CreateSubKey(CASA_REG_KEY); + key.SetValue(sSubKey, sValue, Microsoft.Win32.RegistryValueKind.String); + key.Close(); + } + catch (Exception e) + { + System.Diagnostics.Trace.WriteLine(e.ToString()); + } + } + + internal static string ReadRegSetting(string sSubKey) + { + string sValue = null; + try + { + Microsoft.Win32.RegistryKey key; + key = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(CASA_REG_KEY); + if (key != null) + { + sValue = (string)key.GetValue(sSubKey); + } + key.Close(); + } + catch + { + } + return sValue; + } +#endif + + internal static void RemoveGlobalCASASettings() + { +#if W32 + // Delete CASA settings + try + { + Microsoft.Win32.Registry.LocalMachine.DeleteSubKeyTree(CASA_REG_KEY); + } + catch (Exception e) + { + System.Diagnostics.Debug.WriteLine(e.ToString()); + } +#endif + } + + + + internal static string GetGlobalConfPath() + { +#if LINUX + // Does directory exist? + if (!Directory.Exists(ConstStrings.SSCS_LINUX_GLOBAL_CONF_PATH)) + { + Directory.CreateDirectory(ConstStrings.SSCS_LINUX_GLOBAL_CONF_PATH); + } + return ConstStrings.SSCS_LINUX_GLOBAL_CONF_PATH + ConstStrings.SSCS_GLOBAL_CONF_FILE; +#else + return ConstStrings.SSCS_GLOBAL_CONF_FILE; +#endif + + } + + internal static void AppendToDoc(XmlDocument doc) + { + try{ + XmlElement configElem = doc.CreateElement("ConfigSettings"); + doc.AppendChild(configElem); + + for (int i = 0; i < m_nvc.Count; i++) + { + XmlElement settingElem = doc.CreateElement("Setting"); + configElem.AppendChild(settingElem); + + XmlElement nameElem = doc.CreateElement("Name"); + nameElem.InnerText = m_nvc.GetKey(i); + settingElem.AppendChild(nameElem); + + XmlElement valueElem = doc.CreateElement("Value"); + valueElem.InnerXml = m_nvc.GetValues(i)[0]; + settingElem.AppendChild(valueElem); + } + } + catch (Exception) + { + //Console.WriteLine(e.ToString()); + } + } + + internal static void LoadConfigSettings() + { + string sGlobalConfPath = GetGlobalConfPath(); + if (File.Exists(sGlobalConfPath)) + { + XmlDocument doc = new XmlDocument(); + doc.Load(sGlobalConfPath); + + // Load config settings + System.Collections.Specialized.NameValueCollection nvc = new System.Collections.Specialized.NameValueCollection(); + XmlNode configNode = doc.SelectSingleNode("//ConfigSettings"); + if (configNode != null) + { + XmlNodeList nodeList = configNode.ChildNodes; + XmlNode setting; + + for (int i = 0; i < nodeList.Count; i++) + { + setting = nodeList[i]; + XmlNode nameNode = setting.SelectSingleNode("Name"); + XmlNode valueNode = setting.SelectSingleNode("Value"); + + nvc.Add(nameNode.InnerText, valueNode.InnerText); + } + } + + if (nvc.Count > 0) + { + m_nvc = nvc; + } + } + } + } +} diff --git a/CASA/micasad/common/Constants.cs b/CASA/micasad/common/Constants.cs index 6ac604b0..8049a7cb 100644 --- a/CASA/micasad/common/Constants.cs +++ b/CASA/micasad/common/Constants.cs @@ -102,8 +102,10 @@ namespace sscs.constants //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 string SSCS_LINUX_PIDFILE = "/var/run/micasad.pid"; + + internal static string SSCS_LINUX_GLOBAL_CONF_PATH = "/etc/opt/novell/micasa/"; + internal static string SSCS_GLOBAL_CONF_FILE = "micasad.conf.xml"; internal static bool STATUS = true; internal static bool DEBUG = false; diff --git a/CASA/micasad/init/WinSecretStoreClientService.cs b/CASA/micasad/init/WinSecretStoreClientService.cs index 4d68078d..cc07f403 100644 --- a/CASA/micasad/init/WinSecretStoreClientService.cs +++ b/CASA/micasad/init/WinSecretStoreClientService.cs @@ -20,317 +20,315 @@ * ***********************************************************************/ -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; -using sscs.winforms; - -namespace sscs.init -{ - public class WinSecretStoreClientService : System.ServiceProcess.ServiceBase - { - /// - /// Required designer variable. - /// - 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 - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - // - // SecretStoreClientService - // - this.CanHandlePowerEvent = true; - this.ServiceName = "SecretStoreService"; - - } - #endregion - - /// - /// Clean up any resources being used. - /// - protected override void Dispose( bool disposing ) - { - if( disposing ) - { - if (components != null) - { - components.Dispose(); - } - } - base.Dispose( disposing ); - } - - [STAThreadAttribute] - static void Main(string[] args) - { - string opt = null ; - if ( args.Length > 0) - { - opt = args [0]; - } - - foreach (string arg in args) - { - System.Diagnostics.Debug.WriteLine("arg: " + arg); - } - - if (opt != null && opt.ToLower() == "/hookclient") - { - CredMgr.Install("hookclient"); - return; - } - else if (opt != null && opt.ToLower() == "/install") - { - stopService(); - uninstallService(); - CredMgr.Uninstall(); - CredMgr.Install(null); - installService(); - startService(); - return; - } - else if (opt != null && opt.ToLower() == "/uninstall") - { - stopService(); - uninstallService(); - CredMgr.Uninstall(); - CSSSUtils.RemoveGlobalCASASettings(); - return; - } - else if (opt != null && opt.ToLower() == "/allowdesktopaccess") - { - CSSSUtils.SetAllowDesktopAccess(); - return; - } - +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; +using sscs.winforms; + +namespace sscs.init +{ + public class WinSecretStoreClientService : System.ServiceProcess.ServiceBase + { + /// + /// Required designer variable. + /// + 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 + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + // + // SecretStoreClientService + // + this.CanHandlePowerEvent = true; + this.ServiceName = "SecretStoreService"; + + } + #endregion + + /// + /// Clean up any resources being used. + /// + protected override void Dispose( bool disposing ) + { + if( disposing ) + { + if (components != null) + { + components.Dispose(); + } + } + base.Dispose( disposing ); + } + + [STAThreadAttribute] + static void Main(string[] args) + { + string opt = null ; + if ( args.Length > 0) + { + opt = args [0]; + } + + foreach (string arg in args) + { + System.Diagnostics.Debug.WriteLine("arg: " + arg); + } + + if (opt != null && opt.ToLower() == "/hookclient") + { + CredMgr.Install("hookclient"); + return; + } + else if (opt != null && opt.ToLower() == "/install") + { + stopService(); + uninstallService(); + CredMgr.Uninstall(); + CredMgr.Install(null); + installService(); + startService(); + return; + } + else if (opt != null && opt.ToLower() == "/uninstall") + { + stopService(); + uninstallService(); + CredMgr.Uninstall(); + Config.RemoveGlobalCASASettings(); + return; + } + else if (opt != null && opt.ToLower() == "/allowdesktopaccess") + { + Config.SetAllowDesktopAccess(); + return; + } if (opt != null - && (opt.ToLower() == "/standalone" || opt.ToLower() == "/s")) - { - 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) - { - System.Diagnostics.Debug.WriteLine(e.ToString()); - } - } - - private static void uninstallService() - { - // kill all running versions of CASA manager - Process[] proc = System.Diagnostics.Process.GetProcessesByName("CASAManager"); - for (int i = 0; i < proc.Length; i++) - { - try - { - proc[i].Kill(); - } - catch { } - } - - - 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) - { - System.Diagnostics.Debug.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) - { - try - { - x.Start(); - } - catch (Exception e) - { - System.Diagnostics.Trace.WriteLine(e.ToString()); - System.Diagnostics.Trace.WriteLine(e.StackTrace.ToString()); - } - } - } - } - } - - - /// - /// Set things in motion so your service can do its work. - /// - /// - protected override void OnStart(string[] args) - { - AcquireLock(); - - server = CommunicationFactory.CreateCommunicationEndPoint(); - - listeningThread = new Thread(new ThreadStart(StartServer)); - listeningThread.Start(); - //listeningThread.Join(); - } - - /// - /// Stop this service. - /// - 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."); - - if (true) - { - System.Windows.Forms.Application.Run(new MiCasaForm(args)); - System.Windows.Forms.Application.Exit(); - } - else - { - server = CommunicationFactory.CreateCommunicationEndPoint(); - - listeningThread = new Thread(new ThreadStart(StartServer)); - listeningThread.Start(); - listeningThread.Join(); - } - - } - catch(Exception) - { -// Terminate(); - } - } - - /* The thread which listens and spawns threads on every accept - * starts its execution from this method. - */ - - } -} + && (opt.ToLower() == "/standalone" || opt.ToLower() == "/s")) + { + 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) + { + System.Diagnostics.Debug.WriteLine(e.ToString()); + } + } + + private static void uninstallService() + { + // kill all running versions of CASA manager + Process[] proc = System.Diagnostics.Process.GetProcessesByName("CASAManager"); + for (int i = 0; i < proc.Length; i++) + { + try + { + proc[i].Kill(); + } + catch { } + } + + + 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) + { + System.Diagnostics.Debug.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) + { + try + { + x.Start(); + } + catch (Exception e) + { + System.Diagnostics.Trace.WriteLine(e.ToString()); + System.Diagnostics.Trace.WriteLine(e.StackTrace.ToString()); + } + } + } + } + } + + + /// + /// Set things in motion so your service can do its work. + /// + /// + protected override void OnStart(string[] args) + { + AcquireLock(); + + server = CommunicationFactory.CreateCommunicationEndPoint(); + + listeningThread = new Thread(new ThreadStart(StartServer)); + listeningThread.Start(); + //listeningThread.Join(); + } + + /// + /// Stop this service. + /// + 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."); + + if (true) + { + System.Windows.Forms.Application.Run(new MiCasaForm(args)); + System.Windows.Forms.Application.Exit(); + } + else + { + server = CommunicationFactory.CreateCommunicationEndPoint(); + + listeningThread = new Thread(new ThreadStart(StartServer)); + listeningThread.Start(); + listeningThread.Join(); + } + + } + catch(Exception) + { +// Terminate(); + } + } + + /* The thread which listens and spawns threads on every accept + * starts its execution from this method. + */ + + } +}