mirror of
https://github.com/sshnet/SSH.NET.git
synced 2026-09-10 09:15:47 +00:00
Merge remote-tracking branch 'refs/remotes/origin/develop'
This commit is contained in:
@@ -16,4 +16,7 @@
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_ARGUMENTS_STYLE/@EntryValue">CHOP_IF_LONG</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=HMACMD/@EntryIndexedValue">HMACMD</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=HMACSHA/@EntryIndexedValue">HMACSHA</s:String>
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EAddAccessorOwnerDeclarationBracesMigration/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateThisQualifierSettings/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:String x:Key="/Default/Environment/UnitTesting/ExcludedCategoriesList/@EntryValue">integration,LongRunning</s:String></wpf:ResourceDictionary>
|
||||
@@ -46,10 +46,10 @@ namespace Renci.SshNet
|
||||
|
||||
}
|
||||
|
||||
private bool TryAuthenticate(ISession session,
|
||||
AuthenticationState authenticationState,
|
||||
ICollection<string> allowedAuthenticationMethods,
|
||||
ref SshAuthenticationException authenticationException)
|
||||
private static bool TryAuthenticate(ISession session,
|
||||
AuthenticationState authenticationState,
|
||||
ICollection<string> allowedAuthenticationMethods,
|
||||
ref SshAuthenticationException authenticationException)
|
||||
{
|
||||
if (allowedAuthenticationMethods.Count == 0)
|
||||
{
|
||||
|
||||
@@ -57,15 +57,16 @@ namespace Renci.SshNet
|
||||
session.UserAuthenticationFailureReceived += Session_UserAuthenticationFailureReceived;
|
||||
session.MessageReceived += Session_MessageReceived;
|
||||
|
||||
session.RegisterMessage("SSH_MSG_USERAUTH_INFO_REQUEST");
|
||||
|
||||
try
|
||||
{
|
||||
session.RegisterMessage("SSH_MSG_USERAUTH_INFO_REQUEST");
|
||||
session.SendMessage(_requestMessage);
|
||||
session.WaitOnHandle(_authenticationCompleted);
|
||||
session.UnRegisterMessage("SSH_MSG_USERAUTH_INFO_REQUEST");
|
||||
}
|
||||
finally
|
||||
{
|
||||
session.UnRegisterMessage("SSH_MSG_USERAUTH_INFO_REQUEST");
|
||||
session.UserAuthenticationSuccessReceived -= Session_UserAuthenticationSuccessReceived;
|
||||
session.UserAuthenticationFailureReceived -= Session_UserAuthenticationFailureReceived;
|
||||
session.MessageReceived -= Session_MessageReceived;
|
||||
|
||||
@@ -89,6 +89,7 @@ namespace Renci.SshNet
|
||||
}
|
||||
finally
|
||||
{
|
||||
session.UnRegisterMessage("SSH_MSG_USERAUTH_PASSWD_CHANGEREQ");
|
||||
session.UserAuthenticationSuccessReceived -= Session_UserAuthenticationSuccessReceived;
|
||||
session.UserAuthenticationFailureReceived -= Session_UserAuthenticationFailureReceived;
|
||||
session.MessageReceived -= Session_MessageReceived;
|
||||
|
||||
@@ -60,55 +60,65 @@ namespace Renci.SshNet
|
||||
|
||||
session.RegisterMessage("SSH_MSG_USERAUTH_PK_OK");
|
||||
|
||||
foreach (var keyFile in KeyFiles)
|
||||
try
|
||||
{
|
||||
_authenticationCompleted.Reset();
|
||||
_isSignatureRequired = false;
|
||||
|
||||
var message = new RequestMessagePublicKey(ServiceName.Connection, Username, keyFile.HostKey.Name, keyFile.HostKey.Data);
|
||||
|
||||
if (KeyFiles.Count < 2)
|
||||
{
|
||||
// If only one key file provided then send signature for very first request
|
||||
var signatureData = new SignatureData(message, session.SessionId).GetBytes();
|
||||
|
||||
message.Signature = keyFile.HostKey.Sign(signatureData);
|
||||
}
|
||||
|
||||
// Send public key authentication request
|
||||
session.SendMessage(message);
|
||||
|
||||
session.WaitOnHandle(_authenticationCompleted);
|
||||
|
||||
if (_isSignatureRequired)
|
||||
foreach (var keyFile in KeyFiles)
|
||||
{
|
||||
_authenticationCompleted.Reset();
|
||||
_isSignatureRequired = false;
|
||||
|
||||
var signatureMessage = new RequestMessagePublicKey(ServiceName.Connection, Username, keyFile.HostKey.Name, keyFile.HostKey.Data);
|
||||
var message = new RequestMessagePublicKey(ServiceName.Connection,
|
||||
Username,
|
||||
keyFile.HostKey.Name,
|
||||
keyFile.HostKey.Data);
|
||||
|
||||
var signatureData = new SignatureData(message, session.SessionId).GetBytes();
|
||||
if (KeyFiles.Count < 2)
|
||||
{
|
||||
// If only one key file provided then send signature for very first request
|
||||
var signatureData = new SignatureData(message, session.SessionId).GetBytes();
|
||||
|
||||
signatureMessage.Signature = keyFile.HostKey.Sign(signatureData);
|
||||
message.Signature = keyFile.HostKey.Sign(signatureData);
|
||||
}
|
||||
|
||||
// Send public key authentication request with signature
|
||||
session.SendMessage(signatureMessage);
|
||||
// Send public key authentication request
|
||||
session.SendMessage(message);
|
||||
|
||||
session.WaitOnHandle(_authenticationCompleted);
|
||||
|
||||
if (_isSignatureRequired)
|
||||
{
|
||||
_authenticationCompleted.Reset();
|
||||
|
||||
var signatureMessage = new RequestMessagePublicKey(ServiceName.Connection,
|
||||
Username,
|
||||
keyFile.HostKey.Name,
|
||||
keyFile.HostKey.Data);
|
||||
|
||||
var signatureData = new SignatureData(message, session.SessionId).GetBytes();
|
||||
|
||||
signatureMessage.Signature = keyFile.HostKey.Sign(signatureData);
|
||||
|
||||
// Send public key authentication request with signature
|
||||
session.SendMessage(signatureMessage);
|
||||
}
|
||||
|
||||
session.WaitOnHandle(_authenticationCompleted);
|
||||
|
||||
if (_authenticationResult == AuthenticationResult.Success)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
session.WaitOnHandle(_authenticationCompleted);
|
||||
|
||||
if (_authenticationResult == AuthenticationResult.Success)
|
||||
{
|
||||
break;
|
||||
}
|
||||
return _authenticationResult;
|
||||
}
|
||||
finally
|
||||
{
|
||||
session.UserAuthenticationSuccessReceived -= Session_UserAuthenticationSuccessReceived;
|
||||
session.UserAuthenticationFailureReceived -= Session_UserAuthenticationFailureReceived;
|
||||
session.MessageReceived -= Session_MessageReceived;
|
||||
session.UnRegisterMessage("SSH_MSG_USERAUTH_PK_OK");
|
||||
}
|
||||
|
||||
session.UserAuthenticationSuccessReceived -= Session_UserAuthenticationSuccessReceived;
|
||||
session.UserAuthenticationFailureReceived -= Session_UserAuthenticationFailureReceived;
|
||||
session.MessageReceived -= Session_MessageReceived;
|
||||
|
||||
session.UnRegisterMessage("SSH_MSG_USERAUTH_PK_OK");
|
||||
|
||||
return _authenticationResult;
|
||||
}
|
||||
|
||||
private void Session_UserAuthenticationSuccessReceived(object sender, MessageEventArgs<SuccessMessage> e)
|
||||
@@ -168,8 +178,8 @@ namespace Renci.SshNet
|
||||
var authenticationCompleted = _authenticationCompleted;
|
||||
if (authenticationCompleted != null)
|
||||
{
|
||||
authenticationCompleted.Dispose();
|
||||
_authenticationCompleted = null;
|
||||
authenticationCompleted.Dispose();
|
||||
}
|
||||
|
||||
_isDisposed = true;
|
||||
@@ -243,6 +253,5 @@ namespace Renci.SshNet
|
||||
WriteBinaryString(_message.PublicKeyData);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,17 +65,14 @@ namespace Renci.SshNet.Security
|
||||
{
|
||||
var exchangeHash = CalculateHash();
|
||||
|
||||
var length = (uint)(_hostKey[0] << 24 | _hostKey[1] << 16 | _hostKey[2] << 8 | _hostKey[3]);
|
||||
|
||||
var length = (uint) (_hostKey[0] << 24 | _hostKey[1] << 16 | _hostKey[2] << 8 | _hostKey[3]);
|
||||
var algorithmName = Encoding.UTF8.GetString(_hostKey, 4, (int)length);
|
||||
|
||||
var key = Session.ConnectionInfo.HostKeyAlgorithms[algorithmName](_hostKey);
|
||||
|
||||
Session.ConnectionInfo.CurrentHostKeyAlgorithm = algorithmName;
|
||||
|
||||
if (CanTrustHostKey(key))
|
||||
{
|
||||
|
||||
return key.VerifySignature(exchangeHash, _signature);
|
||||
}
|
||||
return false;
|
||||
@@ -113,7 +110,7 @@ namespace Renci.SshNet.Security
|
||||
|
||||
_clientExchangeValue = BigInteger.ModPow(_group, _randomValue, _prime);
|
||||
|
||||
} while (_clientExchangeValue < 1 || _clientExchangeValue > ((_prime - 1)));
|
||||
} while (_clientExchangeValue < 1 || _clientExchangeValue > (_prime - 1));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -50,11 +50,10 @@ namespace Renci.SshNet.Security
|
||||
base.Start(session, message);
|
||||
|
||||
Session.RegisterMessage("SSH_MSG_KEX_DH_GEX_GROUP");
|
||||
Session.RegisterMessage("SSH_MSG_KEX_DH_GEX_REPLY");
|
||||
|
||||
Session.MessageReceived += Session_MessageReceived;
|
||||
|
||||
// 1. send SSH_MSG_KEY_DH_GEX_REQUEST
|
||||
// 1. client sends SSH_MSG_KEY_DH_GEX_REQUEST
|
||||
SendMessage(new KeyExchangeDhGroupExchangeRequest(MinimumGroupSize, PreferredGroupSize,
|
||||
MaximumProupSize));
|
||||
}
|
||||
@@ -71,34 +70,38 @@ namespace Renci.SshNet.Security
|
||||
|
||||
private void Session_MessageReceived(object sender, MessageEventArgs<Message> e)
|
||||
{
|
||||
// 2. server sends SSH_MSG_KEX_DH_GEX_GROUP
|
||||
var groupMessage = e.Message as KeyExchangeDhGroupExchangeGroup;
|
||||
if (groupMessage != null)
|
||||
{
|
||||
// Unregister message once received
|
||||
// Unregister SSH_MSG_KEX_DH_GEX_GROUP message once received
|
||||
Session.UnRegisterMessage("SSH_MSG_KEX_DH_GEX_GROUP");
|
||||
// Register in order to be able to receive SSH_MSG_KEX_DH_GEX_REPLY message
|
||||
Session.RegisterMessage("SSH_MSG_KEX_DH_GEX_REPLY");
|
||||
|
||||
// 2. Receive SSH_MSG_KEX_DH_GEX_GROUP
|
||||
_prime = groupMessage.SafePrime;
|
||||
_group = groupMessage.SubGroup;
|
||||
|
||||
PopulateClientExchangeValue();
|
||||
|
||||
// 3. Send SSH_MSG_KEX_DH_GEX_INIT
|
||||
// 3. client sends SSH_MSG_KEX_DH_GEX_INIT
|
||||
SendMessage(new KeyExchangeDhGroupExchangeInit(_clientExchangeValue));
|
||||
|
||||
// Skip further execution as we'll be waiting for the SSH_MSG_KEX_DH_GEX_REPLY message
|
||||
return;
|
||||
}
|
||||
else
|
||||
|
||||
// 4. server sends SSH_MSG_KEX_DH_GEX_REPLY
|
||||
var replyMessage = e.Message as KeyExchangeDhGroupExchangeReply;
|
||||
if (replyMessage != null)
|
||||
{
|
||||
var replyMessage = e.Message as KeyExchangeDhGroupExchangeReply;
|
||||
if (replyMessage != null)
|
||||
{
|
||||
// Unregister message once received
|
||||
Session.UnRegisterMessage("SSH_MSG_KEX_DH_GEX_REPLY");
|
||||
// Unregister SSH_MSG_KEX_DH_GEX_REPLY message once received
|
||||
Session.UnRegisterMessage("SSH_MSG_KEX_DH_GEX_REPLY");
|
||||
|
||||
HandleServerDhReply(replyMessage.HostKey, replyMessage.F, replyMessage.Signature);
|
||||
HandleServerDhReply(replyMessage.HostKey, replyMessage.F, replyMessage.Signature);
|
||||
|
||||
// When SSH_MSG_KEX_DH_GEX_REPLY received key exchange is completed
|
||||
Finish();
|
||||
}
|
||||
// When SSH_MSG_KEX_DH_GEX_REPLY received key exchange is completed
|
||||
Finish();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,13 +55,11 @@ namespace Renci.SshNet.Security
|
||||
Session.MessageReceived += Session_MessageReceived;
|
||||
|
||||
_prime = GroupPrime;
|
||||
|
||||
_group = new BigInteger(new byte[] { 2 });
|
||||
|
||||
PopulateClientExchangeValue();
|
||||
|
||||
SendMessage(new KeyExchangeDhInitMessage(_clientExchangeValue));
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
Reference in New Issue
Block a user