major source structure and module name changes
This commit is contained in:
125
micasad/init/AppHandler.cs
Normal file
125
micasad/init/AppHandler.cs
Normal file
@@ -0,0 +1,125 @@
|
||||
/***********************************************************************
|
||||
*
|
||||
* Copyright (C) 2005-2006 Novell, Inc. All Rights Reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, Novell, Inc.
|
||||
*
|
||||
* To contact Novell about this file by physical or electronic mail,
|
||||
* you may find current contact information at www.novell.com.
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
|
||||
using System;
|
||||
using System.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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
139
micasad/init/CredMgr.cs
Normal file
139
micasad/init/CredMgr.cs
Normal file
@@ -0,0 +1,139 @@
|
||||
/***********************************************************************
|
||||
*
|
||||
* Copyright (C) 2005-2006 Novell, Inc. All Rights Reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, Novell, Inc.
|
||||
*
|
||||
* To contact Novell about this file by physical or electronic mail,
|
||||
* you may find current contact information at www.novell.com.
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace sscs.init
|
||||
{
|
||||
/// <summary>
|
||||
/// Summary description for RegCredMgr.
|
||||
/// </summary>
|
||||
public class CredMgr
|
||||
{
|
||||
public CredMgr()
|
||||
{
|
||||
}
|
||||
|
||||
public static void Install()
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine("CASA: attempting to register lcredmgr");
|
||||
string sExePath = GetRegSvrPath();
|
||||
if (sExePath != null)
|
||||
{
|
||||
string sCredMgrPath = GetCredMgrPath();
|
||||
if (sCredMgrPath != null)
|
||||
{
|
||||
RunProcess(sExePath, "/i /n /s " + "\"" + sCredMgrPath + "\"");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void Uninstall()
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine("CASA: attempting to unregister lcredmgr");
|
||||
string sExePath = GetRegSvrPath();
|
||||
if (sExePath != null)
|
||||
{
|
||||
string sCredMgrPath = GetCredMgrPath();
|
||||
if (sCredMgrPath != null)
|
||||
{
|
||||
RunProcess(sExePath, "/u /s " + "\"" + sCredMgrPath + "\"");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private static void RunProcess(string sProcess, string sArgs)
|
||||
{
|
||||
if (sProcess != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
Process myProcess = new Process();
|
||||
ProcessStartInfo myProcessStartInfo = new ProcessStartInfo(sProcess);
|
||||
|
||||
if (sArgs != null)
|
||||
myProcessStartInfo.Arguments = sArgs;
|
||||
|
||||
myProcessStartInfo.UseShellExecute = false;
|
||||
myProcess.StartInfo = myProcessStartInfo;
|
||||
myProcess.Start();
|
||||
myProcess.WaitForExit();
|
||||
System.Diagnostics.Debug.WriteLine("Completed " + myProcess.ExitCode.ToString());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine(e.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static string GetRegSvrPath()
|
||||
{
|
||||
string sPath = Environment.GetEnvironmentVariable("SystemRoot");
|
||||
if (sPath != null)
|
||||
{
|
||||
// look for regsvr32.exe
|
||||
if (File.Exists(sPath + "\\system32\\regsvr32.exe"))
|
||||
{
|
||||
return (sPath + "\\system32\\regsvr32.exe");
|
||||
}
|
||||
else
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine("Did not find regsvr32.exe");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine("Did not find System path");
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
private static string GetCredMgrPath()
|
||||
{
|
||||
string sPath = Environment.GetEnvironmentVariable("ProgramFiles");
|
||||
if (sPath != null)
|
||||
{
|
||||
// look for regsvr32.exe
|
||||
if (File.Exists(sPath + "\\Novell\\CASA\\bin\\lcredmgr.dll"))
|
||||
{
|
||||
return (sPath + "\\Novell\\CASA\\bin\\lcredmgr.dll");
|
||||
}
|
||||
else
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine("Did not find lcredmgr.dll");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine("Did not find path to [ProgramFiles]");
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
227
micasad/init/Main.cs
Normal file
227
micasad/init/Main.cs
Normal file
@@ -0,0 +1,227 @@
|
||||
/***********************************************************************
|
||||
*
|
||||
* Copyright (C) 2005-2006 Novell, Inc. All Rights Reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, Novell, Inc.
|
||||
*
|
||||
* To contact Novell about this file by physical or electronic mail,
|
||||
* you may find current contact information at www.novell.com.
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
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.Native.Syscall.exit(-1);
|
||||
}
|
||||
|
||||
RegisterSignals();
|
||||
Mono.Unix.Native.Syscall.umask( Mono.Unix.Native.FilePermissions.S_IRGRP |
|
||||
Mono.Unix.Native.FilePermissions.S_IWGRP |
|
||||
Mono.Unix.Native.FilePermissions.S_IROTH |
|
||||
Mono.Unix.Native.FilePermissions.S_IWOTH);
|
||||
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.Native.Stdlib.signal(Mono.Unix.Native.Signum.SIGTERM, new Mono.Unix.Native.SignalHandler(Terminate));
|
||||
//SIGINT
|
||||
Mono.Unix.Native.Stdlib.signal(Mono.Unix.Native.Signum.SIGINT, new Mono.Unix.Native.SignalHandler(Terminate));
|
||||
//SIGHUP
|
||||
Mono.Unix.Native.Stdlib.signal(Mono.Unix.Native.Signum.SIGHUP, new Mono.Unix.Native.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.Native.Syscall.exit(0);
|
||||
}
|
||||
}
|
||||
private static void CreatePidFile()
|
||||
{
|
||||
int pid = Mono.Unix.Native.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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
150
micasad/init/ProjectInstaller.cs
Normal file
150
micasad/init/ProjectInstaller.cs
Normal file
@@ -0,0 +1,150 @@
|
||||
/***********************************************************************
|
||||
*
|
||||
* Copyright (C) 2005-2006 Novell, Inc. All Rights Reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, Novell, Inc.
|
||||
*
|
||||
* To contact Novell about this file by physical or electronic mail,
|
||||
* you may find current contact information at www.novell.com.
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
using System;
|
||||
using System.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;
|
||||
private static string SERVICE_DESCRIPTION = "Novell Identity Store is used by CASA (Common Authentication Service Adapter) "
|
||||
+ "to encypt and store credentials entered by users. These credentials can be used to authenticate to additional network services";
|
||||
|
||||
private static string SERVICE_GROUP = "Base";
|
||||
|
||||
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)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void Install(IDictionary stateServer)
|
||||
{
|
||||
Microsoft.Win32.RegistryKey system,
|
||||
currentControlSet,
|
||||
services,
|
||||
service,
|
||||
config;
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
//Let the project installer do its job
|
||||
base.Install(stateServer);
|
||||
|
||||
//Open the HKEY_LOCAL_MACHINE\SYSTEM key
|
||||
system = Microsoft.Win32.Registry.LocalMachine.OpenSubKey("System");
|
||||
//Open CurrentControlSet
|
||||
currentControlSet = system.OpenSubKey("CurrentControlSet");
|
||||
//Go to the services key
|
||||
services = currentControlSet.OpenSubKey("Services");
|
||||
//Open the key for your service, and allow writing
|
||||
service = services.OpenSubKey(this.serviceInstaller1.ServiceName, true);
|
||||
//Add service's description as a REG_SZ value named "Description"
|
||||
service.SetValue("Description", SERVICE_DESCRIPTION);
|
||||
service.SetValue("Group", SERVICE_GROUP);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Console.WriteLine("An exception was thrown during service installation:\n" + e.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
127
micasad/init/ProjectInstaller.resx
Normal file
127
micasad/init/ProjectInstaller.resx
Normal 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>
|
||||
296
micasad/init/WinSecretStoreClientService.cs
Normal file
296
micasad/init/WinSecretStoreClientService.cs
Normal file
@@ -0,0 +1,296 @@
|
||||
/***********************************************************************
|
||||
*
|
||||
* Copyright (C) 2005-2006 Novell, Inc. All Rights Reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, Novell, Inc.
|
||||
*
|
||||
* To contact Novell about this file by physical or electronic mail,
|
||||
* you may find current contact information at www.novell.com.
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
using System;
|
||||
using System.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();
|
||||
CredMgr.Install();
|
||||
return;
|
||||
}
|
||||
else if (opt != null && opt.ToLower () == "/uninstall")
|
||||
{
|
||||
stopService();
|
||||
uninstallService();
|
||||
CredMgr.Uninstall();
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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.
|
||||
*/
|
||||
|
||||
}
|
||||
}
|
||||
109
micasad/init/WinSecretStoreClientService.resx
Normal file
109
micasad/init/WinSecretStoreClientService.resx
Normal 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>
|
||||
Reference in New Issue
Block a user