public static Credential QueryCredentials(Program program, OperationArguments operationArguments) { if (ReferenceEquals(operationArguments, null)) { throw new ArgumentNullException(nameof(operationArguments)); } if (ReferenceEquals(operationArguments.TargetUri, null)) { throw new ArgumentException("TargetUri property returned null", nameof(operationArguments)); } var task = Task.Run(async() => { return(await program.CreateAuthentication(operationArguments)); }); BaseAuthentication authentication = task.Result; Credential credentials = null; switch (operationArguments.Authority) { default: case AuthorityType.Basic: { BasicAuthentication basicAuth = authentication as BasicAuthentication; Task.Run(async() => { // attempt to get cached creds or acquire creds if interactivity is allowed if ((operationArguments.Interactivity != Interactivity.Always && (credentials = authentication.GetCredentials(operationArguments.TargetUri)) != null) || (operationArguments.Interactivity != Interactivity.Never && (credentials = await basicAuth.AcquireCredentials(operationArguments.TargetUri)) != null)) { Git.Trace.WriteLine("credentials found."); // no need to save the credentials explicitly, as Git will call back with // a store command if the credentials are valid. } else { Git.Trace.WriteLine($"credentials for '{operationArguments.TargetUri}' not found."); program.LogEvent($"Failed to retrieve credentials for '{operationArguments.TargetUri}'.", EventLogEntryType.FailureAudit); } }).Wait(); } break; case AuthorityType.AzureDirectory: { VstsAadAuthentication aadAuth = authentication as VstsAadAuthentication; Task.Run(async() => { // attempt to get cached creds -> non-interactive logon -> interactive // logon note that AAD "credentials" are always scoped access tokens if (((operationArguments.Interactivity != Interactivity.Always && ((credentials = aadAuth.GetCredentials(operationArguments.TargetUri)) != null) && (!operationArguments.ValidateCredentials || await aadAuth.ValidateCredentials(operationArguments.TargetUri, credentials)))) || (operationArguments.Interactivity != Interactivity.Always && ((credentials = await aadAuth.NoninteractiveLogon(operationArguments.TargetUri, true)) != null) && (!operationArguments.ValidateCredentials || await aadAuth.ValidateCredentials(operationArguments.TargetUri, credentials))) || (operationArguments.Interactivity != Interactivity.Never && ((credentials = await aadAuth.InteractiveLogon(operationArguments.TargetUri, true)) != null) && (!operationArguments.ValidateCredentials || await aadAuth.ValidateCredentials(operationArguments.TargetUri, credentials)))) { Git.Trace.WriteLine($"credentials for '{operationArguments.TargetUri}' found."); program.LogEvent($"Azure Directory credentials for '{operationArguments.TargetUri}' successfully retrieved.", EventLogEntryType.SuccessAudit); } else { Git.Trace.WriteLine($"credentials for '{operationArguments.TargetUri}' not found."); program.LogEvent($"Failed to retrieve Azure Directory credentials for '{operationArguments.TargetUri}'.", EventLogEntryType.FailureAudit); } }).Wait(); } break; case AuthorityType.MicrosoftAccount: { VstsMsaAuthentication msaAuth = authentication as VstsMsaAuthentication; Task.Run(async() => { // attempt to get cached creds -> interactive logon note that MSA // "credentials" are always scoped access tokens if (((operationArguments.Interactivity != Interactivity.Always && ((credentials = msaAuth.GetCredentials(operationArguments.TargetUri)) != null) && (!operationArguments.ValidateCredentials || await msaAuth.ValidateCredentials(operationArguments.TargetUri, credentials)))) || (operationArguments.Interactivity != Interactivity.Never && ((credentials = await msaAuth.InteractiveLogon(operationArguments.TargetUri, true)) != null) && (!operationArguments.ValidateCredentials || await msaAuth.ValidateCredentials(operationArguments.TargetUri, credentials)))) { Git.Trace.WriteLine($"credentials for '{operationArguments.TargetUri}' found."); program.LogEvent($"Microsoft Live credentials for '{operationArguments.TargetUri}' successfully retrieved.", EventLogEntryType.SuccessAudit); } else { Git.Trace.WriteLine($"credentials for '{operationArguments.TargetUri}' not found."); program.LogEvent($"Failed to retrieve Microsoft Live credentials for '{operationArguments.TargetUri}'.", EventLogEntryType.FailureAudit); } }).Wait(); } break; case AuthorityType.GitHub: { Github.Authentication ghAuth = authentication as Github.Authentication; Task.Run(async() => { if ((operationArguments.Interactivity != Interactivity.Always && ((credentials = ghAuth.GetCredentials(operationArguments.TargetUri)) != null) && (!operationArguments.ValidateCredentials || await ghAuth.ValidateCredentials(operationArguments.TargetUri, credentials))) || (operationArguments.Interactivity != Interactivity.Never && ((credentials = await ghAuth.InteractiveLogon(operationArguments.TargetUri)) != null) && (!operationArguments.ValidateCredentials || await ghAuth.ValidateCredentials(operationArguments.TargetUri, credentials)))) { Git.Trace.WriteLine($"credentials for '{operationArguments.TargetUri}' found."); program.LogEvent($"GitHub credentials for '{operationArguments.TargetUri}' successfully retrieved.", EventLogEntryType.SuccessAudit); } else { Git.Trace.WriteLine($"credentials for '{operationArguments.TargetUri}' not found."); program.LogEvent($"Failed to retrieve GitHub credentials for '{operationArguments.TargetUri}'.", EventLogEntryType.FailureAudit); } }).Wait(); } break; case AuthorityType.Bitbucket: { var bbcAuth = authentication as Bitbucket.Authentication; Task.Run(async() => { if (((operationArguments.Interactivity != Interactivity.Always) && ((credentials = bbcAuth.GetCredentials(operationArguments.TargetUri, operationArguments.CredUsername)) != null) && (!operationArguments.ValidateCredentials || ((credentials = await bbcAuth.ValidateCredentials(operationArguments.TargetUri, operationArguments.CredUsername, credentials)) != null))) || ((operationArguments.Interactivity != Interactivity.Never) && ((credentials = await bbcAuth.InteractiveLogon(operationArguments.TargetUri, operationArguments.CredUsername)) != null) && (!operationArguments.ValidateCredentials || ((credentials = await bbcAuth.ValidateCredentials(operationArguments.TargetUri, operationArguments.CredUsername, credentials)) != null)))) { Git.Trace.WriteLine($"credentials for '{operationArguments.TargetUri}' found."); // Bitbucket relies on a username + secret, so make sure there is a // username to return if (operationArguments.CredUsername != null) { credentials = new Credential(operationArguments.CredUsername, credentials.Password); } program.LogEvent($"Bitbucket credentials for '{operationArguments.TargetUri}' successfully retrieved.", EventLogEntryType.SuccessAudit); } else { program.LogEvent($"Failed to retrieve Bitbucket credentials for '{operationArguments.TargetUri}'.", EventLogEntryType.FailureAudit); } }).Wait(); } break; case AuthorityType.Ntlm: { Git.Trace.WriteLine($"'{operationArguments.TargetUri}' is NTLM."); credentials = BasicAuthentication.NtlmCredentials; } break; } if (credentials != null) { operationArguments.SetCredentials(credentials); } return(credentials); }
public static async Task <Credential> QueryCredentials(Program program, OperationArguments operationArguments) { if (program is null) { throw new ArgumentNullException(nameof(program)); } if (operationArguments is null) { throw new ArgumentNullException(nameof(operationArguments)); } if (operationArguments.TargetUri is null) { var innerException = new NullReferenceException($"{operationArguments.TargetUri} cannot be null."); throw new ArgumentException(innerException.Message, nameof(operationArguments), innerException); } BaseAuthentication authentication = await program.CreateAuthentication(operationArguments); Credential credentials = null; switch (operationArguments.Authority) { default: case AuthorityType.Basic: { var basicAuth = authentication as BasicAuthentication; // Attempt to get cached credentials or acquire credentials if interactivity is allowed. if ((operationArguments.Interactivity != Interactivity.Always && (credentials = await authentication.GetCredentials(operationArguments.TargetUri)) != null) || (operationArguments.Interactivity != Interactivity.Never && (credentials = await basicAuth.AcquireCredentials(operationArguments.TargetUri)) != null)) { program.Trace.WriteLine("credentials found."); // No need to save the credentials explicitly, as Git will call back // with a store command if the credentials are valid. } else { program.Trace.WriteLine($"credentials for '{operationArguments.TargetUri}' not found."); program.LogEvent($"Failed to retrieve credentials for '{operationArguments.TargetUri}'.", EventLogEntryType.FailureAudit); } } break; case AuthorityType.AzureDirectory: { var aadAuth = authentication as VstsAadAuthentication; var patOptions = new PersonalAccessTokenOptions() { RequireCompactToken = true, TokenDuration = operationArguments.TokenDuration, TokenScope = null, }; // Attempt to get cached credentials -> non-interactive logon -> interactive // logon note that AAD "credentials" are always scoped access tokens. if (((operationArguments.Interactivity != Interactivity.Always && ((credentials = await aadAuth.GetCredentials(operationArguments.TargetUri)) != null) && (!operationArguments.ValidateCredentials || await aadAuth.ValidateCredentials(operationArguments.TargetUri, credentials)))) || (operationArguments.Interactivity != Interactivity.Always && ((credentials = await aadAuth.NoninteractiveLogon(operationArguments.TargetUri, patOptions)) != null) && (!operationArguments.ValidateCredentials || await aadAuth.ValidateCredentials(operationArguments.TargetUri, credentials))) || (operationArguments.Interactivity != Interactivity.Never && ((credentials = await aadAuth.InteractiveLogon(operationArguments.TargetUri, patOptions)) != null) && (!operationArguments.ValidateCredentials || await aadAuth.ValidateCredentials(operationArguments.TargetUri, credentials)))) { program.Trace.WriteLine($"credentials for '{operationArguments.TargetUri}' found."); program.LogEvent($"Azure Directory credentials for '{operationArguments.TargetUri}' successfully retrieved.", EventLogEntryType.SuccessAudit); } else { program.Trace.WriteLine($"credentials for '{operationArguments.TargetUri}' not found."); program.LogEvent($"Failed to retrieve Azure Directory credentials for '{operationArguments.TargetUri}'.", EventLogEntryType.FailureAudit); } } break; case AuthorityType.MicrosoftAccount: { var msaAuth = authentication as VstsMsaAuthentication; var patOptions = new PersonalAccessTokenOptions() { RequireCompactToken = true, TokenDuration = operationArguments.TokenDuration, TokenScope = null, }; // Attempt to get cached credentials -> interactive logon note that MSA // "credentials" are always scoped access tokens. if (((operationArguments.Interactivity != Interactivity.Always && ((credentials = await msaAuth.GetCredentials(operationArguments.TargetUri)) != null) && (!operationArguments.ValidateCredentials || await msaAuth.ValidateCredentials(operationArguments.TargetUri, credentials)))) || (operationArguments.Interactivity != Interactivity.Never && ((credentials = await msaAuth.InteractiveLogon(operationArguments.TargetUri, patOptions)) != null) && (!operationArguments.ValidateCredentials || await msaAuth.ValidateCredentials(operationArguments.TargetUri, credentials)))) { program.Trace.WriteLine($"credentials for '{operationArguments.TargetUri}' found."); program.LogEvent($"Microsoft Live credentials for '{operationArguments.TargetUri}' successfully retrieved.", EventLogEntryType.SuccessAudit); } else { program.Trace.WriteLine($"credentials for '{operationArguments.TargetUri}' not found."); program.LogEvent($"Failed to retrieve Microsoft Live credentials for '{operationArguments.TargetUri}'.", EventLogEntryType.FailureAudit); } } break; case AuthorityType.GitHub: { var ghAuth = authentication as Github.Authentication; if ((operationArguments.Interactivity != Interactivity.Always && ((credentials = await ghAuth.GetCredentials(operationArguments.TargetUri)) != null) && (!operationArguments.ValidateCredentials || await ghAuth.ValidateCredentials(operationArguments.TargetUri, credentials))) || (operationArguments.Interactivity != Interactivity.Never && ((credentials = await ghAuth.InteractiveLogon(operationArguments.TargetUri)) != null) && (!operationArguments.ValidateCredentials || await ghAuth.ValidateCredentials(operationArguments.TargetUri, credentials)))) { program.Trace.WriteLine($"credentials for '{operationArguments.TargetUri}' found."); program.LogEvent($"GitHub credentials for '{operationArguments.TargetUri}' successfully retrieved.", EventLogEntryType.SuccessAudit); } else { program.Trace.WriteLine($"credentials for '{operationArguments.TargetUri}' not found."); program.LogEvent($"Failed to retrieve GitHub credentials for '{operationArguments.TargetUri}'.", EventLogEntryType.FailureAudit); } } break; case AuthorityType.Bitbucket: { var bbcAuth = authentication as Bitbucket.Authentication; if (((operationArguments.Interactivity != Interactivity.Always) && ((credentials = await bbcAuth.GetCredentials(operationArguments.TargetUri, operationArguments.Username)) != null) && (!operationArguments.ValidateCredentials || ((credentials = await bbcAuth.ValidateCredentials(operationArguments.TargetUri, operationArguments.Username, credentials)) != null))) || ((operationArguments.Interactivity != Interactivity.Never) && ((credentials = await bbcAuth.InteractiveLogon(operationArguments.TargetUri, operationArguments.Username)) != null) && (!operationArguments.ValidateCredentials || ((credentials = await bbcAuth.ValidateCredentials(operationArguments.TargetUri, operationArguments.Username, credentials)) != null)))) { program.Trace.WriteLine($"credentials for '{operationArguments.TargetUri}' found."); // Bitbucket relies on a username + secret, so make sure there is a // username to return. if (operationArguments.Username != null) { credentials = new Credential(operationArguments.Username, credentials.Password); } program.LogEvent($"Bitbucket credentials for '{operationArguments.TargetUri}' successfully retrieved.", EventLogEntryType.SuccessAudit); } else { program.LogEvent($"Failed to retrieve Bitbucket credentials for '{operationArguments.TargetUri}'.", EventLogEntryType.FailureAudit); } } break; case AuthorityType.Ntlm: { program.Trace.WriteLine($"'{operationArguments.TargetUri}' is NTLM."); credentials = BasicAuthentication.NtlmCredentials; } break; } if (credentials != null) { operationArguments.Credentials = credentials; } return(credentials); }
private static void Get() { const string AadMsaAuthFailureMessage = "Logon failed, use ctrl+c to cancel basic credential prompt."; const string GitHubAuthFailureMessage = "Logon failed, use ctrl+c to cancel basic credential prompt."; // parse the operations arguments from stdin (this is how git sends commands) // see: https://www.kernel.org/pub/software/scm/git/docs/technical/api-credentials.html // see: https://www.kernel.org/pub/software/scm/git/docs/git-credential.html OperationArguments operationArguments = new OperationArguments(Console.In); Debug.Assert(operationArguments != null, "The operationArguments is null"); Debug.Assert(operationArguments.TargetUri != null, "The operationArgument.TargetUri is null"); LoadOperationArguments(operationArguments); EnableTraceLogging(operationArguments); Trace.WriteLine("Program::Get"); Trace.WriteLine(" targetUri = " + operationArguments.TargetUri); BaseAuthentication authentication = CreateAuthentication(operationArguments); Credential credentials = null; switch (operationArguments.Authority) { default: case AuthorityType.Basic: if (authentication.GetCredentials(operationArguments.TargetUri, out credentials)) { Trace.WriteLine(" credentials found"); operationArguments.SetCredentials(credentials); } break; case AuthorityType.AzureDirectory: VsoAadAuthentication aadAuth = authentication as VsoAadAuthentication; Task.Run(async() => { // attmempt to get cached creds -> refresh creds -> non-interactive logon -> interactive logon // note that AAD "credentials" are always scoped access tokens if (((operationArguments.Interactivity != Interactivity.Always && aadAuth.GetCredentials(operationArguments.TargetUri, out credentials) && (!operationArguments.ValidateCredentials || await aadAuth.ValidateCredentials(operationArguments.TargetUri, credentials))) || (operationArguments.Interactivity != Interactivity.Always && await aadAuth.RefreshCredentials(operationArguments.TargetUri, true) && aadAuth.GetCredentials(operationArguments.TargetUri, out credentials) && (!operationArguments.ValidateCredentials || await aadAuth.ValidateCredentials(operationArguments.TargetUri, credentials))) || (operationArguments.Interactivity != Interactivity.Always && await aadAuth.NoninteractiveLogon(operationArguments.TargetUri, true) && aadAuth.GetCredentials(operationArguments.TargetUri, out credentials) && (!operationArguments.ValidateCredentials || await aadAuth.ValidateCredentials(operationArguments.TargetUri, credentials))) || (operationArguments.Interactivity != Interactivity.Never && aadAuth.InteractiveLogon(operationArguments.TargetUri, true)) && aadAuth.GetCredentials(operationArguments.TargetUri, out credentials) && (!operationArguments.ValidateCredentials || await aadAuth.ValidateCredentials(operationArguments.TargetUri, credentials)))) { Trace.WriteLine(" credentials found"); operationArguments.SetCredentials(credentials); LogEvent("Azure Directory credentials for " + operationArguments.TargetUri + " successfully retrieved.", EventLogEntryType.SuccessAudit); } else { Console.Error.WriteLine(AadMsaAuthFailureMessage); LogEvent("Failed to retrieve Azure Directory credentials for " + operationArguments.TargetUri + ".", EventLogEntryType.FailureAudit); } }).Wait(); break; case AuthorityType.MicrosoftAccount: VsoMsaAuthentication msaAuth = authentication as VsoMsaAuthentication; Task.Run(async() => { // attmempt to get cached creds -> refresh creds -> interactive logon // note that MSA "credentials" are always scoped access tokens if (((operationArguments.Interactivity != Interactivity.Always && msaAuth.GetCredentials(operationArguments.TargetUri, out credentials) && (!operationArguments.ValidateCredentials || await msaAuth.ValidateCredentials(operationArguments.TargetUri, credentials))) || (operationArguments.Interactivity != Interactivity.Always && await msaAuth.RefreshCredentials(operationArguments.TargetUri, true) && msaAuth.GetCredentials(operationArguments.TargetUri, out credentials) && (!operationArguments.ValidateCredentials || await msaAuth.ValidateCredentials(operationArguments.TargetUri, credentials))) || (operationArguments.Interactivity != Interactivity.Never && msaAuth.InteractiveLogon(operationArguments.TargetUri, true)) && msaAuth.GetCredentials(operationArguments.TargetUri, out credentials) && (!operationArguments.ValidateCredentials || await msaAuth.ValidateCredentials(operationArguments.TargetUri, credentials)))) { Trace.WriteLine(" credentials found"); operationArguments.SetCredentials(credentials); LogEvent("Microsoft Live credentials for " + operationArguments.TargetUri + " successfully retrieved.", EventLogEntryType.SuccessAudit); } else { Console.Error.WriteLine(AadMsaAuthFailureMessage); LogEvent("Failed to retrieve Microsoft Live credentials for " + operationArguments.TargetUri + ".", EventLogEntryType.FailureAudit); } }).Wait(); break; case AuthorityType.GitHub: GithubAuthentication ghAuth = authentication as GithubAuthentication; Task.Run(async() => { if ((operationArguments.Interactivity != Interactivity.Always && ghAuth.GetCredentials(operationArguments.TargetUri, out credentials) && (!operationArguments.ValidateCredentials || await ghAuth.ValidateCredentials(operationArguments.TargetUri, credentials))) || (operationArguments.Interactivity != Interactivity.Never && ghAuth.InteractiveLogon(operationArguments.TargetUri, out credentials) && ghAuth.GetCredentials(operationArguments.TargetUri, out credentials) && (!operationArguments.ValidateCredentials || await ghAuth.ValidateCredentials(operationArguments.TargetUri, credentials)))) { Trace.WriteLine(" credentials found"); operationArguments.SetCredentials(credentials); LogEvent("GitHub credentials for " + operationArguments.TargetUri + " successfully retrieved.", EventLogEntryType.SuccessAudit); } else { Console.Error.WriteLine(GitHubAuthFailureMessage); LogEvent("Failed to retrieve GitHub credentials for " + operationArguments.TargetUri + ".", EventLogEntryType.FailureAudit); } }).Wait(); break; case AuthorityType.Integrated: credentials = new Credential(String.Empty, String.Empty); operationArguments.SetCredentials(credentials); break; } Console.Out.Write(operationArguments); }