////////////////////////////////////////////////////////////////////////////////
//
// Microsoft Research Singularity
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// File:
//
// Note:
//
using System;
using Microsoft.Contracts;
using Microsoft.Singularity;
using Microsoft.Singularity.Channels;
using Microsoft.Singularity.Directory;
using Microsoft.SingSharp;
namespace Microsoft.Singularity.Security
{
// This structure describes a "protocol context" or a "protocol tuple".
// This captures (roughly) the parameters that are relevant to security
// that a client application uses.
//
public rep struct ProtocolTuple : ITracked
{
// The protocol that is specific to the application in question.
// For example, "smb" or "http" or "ftp".
public char[]! in ExHeap ApplicationProtocol;
// The address of the remote service or application, who will be
// authenticating the client application. In this context, "address"
// can be any protocol-specific identifier of a remote peer.
// This includes addresses such as DNS names, IPv4 and IPv6 addresses,
// converted to text.
// For example, "products.redmond.corp.microsoft.com" or "192.168.1.1"
// or any other protocol-specific identifier of a remote principal.
public char[]! in ExHeap ServiceAddress;
// The security protocol that the client wishes to use.
// For example, "ntlm" or "kerberos" or "spnego".
public char[]! in ExHeap AuthenticationProtocol;
// The name of the remote security realm. For NTLM, this is a domain name,
// e.g. "redmond". For Kerberos, this is a domain name, e.g.
// "redmond.corp.microsoft.com".
public char[]! in ExHeap Realm;
}
public rep struct CredentialsId : ITracked
{
public char[]! in ExHeap CredentialsName;
public char[]! in ExHeap Tag;
}
public rep struct ProtocolMapping : ITracked
{
public ProtocolTuple ProtocolTuple;
public CredentialsId CredentialsId;
}
public contract CredentialsManagerContract : ServiceContract
{
public const string ChannelPath = "/dev/credentials-manager";
public const string ProtocolFieldWildcard = "*";
//
// Adds the specified credentials to the credentials store.
//
// The tag value can be used to disambiguate different instances of the same credentials.
// For example, the username ".\Administrator" might be used at three different machines,
// each of which have different passwords. If the tag value is null, it is treated as
// an empty string.
//
in message AddCredentials(CredentialsId id, char[]! in ExHeap password, bool replace);
//
// Removes the specified credentials from the credentials store. The username and tag
// value must match exactly the values provided previously in a call to AddCredentials.
// If the tag value is null, it is treated as an empty string.
//
in message DeleteCredentials(CredentialsId id);
//
// Deletes all credentials in the credentials store.
//
in message DeleteAllCredentials();
//
// Enumerates the list of all credentials in the credentials store.
//
in message EnumerateCredentials();
out message CredentialsList(CredentialsId[]! in ExHeap list);
//
// Adds a new mapping of a protocol tuple to credentials.
//
// Some of the fields of the protocol mapping ID support wildcards.
// To do so, the field should be set to "*".
// This allows the protocol mapping to apply to all contexts that match.
//
in message AddProtocolMapping(ProtocolTuple tuple, CredentialsId credentials, bool replace);
//
// Deletes a specific protocol mapping. The protocol mapping ID must match
// exactly an entry previously added using the AddProtocolMapping request.
// Wildcards (fields using "*") are not interpreted.
//
in message DeleteProtocolMapping(ProtocolTuple tuple);
//
// Deletes all protocol mappings.
//
in message DeleteAllProtocolMappings();
//
// Searches the set of all protocol mappings for an entry that best matches
// a specific protocol mapping.
//
in message FindMatchingProtocolMapping(ProtocolTuple tuple, bool useWildcards);
out message NoMatchingProtocolMapping();
out message MatchingProtocolMapping(CredentialsId credentials);
//
// Queries the list of all protocol mappings.
//
in message EnumerateProtocolMappings();
out message ProtocolMappings(ProtocolMapping[]! in ExHeap mappings);
// This message requests that the credentials manager create an instance of a security
// protocol (identified by name), using the endpoint provided by the import holder.
// This allows the import holder to choose the channel contract, which allows a
// single protocol implementation to support more than one channel contract.
// In response to this request, the credentials manager creates an instance of the
// protocol (if possible).
in message CreateSupplicant(
char[]! in ExHeap authenticationProtocol,
CredentialsId credentials,
ServiceContract.Exp:Start! exp);
// This request is similar to CreateSupplicant, but it also performs a protocol
// tuple look-up, since this is anticipated to be a common usage of the CM.
in message CreateSupplicantForProtocol(
ProtocolTuple protocol,
ServiceContract.Exp:Start! exp);
out message AckCreateSupplicantForProtocol(CredentialsId credentialsSelected);
// Generic response messages.
// These are used when there is no request-specific data to return.
out message Ok();
out message RequestFailed(CredError error);
out message Success();
override state Start : one
{
Success! -> Ready;
}
state Ready : one
{
AddCredentials? -> (Ok! or RequestFailed!) -> Ready;
DeleteCredentials? -> (Ok! or RequestFailed!) -> Ready;
DeleteAllCredentials? -> (Ok! or RequestFailed!) -> Ready;
EnumerateCredentials? -> (CredentialsList! or RequestFailed!) -> Ready;
EnumerateProtocolMappings? -> (ProtocolMappings! or RequestFailed!) -> Ready;
FindMatchingProtocolMapping? -> (MatchingProtocolMapping! or RequestFailed!) -> Ready;
AddProtocolMapping? -> (Ok! or RequestFailed!) -> Ready;
DeleteProtocolMapping? -> (Ok! or RequestFailed!) -> Ready;
DeleteAllProtocolMappings? -> (Ok! or RequestFailed!) -> Ready;
CreateSupplicant? -> (Ok! or RequestFailed!) -> Ready;
CreateSupplicantForProtocol? -> (AckCreateSupplicantForProtocol! or RequestFailed!) -> Ready;
}
}
/// Strings that are appropriate for passing to CreateSupplicant.
public sealed /* static */ class AuthenticationProtocolNames
{
public const string Ntlm = "ntlm";
// not yet implemented
public const string Kerberos = "kerberos";
// not yet implemented
public const string HttpMD5 = "http-md5";
}
/// Error codes for the requests of the CredentialsManagerContract.
public enum CredError
{
NoError = 0,
InternalError,
NoMatchingCredentials,
NoMatchingAuthenticationProtocol,
NoEntryFound,
ContractNotSupported,
MatchingEntryExists,
InvalidArguments,
EvidenceTypeNotSupported,
}
}