Add AuthenticationEventArgs inherited classes to suport different authentication scenarios where user input is needed or additional information is available

This commit is contained in:
olegkap_cp
2010-12-22 18:44:22 +00:00
parent f0422f9151
commit 8aa21ae400
8 changed files with 122 additions and 26 deletions
@@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Renci.SshClient.Common
{
public class AuthenticationBannerEventArgs : AuthenticationEventArgs
{
public string BannerMessage { get; private set; }
public string Language { get; private set; }
public AuthenticationBannerEventArgs(string username, string message, string language)
: base(username)
{
this.BannerMessage = message;
this.Language = language;
}
}
}
@@ -6,27 +6,13 @@ using Renci.SshClient.Messages.Authentication;
namespace Renci.SshClient.Common
{
public class AuthenticationEventArgs : EventArgs
public abstract class AuthenticationEventArgs : EventArgs
{
public string BannerMessage { get; private set; }
public string Username { get; private set; }
public string Language { get; private set; }
public string Instruction { get; private set; }
public IEnumerable<AuthenticationPrompt> Prompts { get; private set; }
public AuthenticationEventArgs(string message, string language)
public AuthenticationEventArgs(string username)
{
this.BannerMessage = message;
this.Language = language;
}
public AuthenticationEventArgs(string instruction, string language, IEnumerable<AuthenticationPrompt> prompts)
{
this.Instruction = instruction;
this.Language = language;
this.Prompts = prompts;
this.Username = username;
}
}
}
@@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Renci.SshClient.Common
{
public class AuthenticationPasswordChangeEventArgs : AuthenticationEventArgs
{
public string NewPassword { get; set; }
public AuthenticationPasswordChangeEventArgs(string username)
: base(username)
{
}
}
}
@@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Renci.SshClient.Common
{
public class AuthenticationPromptEventArgs : AuthenticationEventArgs
{
public string Language { get; private set; }
public string Instruction { get; private set; }
public IEnumerable<AuthenticationPrompt> Prompts { get; private set; }
public AuthenticationPromptEventArgs(string username, string instruction, string language, IEnumerable<AuthenticationPrompt> prompts)
: base(username)
{
this.Instruction = instruction;
this.Language = language;
this.Prompts = prompts;
}
}
}
@@ -60,7 +60,10 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Common\AuthenticationBannerEventArgs.cs" />
<Compile Include="Common\AuthenticationEventArgs.cs" />
<Compile Include="Common\AuthenticationPasswordChangeEventArgs.cs" />
<Compile Include="Common\AuthenticationPromptEventArgs.cs" />
<Compile Include="Common\AuthenticationPrompt.cs" />
<Compile Include="Common\ChannelDataEventArgs.cs" />
<Compile Include="Common\ChannelEventArgs.cs" />
@@ -63,7 +63,7 @@ namespace Renci.SshClient.Security
protected virtual void Session_UserAuthenticationBannerMessageReceived(object sender, MessageEventArgs<BannerMessage> e)
{
RaiseAuthenticating(new AuthenticationEventArgs(e.Message.Message, e.Message.Language));
RaiseAuthenticating(new AuthenticationBannerEventArgs(this.Username, e.Message.Message, e.Message.Language));
}
protected void RaiseAuthenticating(AuthenticationEventArgs args)
@@ -59,7 +59,7 @@ namespace Renci.SshClient.Security
var informationRequestMessage = e.Message as InformationRequestMessage;
if (informationRequestMessage != null)
{
var eventArgs = new AuthenticationEventArgs(informationRequestMessage.Instruction, informationRequestMessage.Language, informationRequestMessage.Prompts);
var eventArgs = new AuthenticationPromptEventArgs(this.Username, informationRequestMessage.Instruction, informationRequestMessage.Language, informationRequestMessage.Prompts);
var eventTask = Task.Factory.StartNew(() =>
{
@@ -2,6 +2,8 @@
using System.Threading;
using Renci.SshClient.Messages;
using Renci.SshClient.Messages.Authentication;
using System.Threading.Tasks;
using Renci.SshClient.Common;
namespace Renci.SshClient.Security
{
@@ -9,6 +11,10 @@ namespace Renci.SshClient.Security
{
private EventWaitHandle _authenticationCompleted = new AutoResetEvent(false);
private Exception _exception;
private PasswordConnectionInfo _connectionInfo;
public override string Name
{
get
@@ -19,22 +25,26 @@ namespace Renci.SshClient.Security
protected override void OnAuthenticate()
{
var passwordConnectionInfo = this.Session.ConnectionInfo as PasswordConnectionInfo;
this._connectionInfo = this.Session.ConnectionInfo as PasswordConnectionInfo;
if (passwordConnectionInfo == null)
if (this._connectionInfo == null)
return;
// TODO: Handle PasswordChangeRequiredMessage authentication message
//Message.RegisterMessageType<PasswordChangeRequiredMessage>(MessageTypes.UserAuthenticationPasswordChangeRequired);
this.Session.RegisterMessageType<PasswordChangeRequiredMessage>(MessageTypes.UserAuthenticationPasswordChangeRequired);
this.SendMessage(new RequestMessagePassword
{
ServiceName = ServiceNames.Connection,
Username = this.Username,
Password = passwordConnectionInfo.Password ?? string.Empty,
Password = this._connectionInfo.Password ?? string.Empty,
});
this.WaitHandle(this._authenticationCompleted);
if (this._exception != null)
{
throw this._exception;
}
}
protected override void Session_UserAuthenticationSuccessMessageReceived(object sender, MessageEventArgs<SuccessMessage> e)
@@ -49,6 +59,41 @@ namespace Renci.SshClient.Security
this._authenticationCompleted.Set();
}
protected override void Session_MessageReceived(object sender, MessageEventArgs<Message> e)
{
base.Session_MessageReceived(sender, e);
if (e.Message is PasswordChangeRequiredMessage)
{
this.Session.UnRegisterMessageType(MessageTypes.UserAuthenticationPasswordChangeRequired);
var eventTask = Task.Factory.StartNew(() =>
{
try
{
var eventArgs = new AuthenticationPasswordChangeEventArgs(this.Username);
// Raise an event to allow user to supply a new password
this.RaiseAuthenticating(eventArgs);
// Send new authentication request with new password
this.SendMessage(new RequestMessagePassword
{
ServiceName = ServiceNames.Connection,
Username = this.Username,
Password = this._connectionInfo.Password ?? string.Empty,
NewPassword = eventArgs.NewPassword ?? string.Empty,
});
}
catch (Exception exp)
{
this._exception = exp;
this._authenticationCompleted.Set();
}
});
}
}
#region IDisposable Members
private bool isDisposed = false;