无法使用SSH连接到AIX(Unix)机器.. NET库-错误:值不能为空

本文关键字:错误 NET 不能 机器 SSH 连接 Unix AIX | 更新日期: 2023-09-27 18:06:14

我正在尝试连接到AIX盒子并使用 SSH.NET 库执行一些命令。下面是代码片段

KeyboardInteractiveAuthenticationMethod kauth = new KeyboardInteractiveAuthenticationMethod(username);
PasswordAuthenticationMethod pauth = new PasswordAuthenticationMethod(username, password);
ConnectionInfo connectionInfo = new(ConnectionInfo(servername, 22, username, pauth,kauth);
SshClient sshClient = new SshClient(connectionInfo);
sshClient.Connect();
SshCommand sshCommand = sshClient.RunCommand("mpstat");
Console.WriteLine(sshCommand.Result);
Console.ReadKey();

当我尝试连接sshClient.Connect()

行时,我得到以下异常消息

{"值不能为空。'r'nParameter name: data"}

栈跟踪是
   at Renci.SshNet.KeyboardInteractiveAuthenticationMethod.Authenticate(Session session)
   at Renci.SshNet.ConnectionInfo.Authenticate(Session session)
   at Renci.SshNet.Session.Connect()
   at Renci.SshNet.BaseClient.Connect()

我确信我通过的凭证是有效的,因为我能够使用具有相同凭证的 PuTTY 客户端登录。什么好主意吗?

无法使用SSH连接到AIX(Unix)机器.. NET库-错误:值不能为空

经过一番研究,我找到了解决方案。希望它能帮助到别人。

应使用键盘交互认证,并使用以下函数覆盖 AuthenticationPrompt 事件

void HandleKeyEvent(Object sender, AuthenticationPromptEventArgs e)
{
    foreach (AuthenticationPrompt prompt in e.Prompts)
    {
        if (prompt.Request.IndexOf("Password:", StringComparison.InvariantCultureIgnoreCase) != -1)
        {
            prompt.Response = password;
        }
    }
}

函数调用代码:

KeyboardInteractiveAuthenticationMethod kauth = new KeyboardInteractiveAuthenticationMethod(username);
PasswordAuthenticationMethod pauth = new PasswordAuthenticationMethod(username, password);
kauth.AuthenticationPrompt += new EventHandler<AuthenticationPromptEventArgs>(HandleKeyEvent);
ConnectionInfo connectionInfo = new ConnectionInfo(serverName, port, username, pauth, kauth);
sshClient = new SshClient(connectionInfo);
sshClient.Connect();

我已经封装了整个东西,以便更容易使用。警告:尚未执行try/catch !DLL可在这里获得:https://sshnet.codeplex.com/releases/view/120504SLES (11.1 64), Debian (6), AIX (5.3, 6.1, 7)

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Renci.SshNet;
using Renci.SshNet.Common;
namespace SSH2
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            SSH client = new SSH("servername", "username", "password");
            MessageBox.Show(client.command("ls -la /"));
        }
    }
    public class SSH
    {
        string servername;
        int port;
        string username;
        string password;
        SshClient Server = null;

        public SSH(string servername, int port, string username, string password)
        {
            this.servername = servername;
            this.port = port;
            this.username = username;
            this.password = password;
            this.init();
        }
        public SSH(string servername, string username, string password)
        {
            this.servername = servername;
            this.port = 22;
            this.username = username;
            this.password = password;
            this.init();
        }

        private void init()
        {
            KeyboardInteractiveAuthenticationMethod kauth = new KeyboardInteractiveAuthenticationMethod(this.username);
            PasswordAuthenticationMethod pauth = new PasswordAuthenticationMethod(this.username, this.password);
            kauth.AuthenticationPrompt += new EventHandler<AuthenticationPromptEventArgs>(HandleKeyEvent);
            this.Server = new SshClient(new ConnectionInfo(this.servername, this.port, this.username, pauth, kauth));
        }

        void HandleKeyEvent(Object sender, AuthenticationPromptEventArgs e)
        {
            foreach (AuthenticationPrompt prompt in e.Prompts)
            {
                if (prompt.Request.IndexOf("Password:", StringComparison.InvariantCultureIgnoreCase) != -1)
                {
                    prompt.Response = this.password;
                }
            }
        }
        public string command(string cmd)
        {
            this.Server.Connect();
            var output = this.Server.RunCommand(cmd);
            this.Server.Disconnect();
            return output.Result;
        }
    }
}