<PackageReference Include="SSH.NET" Version="2016.0.0" />

ClientAuthentication

using Renci.SshNet.Common; using System; using System.Collections.Generic; using System.Linq; namespace Renci.SshNet { internal class ClientAuthentication : IClientAuthentication { private class AuthenticationState { private readonly IList<IAuthenticationMethod> _supportedAuthenticationMethods; public IList<IAuthenticationMethod> ExecutedAuthenticationMethods { get; set; } public IList<IAuthenticationMethod> FailedAuthenticationMethods { get; set; } public IEnumerable<IAuthenticationMethod> SupportedAuthenticationMethods => _supportedAuthenticationMethods; public AuthenticationState(IList<IAuthenticationMethod> supportedAuthenticationMethods) { _supportedAuthenticationMethods = supportedAuthenticationMethods; ExecutedAuthenticationMethods = new List<IAuthenticationMethod>(); FailedAuthenticationMethods = new List<IAuthenticationMethod>(); } } public void Authenticate(IConnectionInfoInternal connectionInfo, ISession session) { if (connectionInfo == null) throw new ArgumentNullException("connectionInfo"); if (session == null) throw new ArgumentNullException("session"); session.RegisterMessage("SSH_MSG_USERAUTH_FAILURE"); session.RegisterMessage("SSH_MSG_USERAUTH_SUCCESS"); session.RegisterMessage("SSH_MSG_USERAUTH_BANNER"); session.UserAuthenticationBannerReceived += connectionInfo.UserAuthenticationBannerReceived; try { SshAuthenticationException authenticationException = null; IAuthenticationMethod authenticationMethod = connectionInfo.CreateNoneAuthenticationMethod(); if (authenticationMethod.Authenticate(session) != 0 && !TryAuthenticate(session, new AuthenticationState(connectionInfo.AuthenticationMethods), authenticationMethod.AllowedAuthentications.ToList(), ref authenticationException)) throw authenticationException; } finally { session.UserAuthenticationBannerReceived -= connectionInfo.UserAuthenticationBannerReceived; session.UnRegisterMessage("SSH_MSG_USERAUTH_FAILURE"); session.UnRegisterMessage("SSH_MSG_USERAUTH_SUCCESS"); session.UnRegisterMessage("SSH_MSG_USERAUTH_BANNER"); } } private static bool TryAuthenticate(ISession session, AuthenticationState authenticationState, ICollection<string> allowedAuthenticationMethods, ref SshAuthenticationException authenticationException) { if (allowedAuthenticationMethods.Count == 0) { authenticationException = new SshAuthenticationException("No authentication methods defined on SSH server."); return false; } List<IAuthenticationMethod> list = (from a in authenticationState.SupportedAuthenticationMethods where allowedAuthenticationMethods.Contains(a.Name) select a).ToList(); if (list.Count == 0) { authenticationException = new SshAuthenticationException(string.Format("No suitable authentication method found to complete authentication ({0}).", string.Join(",", allowedAuthenticationMethods.ToArray()))); return false; } foreach (IAuthenticationMethod orderedAuthenticationMethod in GetOrderedAuthenticationMethods(authenticationState, list)) { if (!authenticationState.FailedAuthenticationMethods.Contains(orderedAuthenticationMethod)) { if (!authenticationState.ExecutedAuthenticationMethods.Contains(orderedAuthenticationMethod)) authenticationState.ExecutedAuthenticationMethods.Add(orderedAuthenticationMethod); AuthenticationResult authenticationResult = orderedAuthenticationMethod.Authenticate(session); switch (authenticationResult) { case AuthenticationResult.PartialSuccess: if (TryAuthenticate(session, authenticationState, orderedAuthenticationMethod.AllowedAuthentications, ref authenticationException)) authenticationResult = AuthenticationResult.Success; break; case AuthenticationResult.Failure: authenticationState.FailedAuthenticationMethods.Add(orderedAuthenticationMethod); authenticationException = new SshAuthenticationException($"""{orderedAuthenticationMethod.Name}"""); break; case AuthenticationResult.Success: authenticationException = null; break; } if (authenticationResult == AuthenticationResult.Success) return true; } } return false; } private static IEnumerable<IAuthenticationMethod> GetOrderedAuthenticationMethods(AuthenticationState authenticationState, IEnumerable<IAuthenticationMethod> matchingAuthenticationMethods) { List<IAuthenticationMethod> skippedAuthenticationMethods = new List<IAuthenticationMethod>(); foreach (IAuthenticationMethod matchingAuthenticationMethod in matchingAuthenticationMethods) { if (authenticationState.ExecutedAuthenticationMethods.Contains(matchingAuthenticationMethod)) skippedAuthenticationMethods.Add(matchingAuthenticationMethod); else yield return matchingAuthenticationMethod; } List<IAuthenticationMethod>.Enumerator enumerator2 = skippedAuthenticationMethods.GetEnumerator(); try { while (enumerator2.MoveNext()) { IAuthenticationMethod current2 = enumerator2.Current; yield return current2; } } finally { ((IDisposable)enumerator2).Dispose(); } enumerator2 = default(List<IAuthenticationMethod>.Enumerator); } } }