singrdk/base/Applications/CredentialsControl/CredentialsControl.sg

513 lines
20 KiB
Plaintext

////////////////////////////////////////////////////////////////////////////////
//
// Microsoft Research Singularity
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// File: Applications/CredentialsControl/CredentialsControl.sg
//
// Note: Command-line tool for controlling the Credentials Manager Service.
//
using System;
using System.Collections;
using System.Diagnostics;
using Microsoft.Contracts;
using Microsoft.Singularity;
using Microsoft.Singularity.Channels;
using Microsoft.Singularity.Directory;
using Microsoft.Singularity.Applications;
using Microsoft.Singularity.Io;
using Microsoft.Singularity.Configuration;
using Microsoft.SingSharp;
using Microsoft.SingSharp.Reflection;
using Microsoft.Singularity.Security;
[assembly: Transform(typeof(ApplicationResourceTransform))]
namespace Microsoft.Singularity.Applications
{
[ConsoleCategory(DefaultAction=true)]
internal class DefaultCommand
{
[InputEndpoint("data")]
public readonly TRef<UnicodePipeContract.Imp:READY> Stdin;
[OutputEndpoint("data")]
public readonly TRef<UnicodePipeContract.Imp:READY> Stdout;
reflective internal DefaultCommand();
internal int AppMain()
{
Console.WriteLine("Use -? for a list of commands.");
return 0;
}
}
[ConsoleCategory(Action="add", HelpMessage="Adds credentials (user id and password) to the credentials store.")]
internal class AddCredentialsCommand
{
[InputEndpoint("data")]
public readonly TRef<UnicodePipeContract.Imp:READY> Stdin;
[OutputEndpoint("data")]
public readonly TRef<UnicodePipeContract.Imp:READY> Stdout;
reflective internal AddCredentialsCommand();
[BoolParameter("replace", Mandatory=false, HelpMessage="If specified, will replace existing credentials with the same name.", Default=true)]
public bool ReplaceExistingCredentials;
[StringParameter("username", Mandatory=true, Position=0, HelpMessage="The [domain\\]username of the credentials.")]
public string UserName;
[StringParameter("password", Mandatory=true, Position=1, HelpMessage="The password for this account.")]
public string Password;
[StringParameter("tag", Mandatory=false, HelpMessage="A tag that can be used to distinguish different instances of the same account name.")]
public string Tag;
[BoolParameter("default", Mandatory=false, HelpMessage="If specified, then the credentials will be registered as the default credentials.", Default=true)]
public bool AddDefaultProtocolMapping;
internal int AppMain()
{
try
{
assert this.UserName != null;
assert this.Password != null;
if (this.Tag == null)
this.Tag = "";
CredentialsManager.AddCredentials(this.UserName, this.Tag, this.Password, this.ReplaceExistingCredentials);
Console.WriteLine("Credentials successfully added to credentials store.");
const string Wildcard = "*";
if (this.AddDefaultProtocolMapping)
{
CredentialsManager.AddProtocolMapping(
Wildcard,
Wildcard,
Wildcard,
Wildcard,
this.UserName,
this.Tag,
true);
Console.WriteLine("Default protocol mapping added.");
}
return 0;
} catch (Exception! ex) {
Util.ShowException(ex);
return -1;
}
}
}
[ConsoleCategory(Action="del", HelpMessage="Deletes credentials from the credentials store.")]
internal class DeleteCredentialsCommand
{
[InputEndpoint("data")]
public readonly TRef<UnicodePipeContract.Imp:READY> Stdin;
[OutputEndpoint("data")]
public readonly TRef<UnicodePipeContract.Imp:READY> Stdout;
reflective internal DeleteCredentialsCommand();
[StringParameter("username", Mandatory=true, Position=0, HelpMessage="The [domain\\]username of the credentials.")]
public string UserName;
[StringParameter("tag", Mandatory=false, HelpMessage="A tag that can be used to distinguish different instances of the same account name.")]
public string Tag;
internal int AppMain()
{
try {
assert this.UserName != null;
if (this.Tag == null)
this.Tag = "";
CredentialsManager.DeleteCredentials(this.UserName, this.Tag);
Console.WriteLine("Credentials deleted.");
return 0;
} catch (Exception ex) {
Util.ShowException(ex);
return -1;
}
}
}
[ConsoleCategory(Action="delall", HelpMessage="Deletes all credentials from the credentials store.")]
internal class DeleteAllCredentialsCommand
{
[InputEndpoint("data")]
public readonly TRef<UnicodePipeContract.Imp:READY> Stdin;
[OutputEndpoint("data")]
public readonly TRef<UnicodePipeContract.Imp:READY> Stdout;
reflective internal DeleteAllCredentialsCommand();
internal int AppMain()
{
try {
CredentialsManager.DeleteAllCredentials();
Console.WriteLine("All credentials deleted.");
return 0;
} catch (Exception ex) {
Util.ShowException(ex);
return -1;
}
}
}
[ConsoleCategory(Action="list", HelpMessage="Shows a list of the credentials in the credentials store.")]
internal class ListCredentialsCommand
{
[InputEndpoint("data")]
public readonly TRef<UnicodePipeContract.Imp:READY> Stdin;
[OutputEndpoint("data")]
public readonly TRef<UnicodePipeContract.Imp:READY> Stdout;
reflective internal ListCredentialsCommand();
internal int AppMain()
{
try {
CredentialsManagerContract.Imp! manager = CredentialsManager.ConnectService();
try {
manager.SendEnumerateCredentials();
switch receive {
case manager.CredentialsList(list):
if (list.Length == 0) {
Console.WriteLine("No entries in credentials store.");
} else {
const string format = "{0,-20} {1,-20}";
Console.WriteLine(format, "User name", "Tag");
Console.WriteLine(format, "=========", "===");
for (int i = 0; i < list.Length; i++) {
expose(list[i]) {
string! username = Bitter.ToString2(list[i].CredentialsName);
string! tag = Bitter.ToString2(list[i].Tag);
Console.WriteLine(format, username, tag);
}
}
}
delete list;
return 0;
case manager.RequestFailed(error):
Util.ShowCredError(error);
return 1;
}
} finally {
delete manager;
}
} catch (Exception ex) {
Util.ShowException(ex);
return -1;
}
}
}
[ConsoleCategory(Action="addmap", HelpMessage="Add a mapping from a protocol tuple to credentials.")]
internal class AddProtocolMappingCommand
{
[InputEndpoint("data")]
public readonly TRef<UnicodePipeContract.Imp:READY> Stdin;
[OutputEndpoint("data")]
public readonly TRef<UnicodePipeContract.Imp:READY> Stdout;
reflective internal AddProtocolMappingCommand();
[StringParameter("app", HelpMessage="The application protocol, such as 'smb' or 'http'.", Mandatory=true, Position=0)]
string ApplicationProtocol;
[StringParameter("service", HelpMessage="The remote service name, such as 'fooserver.example.com' or '192.168.0.1',", Mandatory=false, Position=1)]
string ServiceAddress;
[StringParameter("authp", HelpMessage="The authentication protocol, such as 'ntlm'.", Mandatory=true, Position=2)]
string AuthenticationProtocol;
[StringParameter("realm", HelpMessage="The authentication realm, such as 'yourdomain'.", Mandatory=true, Position=3)]
string Realm;
[StringParameter("username", HelpMessage="The username (credentials name) to map to.", Mandatory=true, Position=4)]
string CredentialsName;
[StringParameter("tag", HelpMessage="The credentials tag, which can be used to disambiguate between credentials with the same name.", Mandatory=false, Position=5, Default="")]
string Tag;
[BoolParameter("replace", HelpMessage="If specified, then any existing entry will be replaced.", Default=true)]
bool ReplaceExistingEntry;
internal int AppMain()
{
try {
CredentialsManager.AddProtocolMapping(
this.ApplicationProtocol,
this.ServiceAddress,
this.AuthenticationProtocol,
this.Realm,
this.CredentialsName,
this.Tag,
this.ReplaceExistingEntry);
Console.WriteLine("The protocol mapping has been added.");
return 0;
} catch (Exception ex) {
Util.ShowException(ex);
return -1;
}
}
}
[ConsoleCategory(Action="delmap", HelpMessage="Delete a mapping from a protocol tuple to credentials.")]
internal class DeleteProtocolMappingCommand
{
[InputEndpoint("data")]
public readonly TRef<UnicodePipeContract.Imp:READY> Stdin;
[OutputEndpoint("data")]
public readonly TRef<UnicodePipeContract.Imp:READY> Stdout;
reflective internal DeleteProtocolMappingCommand();
[StringParameter("app", HelpMessage="The application protocol, such as 'smb' or 'http'.", Mandatory=true, Position=0)]
string ApplicationProtocol;
[StringParameter("service", HelpMessage="The remote service name, such as 'fooserver.example.com' or '192.168.0.1',", Mandatory=false, Position=1)]
string ServiceAddress;
[StringParameter("authp", HelpMessage="The authentication protocol, such as 'ntlm'.", Mandatory=true, Position=2)]
string AuthenticationProtocol;
[StringParameter("realm", HelpMessage="The authentication realm, such as 'yourdomain'.", Mandatory=true, Position=3)]
string Realm;
internal int AppMain()
{
try {
CredentialsManager.DeleteProtocolMapping(
this.ApplicationProtocol,
this.ServiceAddress,
this.AuthenticationProtocol,
this.Realm);
Console.WriteLine("The protocol mapping has been deleted.");
return 0;
} catch (Exception ex) {
Util.ShowException(ex);
return -1;
}
}
}
[ConsoleCategory(Action="delmapall", HelpMessage="Delete all protocol mappings.")]
internal class DeleteAllProtocolMappingsCommand
{
[InputEndpoint("data")]
public readonly TRef<UnicodePipeContract.Imp:READY> Stdin;
[OutputEndpoint("data")]
public readonly TRef<UnicodePipeContract.Imp:READY> Stdout;
reflective internal DeleteAllProtocolMappingsCommand();
internal int AppMain()
{
try {
CredentialsManager.DeleteAllProtocolMappings();
Console.WriteLine("All protocol mappings have been deleted.");
return 0;
} catch (Exception ex) {
Util.ShowException(ex);
return -1;
}
}
}
[ConsoleCategory(Action="listmap", HelpMessage="Shows a list of all protocol mappings.")]
internal class ListProtocolMappingsCommand
{
[InputEndpoint("data")]
public readonly TRef<UnicodePipeContract.Imp:READY> Stdin;
[OutputEndpoint("data")]
public readonly TRef<UnicodePipeContract.Imp:READY> Stdout;
reflective internal ListProtocolMappingsCommand();
internal int AppMain()
{
try {
CredentialsManagerContract.Imp! manager = CredentialsManager.ConnectService();
try {
manager.SendEnumerateProtocolMappings();
switch receive {
case manager.ProtocolMappings(list):
Console.WriteLine("Protocol mappings:");
const string format = "{0,-10} {1,-10} {2,-10} {3,-10} {4,-10} {5,-10}";
Console.WriteLine(format, "App Prot.", "Service", "Auth Prot.", "Realm", "Credentials", "Tag");
Console.WriteLine(format, "=========", "=======", "==========", "=====", "===========", "===");
for (int i = 0; i < list.Length; i++) {
string! applicationProtocol;
string! serviceName;
string! authenticationProtocol;
string! realm;
string! credentialsName;
string! tag;
expose(list[i]) {
// expose(list[i].ProtocolTuple) {
applicationProtocol = Bitter.ToString2(list[i].ProtocolTuple.ApplicationProtocol);
serviceName = Bitter.ToString2(list[i].ProtocolTuple.ServiceAddress);
authenticationProtocol = Bitter.ToString2(list[i].ProtocolTuple.AuthenticationProtocol);
realm = Bitter.ToString2(list[i].ProtocolTuple.Realm);
// }
// expose(list[i].CredentialsId) {
credentialsName = Bitter.ToString2(list[i].CredentialsId.CredentialsName);
tag = Bitter.ToString2(list[i].CredentialsId.Tag);
// }
}
Console.WriteLine(format,
applicationProtocol,
serviceName,
authenticationProtocol,
realm,
credentialsName,
tag);
}
delete list;
return 0;
case manager.RequestFailed(error):
Util.ShowCredError(error);
return 1;
}
} finally {
delete manager;
}
} catch (Exception ex) {
Util.ShowException(ex);
return -1;
}
}
}
[ConsoleCategory(Action="testmap", HelpMessage="Test a protocol mapping. Specify a protocol tuple, and the command will show you which credentials would be selected.")]
internal class TestProtocolMappingCommand
{
[InputEndpoint("data")]
public readonly TRef<UnicodePipeContract.Imp:READY> Stdin;
[OutputEndpoint("data")]
public readonly TRef<UnicodePipeContract.Imp:READY> Stdout;
[StringParameter("app", HelpMessage="The application protocol, such as 'smb' or 'http'.", Mandatory=true, Position=0)]
string ApplicationProtocol;
[StringParameter("service", HelpMessage="The remote service name, such as 'fooserver.example.com' or '192.168.0.1',", Mandatory=true, Position=1)]
string ServiceAddress;
[StringParameter("authp", HelpMessage="The authentication protocol, such as 'ntlm'.", Mandatory=true, Position=2)]
string AuthenticationProtocol;
[StringParameter("realm", HelpMessage="The authentication realm, such as 'yourdomain'.", Mandatory=true, Position=3)]
string Realm;
reflective internal TestProtocolMappingCommand();
internal int AppMain()
{
try {
string! credentialsName;
string! tag;
Console.WriteLine("Checking:");
Console.WriteLine(" Application Protocol = " + this.ApplicationProtocol);
Console.WriteLine(" Service Address = " + this.ServiceAddress);
Console.WriteLine(" Authentication Protocol = " + this.AuthenticationProtocol);
Console.WriteLine(" Authentication Realm = " + this.Realm);
Console.WriteLine("");
if (CredentialsManager.FindMatchingProtocolMapping(
this.ApplicationProtocol,
this.ServiceAddress,
this.AuthenticationProtocol,
this.Realm,
true,
out credentialsName,
out tag))
{
Console.WriteLine("Credentials selected: {0} {1}", credentialsName, tag);
return 0;
} else {
Console.WriteLine("No mappings found that match the specified protocol tuple.");
return 1;
}
} catch (Exception ex) {
Util.ShowException(ex);
return -1;
}
}
}
class Util
{
public static void ShowException(Exception! chain)
{
for (Exception ex = chain; ex != null; ex = ex.InnerException) {
Console.WriteLine(ex.GetType().FullName + ": " + ex.Message);
}
}
public static void ShowCredError(CredError error)
{
Console.WriteLine("Error: " + CredentialsManager.CredErrorToString(error));
}
}
}