Open aoemam opened 4 years ago
1 note for the above issue that the connection is done but the exception appears once i run any command
Try these steps, let me know what happens.
const string Command_Prompt = @".*\?:|[$#]|\[.*@(.*?)\][$%#]";
protected void HandleKeyEvent(object sender, AuthenticationPromptEventArgs e)
{
foreach (AuthenticationPrompt prompt in e.Prompts)
{
if (prompt.Request.IndexOf("Password:", StringComparison.InvariantCultureIgnoreCase) != -1)
{
if (DataFiles.CheckPass())
prompt.Response = Defs.PassWord;
}
}
}
Your method....
//account setup..
KeyboardInteractiveAuthenticationMethod kauth = new KeyboardInteractiveAuthenticationMethod(Defs.UserName);
PasswordAuthenticationMethod pauth = new PasswordAuthenticationMethod(Defs.UserName, Defs.PassWord);
kauth.AuthenticationPrompt += new EventHandler<AuthenticationPromptEventArgs>(HandleKeyEvent);
//setup connection
ConnectionInfo connectionInfo = new ConnectionInfo(Defs.HostName, Defs.Port, Defs.UserName, pauth, kauth);
connectionInfo.Timeout = Defs.ConnectionTimeout;
//pass connection data
SshClient _sshClient = new SshClient(connectionInfo);
//let the user know what we are doing.
Log.Verbose("Attempting to connect...");
//connect to linux
_sshClient.Connect();
//let the user know what we are doing.
Log.Verbose("Connected, creating shell stream...", ConsoleColor.Green);
//lets build out a stream that will each back what we request.
var terminalMode = new Dictionary<TerminalModes, uint>();
//create shell stream
ShellStream _shellStream = _sshClient.CreateShellStream("input", 255, 50, 400, 600, 4096, terminalMode);
//setup for prompt
var promptRegex = new Regex(Command_Prompt);
//send a command
_shellStream.WriteLine("ls -ltr");
//look for prompt
var output = _shellStream.Expect(promptRegex);
//log output
Log.Verbose(output);
You will obviously have to put in your own variables for Defs.vars, I have in the above code. This is something I use and never get rejected.
You will obviously have to put in your own variables for Defs.vars, I have in the above code. This is something I use and never get rejected.
Hello gavin1970, thanks for your reply, but i need more details about what i have to add actually i did not get you what do you mean by Defs.vars ? appreciate if you provide me with example code or update the above code so i can understand thanks again and your support is highly appreciated
Defs is just my class and properties. Based on the property name you can tell what you can replace it with.
Hello gavin1970, actually it gives the same because i have a problem in key exchange when i am using putty it asked me for the first time to add the fingerprint key that coming from the server to putty's cache actually i need to know how to do the same in renci SSH.net how to automatically add the server key and carry it with the connection
Sounds like you need to alter your ssh config that holds your keys. Delete that sever info from it.
Sounds like you need to alter your ssh config that holds your keys. Delete that sever info from it.
actually i do not hold the key that coming from the server, so i need to know how to receive the key that coming from the server and how to pass it to the connection so once i connect and send command the server can trust me (as per the log now i am not trusted at the server side)
below is a sample code from another tool that doing the same what i need to do exactly
this thirdparty control called DART (https://www.dart.com/products/powertcp-ssh-and-sftp-for-net#overview)
private void ssh1_HostKey(object sender, HostKeyEventArgs e) { if (sshModel.ValidateServerHostKey(ssh1.Connection.RemoteEndPoint.ToString(), e.HostKey)) e.Verified = true; else { //Generate SHA256 and MD5 hashes string md5Hash = SshModel.GetMd5Hash(e.HostKey); string sha256Hash = SshModel.GetSha256Hash(e.HostKey);
bool serverKnown = sshModel.AcceptedServerHostKeyCacheDict.ContainsKey(ssh1.Connection.RemoteEndPoint.ToString());
string initialMessage = serverKnown ? "WARNING: The server's host key has changed." : "The server's host key is unknown.";
DialogResult hostKeyResult = MessageBox.Show(initialMessage + Environment.NewLine +
"Host: " + ssh1.Connection.RemoteEndPoint.ToString() + Environment.NewLine +
"Host Key Algorithm: " + e.HostKeyAlgorithm + Environment.NewLine +
"MD5 Hash: " + md5Hash + Environment.NewLine +
"SHA256 Hash: " + sha256Hash + Environment.NewLine + Environment.NewLine +
"Always trust this host - host key pair?",
"Unknown Server Host Key", MessageBoxButtons.YesNoCancel, serverKnown ? MessageBoxIcon.Exclamation : MessageBoxIcon.Information);
if (hostKeyResult == System.Windows.Forms.DialogResult.Yes)
{
if (sshModel.AcceptedServerHostKeyCacheDict.ContainsKey(ssh1.Connection.RemoteEndPoint.ToString()))
sshModel.AcceptedServerHostKeyCacheDict[ssh1.Connection.RemoteEndPoint.ToString()] = e.HostKey;
else
sshModel.AcceptedServerHostKeyCacheDict.Add(ssh1.Connection.RemoteEndPoint.ToString(), e.HostKey);
e.Verified = true;
}
else if (hostKeyResult == System.Windows.Forms.DialogResult.No)
e.Verified = true;
//else if (hostKeyResult == System.Windows.Forms.DialogResult.Cancel): e.Verified is already false.
}
}
Oddly enough, I dont ever do anything with keys and never have an issue. I connect to many different servers Ive never connect to and no key issues. Then Ill try the command line ssh user@server passing password and it prompts for authorization. Never understood it, but only know of the issues for when I see putty so I end up deleting the id_rsa file locally so it doesnt conflict. But even when that is in conflict my code allows me to connect, only blocks putty. Figured Im just lucky that way. Ha.
my be the servers that you ssh dose not request authentication using keys, in my case the server dose not accept any command till i do the same above with the shared code from DART, its like a certificate to communicate with the server if you accepted this certificate you can communicate otherwise server automatically abort your connection
Thats what I get from putty or command line.
any one can support please
@aoemam Please provide the following information:
Can you reproduce this issue consistently? Would it be possible to give me access to a test server against which you can reproduce the issue? It this is possible, please send me the connection details offline.
Im guessing no-one supports these requests as Ive not seen any answer to mine from a while back. I come up with my own solutions. It is open source, so maybe look and see what the underlying problem Is yourself?
@gavin1970 I'm sorry to hear this, but - given the limited time I have to work on SSH.NET - I'm not really surprised. Do you have an issue that you want me to look at?
Timeout was never working on the expects. I ended up threading it off and holding my event wait timer on it.
@gavin1970 To be honest, ShellStream could use a lot of love.
@aoemam Please provide the following information:
- Version of SSH.NET
- Key exchange algorithm You can use .ConnectionInfo.CurrentKeyExchangeAlgorithm to obtain this information.
Can you reproduce this issue consistently? Would it be possible to give me access to a test server against which you can reproduce the issue? It this is possible, please send me the connection details offline.
Dear Drieseng, thanks more for your replay, the ConnectionInfo.CurrentKeyExchangeAlgorithm is diffie-hellman-group-exchange-sha256 and i am using now SSH.Net V 2016.1.0 Latest Version, i am also tried the SSH.Net V 2020.0.0 Beta Version and also the same the connection to the device done successfully but once i send any command the connection aborted by the server as the below log Sep 7 17:21:21.228 [GENERAL] [ERROR] SSH_input_control[0]: key exchange failed for instance: 4568 status: -5904 Sep 7 17:21:21.228 [GENERAL] [] SSH_input_control[0]: connection id: 0 exiting... Sep 7 17:21:21.228 [GENERAL] [ERROR] SSH_cleanup[0]: SSH/SFTP: unverified session terminated
for the ability to give you access unfortunately they prevent that due to security reasons
again you support is highly appreciated
@aoemam It's extremely hard to diagnose such issues without access to a machine that allows one to reproduce the problem. You have no issues if you use another (commercial or OSS) SSH client?
aoemam, try using ssh at the command line manually and see what happens. All windows machines after Win7 have it. Example: ssh user@severname
Sounds like you need to alter your ssh config that holds your keys. Delete that sever info from it.
actually i do not hold the key that coming from the server, so i need to know how to receive the key that coming from the server and how to pass it to the connection so once i connect and send command the server can trust me (as per the log now i am not trusted at the server side)
below is a sample code from another tool that doing the same what i need to do exactly
this thirdparty control called DART (https://www.dart.com/products/powertcp-ssh-and-sftp-for-net#overview)
private void ssh1_HostKey(object sender, HostKeyEventArgs e) { if (sshModel.ValidateServerHostKey(ssh1.Connection.RemoteEndPoint.ToString(), e.HostKey)) e.Verified = true; else { //Generate SHA256 and MD5 hashes string md5Hash = SshModel.GetMd5Hash(e.HostKey); string sha256Hash = SshModel.GetSha256Hash(e.HostKey);
bool serverKnown = sshModel.AcceptedServerHostKeyCacheDict.ContainsKey(ssh1.Connection.RemoteEndPoint.ToString()); string initialMessage = serverKnown ? "WARNING: The server's host key has changed." : "The server's host key is unknown."; DialogResult hostKeyResult = MessageBox.Show(initialMessage + Environment.NewLine + "Host: " + ssh1.Connection.RemoteEndPoint.ToString() + Environment.NewLine + "Host Key Algorithm: " + e.HostKeyAlgorithm + Environment.NewLine + "MD5 Hash: " + md5Hash + Environment.NewLine + "SHA256 Hash: " + sha256Hash + Environment.NewLine + Environment.NewLine + "Always trust this host - host key pair?", "Unknown Server Host Key", MessageBoxButtons.YesNoCancel, serverKnown ? MessageBoxIcon.Exclamation : MessageBoxIcon.Information); if (hostKeyResult == System.Windows.Forms.DialogResult.Yes) { if (sshModel.AcceptedServerHostKeyCacheDict.ContainsKey(ssh1.Connection.RemoteEndPoint.ToString())) sshModel.AcceptedServerHostKeyCacheDict[ssh1.Connection.RemoteEndPoint.ToString()] = e.HostKey; else sshModel.AcceptedServerHostKeyCacheDict.Add(ssh1.Connection.RemoteEndPoint.ToString(), e.HostKey); e.Verified = true; } else if (hostKeyResult == System.Windows.Forms.DialogResult.No) e.Verified = true; //else if (hostKeyResult == System.Windows.Forms.DialogResult.Cancel): e.Verified is already false. } }
@drieseng take a look at the above comment i give an example from another tool DART it's working fine they working with HostKey event once host key received they do the above sort of code to add this key as trusted @gavin1970 also its working fine from putty as i mentioned before but under one condition the putty asks first the below message The server's host key is not cached in the registry. You have no guarantee that the server is the computer you think it is. The server's rsa2 key fingerprint is: ssh-rsa 1023 a0:71:de:c9:a6:ca:f3:90:5b:84:a9:84:b5:bc:83:de If you trust this host, enter "y" to add the key to PuTTY's cache and carry on connecting. If you want to carry on connecting just once, without adding the key to the cache, enter "n". If you do not trust this host, press Return to abandon the connection. Store key in cache? (y/n) if i click yes it cashes this host key if i click no it will trust it for one time only and next time asks me again if i click cancel it will do as what happened with me using Renci ssh.net that mean it will abort the connection
@gavin1970 Hello Gavin, Thanks for your support i have another case but this time the server dose not connect by the simple way connection it gives me No suitable authentication method found to complete authentication (publickey,gssapi-keyex,gssapi-with-mic,keyboard-interactive).
this time i tried your way of connection through shellstream and working fine but i need your support for 1 thing i need to read the shellstream async if i use var output = _shellStream.Expect(promptRegex); it dose not give me the whole result because the stream still reading actually how to use _shellStream.ReadAsync Method Appreciate your support
Sure.. This is sudo code, but it should help.
var output = _shellStream.Expect(promptRegex, timeOut);
while (_shellStream.DataAvailable)
{
string data = _shellStream.Read();
if (output.Length == 0)
output = data;
Log.Verbose(output);
output = "";
}
//clears all buffers, we should be done.
_shellStream.Flush();
aoemam, I uploaded my full project. Maybe some of it can help you. https://github.com/gavin1970/Linux-Commander
aoemam, I uploaded my full project. Maybe some of if can help you. https://github.com/gavin1970/Linux-Commander
thanks @gavin1970 , really you support is highly appreciated
Sure.. This is sudo code, but it should help.
var output = _shellStream.Expect(promptRegex, timeOut); while (_shellStream.DataAvailable) { string data = _shellStream.Read(); if (output.Length == 0) output = data; Log.Verbose(output); output = ""; } //clears all buffers, we should be done. _shellStream.Flush();
Hello @gavin1970 regarding this case i am getting Warning, can't fully initialize terminal, TERM is set to "input", status (0) do you have any idea about this message
Flush isn't required. You ca comment it.
Try these steps, let me know what happens.
const string Command_Prompt = @".*\?:|[$#]|\[.*@(.*?)\][$%#]"; protected void HandleKeyEvent(object sender, AuthenticationPromptEventArgs e) { foreach (AuthenticationPrompt prompt in e.Prompts) { if (prompt.Request.IndexOf("Password:", StringComparison.InvariantCultureIgnoreCase) != -1) { if (DataFiles.CheckPass()) prompt.Response = Defs.PassWord; } } } Your method.... //account setup.. KeyboardInteractiveAuthenticationMethod kauth = new KeyboardInteractiveAuthenticationMethod(Defs.UserName); PasswordAuthenticationMethod pauth = new PasswordAuthenticationMethod(Defs.UserName, Defs.PassWord); kauth.AuthenticationPrompt += new EventHandler<AuthenticationPromptEventArgs>(HandleKeyEvent); //setup connection ConnectionInfo connectionInfo = new ConnectionInfo(Defs.HostName, Defs.Port, Defs.UserName, pauth, kauth); connectionInfo.Timeout = Defs.ConnectionTimeout; //pass connection data SshClient _sshClient = new SshClient(connectionInfo); //let the user know what we are doing. Log.Verbose("Attempting to connect..."); //connect to linux _sshClient.Connect(); //let the user know what we are doing. Log.Verbose("Connected, creating shell stream...", ConsoleColor.Green); //lets build out a stream that will each back what we request. var terminalMode = new Dictionary<TerminalModes, uint>(); //create shell stream ShellStream _shellStream = _sshClient.CreateShellStream("input", 255, 50, 400, 600, 4096, terminalMode); //setup for prompt var promptRegex = new Regex(Command_Prompt); //send a command _shellStream.WriteLine("ls -ltr"); //look for prompt var output = _shellStream.Expect(promptRegex); //log output Log.Verbose(output);
@gavin1970
Thank u, your code solved my problem. Not sure what caused the abort, but maybe its related to the router asking me to trust the fingerprint (in the command prompt) first time connecting.....
@abdalkhalik np, glad it helped.
i am using Renci SSH.Net to do ssh connection, most of my connections done successfully and no issue but now i have an issue connecting to server i am getting An established connection was aborted by the server
the below is the simple code i used
using (var client = new SshClient(Host, 22, Username, Password)) { client.Connect(); // the exception raise here var result = client.RunCommand(" show ver "); client.Disconnect(); } i asked the server admin for the log and he sent to me the below log result from the server :
Sep 7 17:21:21.228 [GENERAL] [ERROR] SSH_input_control[0]: key exchange failed for instance: 4568 status: -5904 Sep 7 17:21:21.228 [GENERAL] [] SSH_input_control[0]: connection id: 0 exiting... Sep 7 17:21:21.228 [GENERAL] [ERROR] SSH_cleanup[0]: SSH/SFTP: unverified session terminated
appreciate your support