530 lines
21 KiB
Plaintext
530 lines
21 KiB
Plaintext
////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Microsoft Research Singularity
|
|
//
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
//
|
|
// 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(
|
|
Util.NullToEmpty(this.ApplicationProtocol),
|
|
Util.NullToEmpty(this.ServiceAddress),
|
|
Util.NullToEmpty(this.AuthenticationProtocol),
|
|
Util.NullToEmpty(this.Realm),
|
|
Util.NullToEmpty(this.CredentialsName),
|
|
Util.NullToEmpty(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(
|
|
Util.NullToEmpty(this.ApplicationProtocol),
|
|
Util.NullToEmpty(this.ServiceAddress),
|
|
Util.NullToEmpty(this.AuthenticationProtocol),
|
|
Util.NullToEmpty(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(
|
|
Util.NullToEmpty(this.ApplicationProtocol),
|
|
Util.NullToEmpty(this.ServiceAddress),
|
|
Util.NullToEmpty(this.AuthenticationProtocol),
|
|
Util.NullToEmpty(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));
|
|
}
|
|
|
|
public static string! NullToEmpty(string s)
|
|
{
|
|
if (s == null)
|
|
return "";
|
|
else
|
|
return s;
|
|
}
|
|
}
|
|
}
|