protected Credential ReadCredentials(string targetName) { Trace.WriteLine("BaseSecureStore::ReadCredentials"); Credential credentials = null; IntPtr credPtr = IntPtr.Zero; try { if (NativeMethods.CredRead(targetName, NativeMethods.CredentialType.Generic, 0, out credPtr)) { NativeMethods.Credential credStruct = (NativeMethods.Credential)Marshal.PtrToStructure(credPtr, typeof(NativeMethods.Credential)); int passwordLength = (int)credStruct.CredentialBlobSize; string password = passwordLength > 0 ? Marshal.PtrToStringUni(credStruct.CredentialBlob, passwordLength / sizeof(char)) : String.Empty; string username = credStruct.UserName ?? String.Empty; credentials = new Credential(username, password); } } finally { if (credPtr != IntPtr.Zero) { NativeMethods.CredFree(credPtr); } } return credentials; }
internal static void ValidateCredential(Credential credentials) { if (ReferenceEquals(credentials, null)) throw new ArgumentNullException(nameof(credentials)); if (credentials.Password.Length > NativeMethods.Credential.PasswordMaxLength) throw new ArgumentOutOfRangeException(nameof(credentials.Password)); if (credentials.Username.Length > NativeMethods.Credential.UsernameMaxLength) throw new ArgumentOutOfRangeException(nameof(credentials.Username)); }
/// <summary> /// Gets a <see cref="Credential"/> from the storage used by the authentication object. /// </summary> /// <param name="targetUri"> /// The uniform resource indicator used to uniquely identify the credentials. /// </param> /// <param name="credentials"> /// If successful a <see cref="Credential"/> object from the authentication object, /// authority or storage; otherwise <see langword="null"/>. /// </param> /// <returns><see langword="true"/> if successful; otherwise <see langword="false"/>.</returns> public override bool GetCredentials(Uri targetUri, out Credential credentials) { BaseSecureStore.ValidateTargetUri(targetUri); Trace.WriteLine("BasicAuthentication::GetCredentials"); this.CredentialStore.ReadCredentials(targetUri, out credentials); return credentials != null; }
/// <summary> /// Sets a <see cref="Credential"/> in the storage used by the authentication object. /// </summary> /// <param name="targetUri"> /// The uniform resource indicator used to uniquely identify the credentials. /// </param> /// <param name="credentials">The value to be stored.</param> /// <returns><see langword="true"/> if successful; otherwise <see langword="false"/>.</returns> public override bool SetCredentials(Uri targetUri, Credential credentials) { BaseSecureStore.ValidateTargetUri(targetUri); Credential.Validate(credentials); Trace.WriteLine("BasicAuthentication::SetCredentials"); this.CredentialStore.WriteCredentials(targetUri, credentials); return true; }
/// <summary> /// Reads credentials for a target URI from the credential store /// </summary> /// <param name="targetUri">The URI of the target for which credentials are being read</param> /// <param name="credentials">The credentials from the store; <see langword="null"/> if failure</param> /// <returns><see langword="true"/> if success; <see langword="false"/> if failure</returns> public bool ReadCredentials(Uri targetUri, out Credential credentials) { ValidateTargetUri(targetUri); string targetName = this.GetTargetName(targetUri); Trace.WriteLine("CredentialStore::ReadCredentials"); credentials = this.ReadCredentials(targetName); return credentials != null; }
internal static void Validate(Credential credentials) { if (credentials == null) { throw new ArgumentNullException(nameof(credentials)); } if (credentials.Password.Length > NativeMethods.Credential.PasswordMaxLength) { throw new ArgumentOutOfRangeException(nameof(credentials.Password)); } if (credentials.Username.Length > NativeMethods.Credential.UsernameMaxLength) { throw new ArgumentOutOfRangeException(nameof(credentials.Username)); } }
protected Credential ReadCredentials(string targetName) { Trace.WriteLine("BaseSecureStore::ReadCredentials"); Credential credentials = null; IntPtr credPtr = IntPtr.Zero; try { if (!NativeMethods.CredRead(targetName, NativeMethods.CredentialType.Generic, 0, out credPtr)) { return null; } NativeMethods.Credential credStruct = (NativeMethods.Credential)Marshal.PtrToStructure(credPtr, typeof(NativeMethods.Credential)); // https://msdn.microsoft.com/en-us/library/gg309393.aspx int size = (int)credStruct.CredentialBlobSize; SecureString pwd = null; if (size != 0) { byte[] bpassword = new byte[size]; Marshal.Copy(credStruct.CredentialBlob, bpassword, 0, size); char[] chars = Encoding.Unicode.GetChars(bpassword); pwd = ConvertToSecureString(chars); Array.Clear(chars, 0, chars.Length); Array.Clear(bpassword, 0, bpassword.Length); } credentials = new Credential(credStruct.UserName, pwd); } finally { if (credPtr != IntPtr.Zero) { NativeMethods.CredFree(credPtr); } } return credentials; }
/// <summary> /// Reads credentials for a target URI from the credential store /// </summary> /// <param name="targetUri">The URI of the target for which credentials are being read</param> /// <param name="credentials">The credentials from the store; <see langword="null"/> if failure</param> /// <returns><see langword="true"/> if success; <see langword="false"/> if failure</returns> public bool ReadCredentials(Uri targetUri, out Credential credentials) { BaseSecureStore.ValidateTargetUri(targetUri); Trace.WriteLine("SecretCache::ReadCredentials"); string targetName = this.GetTargetName(targetUri); lock (_cache) { if (_cache.ContainsKey(targetName) && _cache[targetName] is Credential) { credentials = _cache[targetName] as Credential; } else { credentials = null; } } return credentials != null; }
/// <summary> /// acquires a <see cref="TokenPair"/> from the authority using optionally provided /// credentials or via the current identity. /// </summary> /// <param name="targetUri"> /// The uniform resource indicator of the resource access tokens are being requested for. /// </param> /// <param name="clientId">Identifier of the client requesting the token.</param> /// <param name="resource"> /// Identifier of the target resource that is the recipient of the requested token. /// </param> /// <param name="credentials">Optional: user credential to use for token acquisition.</param> /// <returns>If successful a <see cref="TokenPair"/>; otherwise <see langword="null"/>.</returns> public async Task <TokenPair> AcquireTokenAsync(Uri targetUri, string clientId, string resource, Credential credentials = null) { Debug.Assert(targetUri != null && targetUri.IsAbsoluteUri, "The targetUri parameter is null or invalid"); Debug.Assert(!String.IsNullOrWhiteSpace(clientId), "The clientId parameter is null or empty"); Debug.Assert(!String.IsNullOrWhiteSpace(resource), "The resource parameter is null or empty"); Trace.WriteLine("AzureAuthority::AcquireTokenAsync"); TokenPair tokens = null; try { Trace.WriteLine(String.Format(" authority host url = '{0}'.", AuthorityHostUrl)); UserCredential userCredential = credentials == null ? new UserCredential() : new UserCredential(credentials.Username, credentials.Password); AuthenticationContext authCtx = new AuthenticationContext(AuthorityHostUrl, _adalTokenCache); AuthenticationResult authResult = await authCtx.AcquireTokenAsync(resource, clientId, userCredential); tokens = new TokenPair(authResult); Trace.WriteLine(" token acquisition succeeded."); } catch (AdalException) { Trace.WriteLine(" token acquisition failed."); } return(tokens); }
/// <summary> /// Validates that a set of credentials grants access to the target resource. /// </summary> /// <param name="targetUri">The unique identifier for the resource for which credentials /// are being validated against.</param> /// <param name="credentials">The credentials to validate.</param> /// <returns>True is successful; otherwise false.</returns> public async Task<bool> ValidateCredentials(Uri targetUri, Credential credentials) { BaseSecureStore.ValidateTargetUri(targetUri); Credential.Validate(credentials); Trace.WriteLine("GithubAuthentication::ValidateCredentials"); return await GithubAuthority.ValidateCredentials(targetUri, credentials); }
/// <summary> /// <para></para> /// <para>Tokens acquired are stored in the secure secret store provided during /// initialization.</para> /// </summary> /// <param name="targetUri">The unique identifier for the resource for which access is to /// be acquired.</param> /// <param name="credentials">(out) Credentials when acquision is successful; null otherwise.</param> /// <returns>True if success; otherwise false.</returns> public bool InteractiveLogon(Uri targetUri, out Credential credentials) { string username; string password; if (AcquireCredentialsCallback(targetUri, out username, out password)) { GithubAuthenticationResult result; if (result = GithubAuthority.AcquireToken(targetUri, username, password, null, this.TokenScope).Result) { Trace.WriteLine(" token aquisition succeeded"); credentials = (Credential)result.Token; this.PersonalAccessTokenStore.WriteCredentials(targetUri, credentials); // if a result callback was registered, call it if (AuthenticationResultCallback!=null) { AuthenticationResultCallback(targetUri, result); } return true; } else if (result == GithubAuthenticationResultType.TwoFactorApp || result == GithubAuthenticationResultType.TwoFactorSms) { string authenticationCode; if (AcquireAuthenticationCodeCallback(targetUri, result, out authenticationCode)) { if (result = GithubAuthority.AcquireToken(targetUri, username, password, authenticationCode, this.TokenScope).Result) { Trace.WriteLine(" token aquisition succeeded"); credentials = (Credential)result.Token; this.PersonalAccessTokenStore.WriteCredentials(targetUri, credentials); // if a result callback was registered, call it if (AuthenticationResultCallback != null) { AuthenticationResultCallback(targetUri, result); } return true; } } } // if a result callback was registered, call it if (AuthenticationResultCallback != null) { AuthenticationResultCallback(targetUri, result); } } Trace.WriteLine(" interactive logon failed"); credentials = null; return false; }
private static void Store() { // 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.Username != null, "The operaionArgument.Username is null"); Debug.Assert(operationArguments.TargetUri != null, "The operationArgument.TargetUri is null"); LoadOperationArguments(operationArguments); EnableTraceLogging(operationArguments); Trace.WriteLine("Program::Store"); Trace.WriteLine(" targetUri = " + operationArguments.TargetUri); BaseAuthentication authentication = CreateAuthentication(operationArguments); Credential credentials = new Credential(operationArguments.Username, operationArguments.Password); authentication.SetCredentials(operationArguments.TargetUri, credentials); }
private static string GetBasicAuthorizationHeader(Credential credentials) { const string BasicPrefix = "Basic "; // credentials are packed into the 'Authorization' header as a base64 encoded pair string base64enc = GetBase64EncodedCredentials(credentials); string basicAuthHeader = BasicPrefix + base64enc; return basicAuthHeader; }
internal static HttpWebRequest GetConnectionDataRequest(TargetUri targetUri, Credential credentials) { Debug.Assert(targetUri != null && targetUri.IsAbsoluteUri, "The targetUri parameter is null or invalid"); Debug.Assert(credentials != null, "The credentials parameter is null or invalid"); // create an request to the VSTS deployment data end-point HttpWebRequest request = GetConnectionDataRequest(targetUri); // credentials are packed into the 'Authorization' header as a base64 encoded pair string basicAuthHeader = GetBasicAuthorizationHeader(credentials); request.Headers.Add(HttpRequestHeader.Authorization, basicAuthHeader); return request; }
/// <summary> /// <para></para> /// <para>Tokens acquired are stored in the secure secret store provided during /// initialization.</para> /// </summary> /// <param name="targetUri">The unique identifier for the resource for which access is to /// be acquired.</param> /// <param name="credentials">(out) Credentials when acquision is successful; null otherwise.</param> /// <returns>True if success; otherwise false.</returns> public bool InteractiveLogon(Uri targetUri, out Credential credentials) { // ReadConsole 32768 fail, 32767 ok // @linquize [https://github.com/Microsoft/Git-Credential-Manager-for-Windows/commit/a62b9a19f430d038dcd85a610d97e5f763980f85] const int BufferReadSize = 32 * 1024 - 7; StringBuilder buffer = new StringBuilder(BufferReadSize); uint read = 0; uint written = 0; NativeMethods.FileAccess fileAccessFlags = NativeMethods.FileAccess.GenericRead | NativeMethods.FileAccess.GenericWrite; NativeMethods.FileAttributes fileAttributes = NativeMethods.FileAttributes.Normal; NativeMethods.FileCreationDisposition fileCreationDisposition = NativeMethods.FileCreationDisposition.OpenExisting; NativeMethods.FileShare fileShareFlags = NativeMethods.FileShare.Read | NativeMethods.FileShare.Write; using (SafeFileHandle stdout = NativeMethods.CreateFile("CONOUT$", fileAccessFlags, fileShareFlags, IntPtr.Zero, fileCreationDisposition, fileAttributes, IntPtr.Zero)) using (SafeFileHandle stdin = NativeMethods.CreateFile("CONIN$", fileAccessFlags, fileShareFlags, IntPtr.Zero, fileCreationDisposition, fileAttributes, IntPtr.Zero)) { // read the current console mode NativeMethods.ConsoleMode consoleMode; if (!NativeMethods.GetConsoleMode(stdin, out consoleMode)) { int error = Marshal.GetLastWin32Error(); throw new Win32Exception(error, "Unable to determine console mode (" + error + ")."); } // instruct the user as to what they are expected to do buffer.Append("Please enter your GitHub credentials for ") .Append(targetUri.Scheme) .Append("://") .Append(targetUri.DnsSafeHost) .Append("/") .Append(targetUri.PathAndQuery) .AppendLine(); if (!NativeMethods.WriteConsole(stdout, buffer, (uint)buffer.Length, out written, IntPtr.Zero)) { int error = Marshal.GetLastWin32Error(); throw new Win32Exception(error, "Unable to write to standard output (" + error + ")."); } // clear the buffer for the next operation buffer.Clear(); // prompt the user for the username wanted buffer.Append("username: "******"Unable to write to standard output (" + error + ")."); } // clear the buffer for the next operation buffer.Clear(); // read input from the user if (!NativeMethods.ReadConsole(stdin, buffer, BufferReadSize, out read, IntPtr.Zero)) { int error = Marshal.GetLastWin32Error(); throw new Win32Exception(error, "Unable to read from standard input (" + error + ")."); } // record input from the user into local storage, stripping any eol chars string username = buffer.ToString(0, (int)read); username = username.Trim(Environment.NewLine.ToCharArray()); // clear the buffer for the next operation buffer.Clear(); // set the console mode to current without echo input NativeMethods.ConsoleMode consoleMode2 = consoleMode ^ NativeMethods.ConsoleMode.EchoInput; if (!NativeMethods.SetConsoleMode(stdin, consoleMode2)) { int error = Marshal.GetLastWin32Error(); throw new Win32Exception(error, "Unable to set console mode (" + error + ")."); } // prompt the user for password buffer.Append("password: "******"Unable to write to standard output (" + error + ")."); } // clear the buffer for the next operation buffer.Clear(); // read input from the user if (!NativeMethods.ReadConsole(stdin, buffer, BufferReadSize, out read, IntPtr.Zero)) { int error = Marshal.GetLastWin32Error(); throw new Win32Exception(error, "Unable to read from standard input (" + error + ")."); } // record input from the user into local storage, stripping any eol chars string password = buffer.ToString(0, (int)read); password = password.Trim(Environment.NewLine.ToCharArray()); // clear the buffer for the next operation buffer.Clear(); // restore the console mode to its original value if (!NativeMethods.SetConsoleMode(stdin, consoleMode)) { int error = Marshal.GetLastWin32Error(); throw new Win32Exception(error, "Unable to set console mode (" + error + ")."); } GithubAuthenticationResult result; if (result = GithubAuthority.AcquireToken(targetUri, username, password, null, this.TokenScope).Result) { Trace.WriteLine(" token aquisition succeeded"); credentials = (Credential)result.Token; this.PersonalAccessTokenStore.WriteCredentials(targetUri, credentials); return true; } else if (result == GithubAuthenticationResultType.TwoFactorApp || result == GithubAuthenticationResultType.TwoFactorSms) { buffer.Clear() .AppendLine() .Append("authcode: "); if (!NativeMethods.WriteConsole(stdout, buffer, (uint)buffer.Length, out written, IntPtr.Zero)) { int error = Marshal.GetLastWin32Error(); throw new Win32Exception(error, "Unable to write to standard output (" + error + ")."); } buffer.Clear(); // read input from the user if (!NativeMethods.ReadConsole(stdin, buffer, BufferReadSize, out read, IntPtr.Zero)) { int error = Marshal.GetLastWin32Error(); throw new Win32Exception(error, "Unable to read from standard input (" + error + ")."); } string authenticationCode = buffer.ToString(0, (int)read); authenticationCode = authenticationCode.Trim(Environment.NewLine.ToCharArray()); if (result = GithubAuthority.AcquireToken(targetUri, username, password, authenticationCode, this.TokenScope).Result) { Trace.WriteLine(" token aquisition succeeded"); credentials = (Credential)result.Token; this.PersonalAccessTokenStore.WriteCredentials(targetUri, credentials); return true; } } } Trace.WriteLine(" interactive logon failed"); credentials = null; return false; }
/// <summary> /// Writes credentials for a target URI to the credential store /// </summary> /// <param name="targetUri">The URI of the target for which credentials are being stored</param> /// <param name="credentials">The credentials to be stored</param> public void WriteCredentials(Uri targetUri, Credential credentials) { BaseSecureStore.ValidateTargetUri(targetUri); Credential.Validate(credentials); Trace.WriteLine("SecretCache::WriteCredentials"); string targetName = this.GetTargetName(targetUri); lock (_cache) { if (_cache.ContainsKey(targetName)) { _cache[targetName] = credentials; } else { _cache.Add(targetName, credentials); } } }
/// <summary> /// <para>Uses credentials to authenticate with the Azure tenant and acquire the necessary /// access tokens to exchange for a VSO personal access token.</para> /// <para>Tokens acquired are stored in the secure secret stores provided during /// initialization.</para> /// </summary> /// <param name="targetUri">The unique identifier for the resource for which access is to /// be acquired.</param> /// <param name="credentials">The credentials required to meet the criteria of the Azure /// tenant authentication challenge (i.e. username + password).</param> /// <param name="requestCompactToken"> /// <para>Requests a compact format personal access token; otherwise requests a standard /// personal access token.</para> /// <para>Compact tokens are necessary for clients which have restrictions on the size of /// the basic authentication header which they can create (example: Git).</para> /// </param> /// <returns><see langword="true"/> if authentication and personal access token acquisition was successful; otherwise <see langword="false"/>.</returns> public async Task<bool> NoninteractiveLogonWithCredentials(Uri targetUri, Credential credentials, bool requestCompactToken) { BaseSecureStore.ValidateTargetUri(targetUri); Credential.Validate(credentials); Trace.WriteLine("VsoAadAuthentication::NoninteractiveLogonWithCredentials"); try { TokenPair tokens; if ((tokens = await this.VsoAuthority.AcquireTokenAsync(targetUri, this.ClientId, this.Resource, credentials)) != null) { Trace.WriteLine(" token aquisition succeeded"); this.StoreRefreshToken(targetUri, tokens.RefeshToken); return await this.GeneratePersonalAccessToken(targetUri, tokens.AccessToken, requestCompactToken); } } catch (AdalException) { Trace.WriteLine(" token aquisition failed"); } Trace.WriteLine(" non-interactive logon failed"); return false; }
/// <summary> /// Sets a <see cref="Credential"/> in the storage used by the authentication object. /// </summary> /// <param name="targetUri">The uniform resource indicator used to uniquely identify the credentials.</param> /// <param name="credentials">The value to be stored.</param> public abstract Task <bool> SetCredentials(TargetUri targetUri, Credential credentials);
/// <summary> /// Validates that a set of credentials grants access to the target resource. /// </summary> /// <param name="targetUri">The target resource to validate against.</param> /// <param name="credentials">The credentials to validate.</param> /// <returns><see langword="true"/> if successful; <see langword="false"/> otherwise.</returns> public async Task <bool> ValidateCredentials(TargetUri targetUri, Credential credentials) { Trace.WriteLine("BaseVstsAuthentication::ValidateCredentials"); return(await this.VstsAuthority.ValidateCredentials(targetUri, credentials)); }
/// <summary> /// Validates that <see cref="Credential"/> are valid to grant access to the Visual Studio /// Online service represented by the <paramref name="targetUri"/> parameter. /// </summary> /// <param name="targetUri">Uniform resource identifier for a VSTS service.</param> /// <param name="credentials"> /// <see cref="Credential"/> expected to grant access to the VSTS service. /// </param> /// <returns>True if successful; otherwise false.</returns> public async Task<bool> ValidateCredentials(TargetUri targetUri, Credential credentials) { BaseSecureStore.ValidateTargetUri(targetUri); BaseSecureStore.ValidateCredential(credentials); try { // create an request to the VSTS deployment data end-point HttpWebRequest request = GetConnectionDataRequest(targetUri, credentials); Git.Trace.WriteLine($"validating credentials against '{request.RequestUri}'."); // send the request and wait for the response using (HttpWebResponse response = await request.GetResponseAsync() as HttpWebResponse) { // we're looking for 'OK 200' here, anything else is failure Git.Trace.WriteLine($"server returned: '{response.StatusCode}'."); return response.StatusCode == HttpStatusCode.OK; } } catch (WebException webException) { Git.Trace.WriteLine($"server returned: '{webException.Message}."); } catch { Git.Trace.WriteLine("! unexpected error"); } Git.Trace.WriteLine($"credential validation for '{targetUri}' failed."); return false; }
internal static HttpClient CreateHttpClient(TargetUri targetUri, Credential credentials) { const string CredentialHeader = "Basic"; Debug.Assert(targetUri != null, $"The `{nameof(targetUri)}` parameter is null."); HttpClient httpClient = CreateHttpClient(targetUri); httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(CredentialHeader, GetBase64EncodedCredentials(credentials)); return httpClient; }
/// <summary> /// Sets credentials for future use with this authentication object. /// </summary> /// <remarks>Not supported.</remarks> /// <param name="targetUri">The uniform resource indicator of the resource access tokens are being set for.</param> /// <param name="credentials">The credentials being set.</param> public override void SetCredentials(TargetUri targetUri, Credential credentials) { BaseSecureStore.ValidateTargetUri(targetUri); BaseSecureStore.ValidateCredential(credentials); }
private static string GetBase64EncodedCredentials(Credential credentials) { const string UsernamePasswordFormat = "{0}:{1}"; Debug.Assert(credentials != null, "The credentials parameter is null or invalid"); string credPair = String.Format(UsernamePasswordFormat, credentials.Username, credentials.Password); byte[] credBytes = Encoding.ASCII.GetBytes(credPair); string base64enc = Convert.ToBase64String(credBytes); return base64enc; }
private bool WriteBindingInformation(string configFile, BoundSonarQubeProject binding) { if (this.SafePerformFileSystemOperation(() => WriteConfig(configFile, binding))) { BasicAuthCredentials credentials = binding.Credentials as BasicAuthCredentials; if (credentials != null) { Debug.Assert(credentials.UserName != null, "User name is not expected to be null"); Debug.Assert(credentials.Password != null, "Password name is not expected to be null"); var creds = new Credential(credentials.UserName, credentials.Password); this.credentialStore.WriteCredentials(binding.ServerUri, creds); } return true; } return false; }
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); } else if (operationArguments.UseModalUi) { // display the modal dialog string username; string password; if (PromptForCredentials(operationArguments.TargetUri, out username, out password)) { // set the credentials object // no need to save the credentials explicitly, as Git will call back // with a store command if the credentials are valid. credentials = new Credential(username, password); } } 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); }
/// <summary> /// Validates that a set of credentials grants access to the target resource. /// </summary> /// <param name="targetUri">The target resource to validate against.</param> /// <param name="credentials">The credentials to validate.</param> /// <returns><see langword="true"/> if successful; <see langword="false"/> otherwise.</returns> public async Task<bool> ValidateCredentials(Uri targetUri, Credential credentials) { Trace.WriteLine("BaseVsoAuthentication::ValidateCredentials"); return await this.VsoAuthority.ValidateCredentials(targetUri, credentials); }
/// <summary> /// Gets a <see cref="Credential"/> from the storage used by the authentication object. /// </summary> /// <param name="targetUri"> /// The uniform resource indicator used to uniquely identitfy the credentials. /// </param> /// <param name="credentials"> /// (out) A <see cref="Credential"/> object from the authentication object, /// authority or storage; otherwise `null`, if successful. /// </param> /// <returns>True if successful; otherwise false.</returns> public override bool GetCredentials(Uri targetUri, out Credential credentials) { BaseSecureStore.ValidateTargetUri(targetUri); Trace.WriteLine("GithubAuthentication::GetCredentials"); if (this.PersonalAccessTokenStore.ReadCredentials(targetUri, out credentials)) { Trace.WriteLine(" successfully retrieved stored credentials, updating credential cache"); } return credentials != null; }
/// <summary> /// Sets credentials for future use with this authentication object. /// </summary> /// <remarks>Not supported.</remarks> /// <param name="targetUri"> /// The uniform resource indicator of the resource access tokens are being set for. /// </param> /// <param name="credentials">The credentials being set.</param> /// <returns>True if successful; false otherwise.</returns> public override bool SetCredentials(TargetUri targetUri, Credential credentials) { BaseSecureStore.ValidateTargetUri(targetUri); Credential.Validate(credentials); Trace.WriteLine("VstsMsaAuthentication::SetCredentials"); Trace.WriteLine(" setting MSA credentials is not supported"); // does nothing with VSTS MSA backed accounts return false; }
/// <summary> /// Sets a <see cref="Credential"/> in the storage used by the authentication object. /// </summary> /// <param name="targetUri"> /// The uniform resource indicator used to uniquely identitfy the credentials. /// </param> /// <param name="credentials">The value to be stored.</param> /// <returns>True if successful; otherwise false.</returns> public override bool SetCredentials(Uri targetUri, Credential credentials) { BaseSecureStore.ValidateTargetUri(targetUri); Credential.Validate(credentials); Trace.WriteLine("GithubAuthentication::SetCredentials"); PersonalAccessTokenStore.WriteCredentials(targetUri, credentials); return true; }
internal static extern bool CredWrite(ref Credential credential, UInt32 flags);
protected void WriteCredential(string targetName, Credential credentials) { NativeMethods.Credential credential = new NativeMethods.Credential() { Type = NativeMethods.CredentialType.Generic, TargetName = targetName, CredentialBlob = Marshal.StringToCoTaskMemUni(credentials.Password), CredentialBlobSize = (uint)Encoding.Unicode.GetByteCount(credentials.Password), Persist = NativeMethods.CredentialPersist.LocalMachine, AttributeCount = 0, UserName = credentials.Username, }; try { if (!NativeMethods.CredWrite(ref credential, 0)) { int errorCode = Marshal.GetLastWin32Error(); throw new Exception("Failed to write credentials", new Win32Exception(errorCode)); } Git.Trace.WriteLine($"credentials for '{targetName}' written to store."); } finally { if (credential.CredentialBlob != IntPtr.Zero) { Marshal.FreeCoTaskMem(credential.CredentialBlob); } } }
/// <summary> /// acquires a <see cref="TokenPair"/> from the authority using optionally provided /// credentials or via the current identity. /// </summary> /// <param name="targetUri"> /// The uniform resource indicator of the resource access tokens are being requested for. /// </param> /// <param name="clientId">Identifier of the client requesting the token.</param> /// <param name="resource"> /// Identifier of the target resource that is the recipient of the requested token. /// </param> /// <param name="credentials">Optional: user credential to use for token acquisition.</param> /// <returns>If successful a <see cref="TokenPair"/>; otherwise <see langword="null"/>.</returns> public async Task<TokenPair> AcquireTokenAsync(Uri targetUri, string clientId, string resource, Credential credentials = null) { Debug.Assert(targetUri != null && targetUri.IsAbsoluteUri, "The targetUri parameter is null or invalid"); Debug.Assert(!String.IsNullOrWhiteSpace(clientId), "The clientId parameter is null or empty"); Debug.Assert(!String.IsNullOrWhiteSpace(resource), "The resource parameter is null or empty"); Trace.WriteLine("AzureAuthority::AcquireTokenAsync"); TokenPair tokens = null; try { Trace.WriteLine(String.Format(" authority host url = '{0}'.", AuthorityHostUrl)); UserCredential userCredential = credentials == null ? new UserCredential() : new UserCredential(credentials.Username, credentials.Password); AuthenticationContext authCtx = new AuthenticationContext(AuthorityHostUrl, _adalTokenCache); AuthenticationResult authResult = await authCtx.AcquireTokenAsync(resource, clientId, userCredential); tokens = new TokenPair(authResult); Trace.WriteLine(" token acquisition succeeded."); } catch (AdalException) { Trace.WriteLine(" token acquisition failed."); } return tokens; }
/// <summary> /// Writes credentials for a target URI to the credential store /// </summary> /// <param name="targetUri">The URI of the target for which credentials are being stored</param> /// <param name="credentials">The credentials to be stored</param> public void WriteCredentials(TargetUri targetUri, Credential credentials) { ValidateTargetUri(targetUri); Credential.Validate(credentials); Trace.WriteLine("CredentialStore::WriteCredentials"); string targetName = this.GetTargetName(targetUri); this.WriteCredential(targetName, credentials); _credentialCache.WriteCredentials(targetUri, credentials); }
internal static extern bool CredWrite(ref Credential credential, UInt32 flags);
/// <summary> /// Writes credentials for a target URI to the credential store /// </summary> /// <param name="targetUri">The URI of the target for which credentials are being stored</param> /// <param name="credentials">The credentials to be stored</param> public void WriteCredentials(TargetUri targetUri, Credential credentials) { ValidateTargetUri(targetUri); BaseSecureStore.ValidateCredential(credentials); string targetName = this.GetTargetName(targetUri); this.WriteCredential(targetName, credentials); _credentialCache.WriteCredentials(targetUri, credentials); }
/// <summary> /// Validates that a set of credentials grants access to the target resource. /// </summary> /// <param name="targetUri">The target resource to validate against.</param> /// <param name="credentials">The credentials to validate.</param> /// <returns><see langword="true"/> if successful; <see langword="false"/> otherwise.</returns> public async Task <bool> ValidateCredentials(TargetUri targetUri, Credential credentials) { return(await this.VstsAuthority.ValidateCredentials(targetUri, credentials)); }