//////////////////////////////////////////////////////////////////////////////// // // 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, } }