2008-11-17 18:29:00 -05:00
|
|
|
// ----------------------------------------------------------------------------
|
2008-03-05 09:52:00 -05:00
|
|
|
//
|
|
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
|
|
//
|
2008-11-17 18:29:00 -05:00
|
|
|
// ----------------------------------------------------------------------------
|
2008-03-05 09:52:00 -05:00
|
|
|
|
|
|
|
namespace Microsoft.Singularity.Security
|
|
|
|
{
|
|
|
|
using System;
|
|
|
|
using System.Collections;
|
|
|
|
using System.Text;
|
|
|
|
using System.Threading;
|
|
|
|
|
|
|
|
using Microsoft.Contracts;
|
|
|
|
using Microsoft.SingSharp;
|
|
|
|
using Microsoft.Singularity;
|
|
|
|
using Microsoft.Singularity.Channels;
|
|
|
|
using Microsoft.Singularity.Directory;
|
|
|
|
using Microsoft.Singularity.Security;
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// The implementation of the <code>SecurityService</code> state machine.
|
|
|
|
/// </summary>
|
|
|
|
public class SecurityDiagnostics
|
|
|
|
{
|
|
|
|
/// <summary>
|
|
|
|
/// The exporting endpoint of the security service.
|
|
|
|
/// </summary>
|
|
|
|
private TRef<ServiceProviderContract.Exp:Start> channel;
|
|
|
|
private bool run = true;
|
|
|
|
|
|
|
|
private ArrayList! coreList;
|
|
|
|
|
|
|
|
public SecurityDiagnostics()
|
|
|
|
{
|
|
|
|
coreList = new ArrayList();
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Starts the service and registers it in the namespace
|
|
|
|
/// </summary>
|
|
|
|
public void Start()
|
|
|
|
{
|
|
|
|
DebugStub.WriteLine("Starting the Security Diagnostics provider");
|
|
|
|
|
|
|
|
// register the service with the namespace
|
|
|
|
ServiceProviderContract.Imp! nsImp;
|
|
|
|
ServiceProviderContract.Exp! nsExp;
|
|
|
|
ServiceProviderContract.NewChannel(out nsImp, out nsExp);
|
|
|
|
|
|
|
|
DirectoryServiceContract.Imp epNS = DirectoryService.NewClientEndpoint();
|
|
|
|
|
|
|
|
try {
|
|
|
|
epNS.SendRegister(Bitter.FromString2(SecurityDiagnosticsContract.ModuleName), nsImp);
|
|
|
|
|
|
|
|
switch receive {
|
|
|
|
case epNS.AckRegister() :
|
|
|
|
// All is well.
|
|
|
|
break;
|
|
|
|
case epNS.NakRegister(ServiceProviderContract.Imp:Start rejectedEP, ErrorCode error) :
|
|
|
|
// All is very much not well; abort.
|
|
|
|
DebugStub.WriteLine("Failed to register the Security Service under: {0}",
|
|
|
|
__arglist(SecurityDiagnosticsContract.ModuleName));
|
|
|
|
delete nsExp;
|
|
|
|
delete rejectedEP;
|
|
|
|
throw new Exception("Failed to register the Security Diagnostics provider");
|
|
|
|
case epNS.ChannelClosed():
|
|
|
|
delete nsExp;
|
|
|
|
DebugStub.WriteLine(
|
|
|
|
"Failed to register the Security Diagnostics provider under: {0}",
|
|
|
|
__arglist(SecurityDiagnosticsContract.ModuleName));
|
|
|
|
throw new Exception("Failed to register the Security Diagnostics provider");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
finally {
|
|
|
|
delete epNS;
|
|
|
|
}
|
|
|
|
|
|
|
|
channel = new TRef<ServiceProviderContract.Exp:Start>(nsExp);
|
|
|
|
|
|
|
|
Thread thread = Thread.CreateThread(((!)Thread.CurrentThread).Process,
|
|
|
|
new ThreadStart(StateMachine));
|
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
if (thread != null) {
|
2008-03-05 09:52:00 -05:00
|
|
|
thread.Start();
|
|
|
|
}
|
2008-11-17 18:29:00 -05:00
|
|
|
else {
|
2008-03-05 09:52:00 -05:00
|
|
|
throw new Exception("Could not create worker thread");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public void RegisterAclCore(AclCore core)
|
|
|
|
{
|
|
|
|
//*** need locking here, but it doesn't work for now
|
|
|
|
//we're called at the wrong point in the init sequence
|
|
|
|
coreList.Add(core);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// State machine for the security namespace
|
|
|
|
/// </summary>
|
|
|
|
private void StateMachine()
|
|
|
|
requires this.channel != null;
|
|
|
|
{
|
|
|
|
// get the endpoint and start listening
|
|
|
|
ServiceProviderContract.Exp! exp = channel.Acquire();
|
|
|
|
// the clients
|
|
|
|
ESet<SecurityDiagnosticsContract.Exp, SecurityDiagnosticsContract.ReadyState> clients =
|
|
|
|
new ESet<SecurityDiagnosticsContract.Exp, SecurityDiagnosticsContract.ReadyState>();
|
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
while (run) {
|
|
|
|
switch receive {
|
2008-03-05 09:52:00 -05:00
|
|
|
case exp.Connect(ServiceContract.Exp:Start! epClient):
|
|
|
|
{
|
|
|
|
// incoming bind request: always grant, anyone should be able to talk to us
|
|
|
|
SecurityDiagnosticsContract.Exp client =
|
|
|
|
epClient as SecurityDiagnosticsContract.Exp;
|
2008-11-17 18:29:00 -05:00
|
|
|
if (client == null) {
|
2008-03-05 09:52:00 -05:00
|
|
|
exp.SendNackConnect(epClient);
|
|
|
|
}
|
2008-11-17 18:29:00 -05:00
|
|
|
else {
|
2008-03-05 09:52:00 -05:00
|
|
|
exp.SendAckConnect();
|
|
|
|
client.SendReady();
|
|
|
|
clients.Add(client);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
case client.GetStatistics() in clients:
|
|
|
|
{
|
|
|
|
StringBuilder sb = new StringBuilder();
|
|
|
|
DumpAllStats(sb);
|
|
|
|
client.SendGetStatisticsAck(Bitter.FromString2(sb.ToString()));
|
|
|
|
clients.Add(client);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case client.ClearStatistics() in clients:
|
|
|
|
{
|
|
|
|
ClearAllStats();
|
|
|
|
client.SendAck();
|
|
|
|
clients.Add(client);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case client.Disable(bool yes) in clients:
|
|
|
|
{
|
|
|
|
DisableAll(yes);
|
|
|
|
client.SendAck();
|
|
|
|
clients.Add(client);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case client.FlushCaches() in clients:
|
|
|
|
{
|
|
|
|
FlushAllCaches();
|
|
|
|
client.SendAck();
|
|
|
|
clients.Add(client);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case client.ChannelClosed() in clients:
|
|
|
|
{
|
|
|
|
delete client;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case exp.ChannelClosed():
|
|
|
|
{
|
|
|
|
run = false;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
delete exp;
|
|
|
|
clients.Dispose();
|
|
|
|
}
|
|
|
|
|
|
|
|
private void DisableAll(bool value) {
|
|
|
|
lock (coreList) {
|
2008-11-17 18:29:00 -05:00
|
|
|
for (int i = 0; (i < coreList.Count); i++) {
|
2008-03-05 09:52:00 -05:00
|
|
|
AclCore core = (AclCore!) coreList[i];
|
|
|
|
core.Disable = value;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private void DumpAllStats(StringBuilder! sb)
|
|
|
|
{
|
|
|
|
lock (coreList) {
|
2008-11-17 18:29:00 -05:00
|
|
|
for (int i = 0; (i < coreList.Count); i++) {
|
2008-03-05 09:52:00 -05:00
|
|
|
AclCore core = (AclCore!) coreList[i];
|
|
|
|
core.DumpStats(sb);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private void ClearAllStats()
|
|
|
|
{
|
|
|
|
lock (coreList) {
|
2008-11-17 18:29:00 -05:00
|
|
|
for (int i = 0; (i < coreList.Count); i++) {
|
2008-03-05 09:52:00 -05:00
|
|
|
AclCore core = (AclCore!) coreList[i];
|
|
|
|
core.ClearStats();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private void FlushAllCaches()
|
|
|
|
{
|
|
|
|
lock (coreList) {
|
2008-11-17 18:29:00 -05:00
|
|
|
for (int i = 0; (i < coreList.Count); i++) {
|
2008-03-05 09:52:00 -05:00
|
|
|
AclCore core = (AclCore!) coreList[i];
|
|
|
|
core.FlushCache();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|