在后台

时间:2015-10-16 22:26:58

标签: c# ssh public-key ssh-tunnel

尝试在127.0.0.1:9999上打开SSH隧道时,我遇到了C#问题。

这是我的Program.cs

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Begin");

        PlinkTest plink = new PlinkTest();

        String feedback = plink.CreateTunnel("1.2.3.4", "user", "user");

        Console.WriteLine("THING:" + feedback);

        Console.Read();
    }
}

这是我的计划,PlinkTest.cs

class PlinkTest
{
    String PATH_TO_PLINK = @"C:\plink\plink.exe";
    public PlinkTest()
    {
    }

    public string RequestInfo(string remoteHost, string userName, string password, string[] lstCommands)
    {
        m_szFeedback = "Feedback from: " + remoteHost + "\r\n";

       //  ProcessStartInfo psi = new ProcessStartInfo("echo y | C:\\plink\\plink.exe")
        ProcessStartInfo psi = new ProcessStartInfo("C:\\plink\\plink.exe")
        {
            Arguments = String.Format("-ssh -N -D 9999 user@1.2.3.4 -pw user -v"),
            RedirectStandardError = true,
            RedirectStandardOutput = true,
            RedirectStandardInput = true,
            UseShellExecute = false,
            CreateNoWindow = true
        };

        Process p = Process.Start(psi);

        m_objLock = new Object();
        m_blnDoRead = true;

        AsyncReadFeedback(p.StandardOutput); // start the async read of stdout
        AsyncReadFeedback(p.StandardError); // start the async read of stderr

        StreamWriter strw = p.StandardInput;

        foreach (string cmd in lstCommands)
        {
            strw.WriteLine(cmd); // send commands 
        }
        strw.WriteLine("exit"); // send exit command at the end

        p.WaitForExit(); // block thread until remote operations are done
        return m_szFeedback;
    }


    public string CreateTunnel(string remoteHost, string userName, string password)
    {
        m_szFeedback = "Feedback from: " + remoteHost + "\r\n";

        //  ProcessStartInfo psi = new ProcessStartInfo("echo y | C:\\plink\\plink.exe")
        ProcessStartInfo psi = new ProcessStartInfo(PATH_TO_PLINK)
        {
            Arguments = String.Format("-ssh -N -D 9999 user@1.2.3.4 -pw user -v"),
            RedirectStandardError = true,
            RedirectStandardOutput = true,
            RedirectStandardInput = true,
            UseShellExecute = false,
            CreateNoWindow = true
        };

        Process p = Process.Start(psi);

        m_objLock = new Object();
        m_blnDoRead = true;

        AsyncReadFeedback(p.StandardOutput); // start the async read of stdout
        AsyncReadFeedback(p.StandardError); // start the async read of stderr

        StreamWriter strw = p.StandardInput;


        // SLEEP HERE 10 SEC

        strw.WriteLine("exit"); // send exit command at the end

        p.WaitForExit(); // block thread until remote operations are done
        return m_szFeedback;
    }


    private String m_szFeedback; // hold feedback data
    private Object m_objLock; // lock object
    private Boolean m_blnDoRead; // boolean value keeping up the read (may be used to interrupt the reading process)

    public void AsyncReadFeedback(StreamReader strr)
    {
        Thread trdr = new Thread(new ParameterizedThreadStart(__ctReadFeedback));
        trdr.Start(strr);
    }
    private void __ctReadFeedback(Object objStreamReader)
    {
        StreamReader strr = (StreamReader)objStreamReader;
        string line;
        while (!strr.EndOfStream && m_blnDoRead)
        {
            line = strr.ReadLine();
            // lock the feedback buffer (since we don't want some messy stdout/err mix string in the end)
            lock (m_objLock) { m_szFeedback += line + "\r\n"; }
        }
    }
}

第一个问题

我面临的第一个问题是自动接受RSA密钥,我可以运行

echo y |plink.exe -ssh -N -D 9999 user@1.2.3.4 -pw user -v

但事实证明,当我在echo y |行使用Process p = Process.Start(psi); psi变量正常时,我收到错误。我知道如何在Arguments = String.Format("-ssh -N -D 9999 user@1.2.3.4 -pw user -v"),之后提出论据,但我不知道如何将它们放在命令面前。

第二个问题

第二个问题是我不想等待内容,因为当我创建隧道时,它什么也没说,只是在等待。我只想在127.0.0.1:9999的后台打开一个SSH隧道,这就是全部。

我需要改变什么?

感谢。

3 个答案:

答案 0 :(得分:1)

  1. 要验证SSH主机密钥,请使用-hostkey switch。不要试图跳过主机密钥验证。它是为了保护您免受man-in-the-middle attacks

    Arguments = String.Format("-ssh -N -D 9999 user@1.2.3.4 -pw user -v -hostkey aa:bb:cc:dd:..."),
    

    无论如何,你的管道语法本身不起作用,因为cmd.exe只能理解它,所以你必须像以下那样运行它:

    ProcessStartInfo psi = new ProcessStartInfo("cmd.exe")
    {
        Arguments = String.Format("/C echo y | C:\\plink\\plink.exe -ssh -N -D 9999 user@1.2.3.4 -pw user -v"),
    }
    

    但是,不要这样做!

  2.   

    我不想等待内容

  3. 所以,不要等。

    我们不知道,您的申请目的是什么。

    如果只是打开隧道,然后让它等待(按键?)无限期,以保持隧道畅通。

    如果应用程序要使用隧道,那么只需继续执行其他任务,而无需关闭SSH会话。

    您应该更好地为隧道使用本机.NET SSH库,然后使用外部应用程序。

    例如SSH.NET。见.NET SSH Port Forwarding

答案 1 :(得分:-1)

显然,在您的方案中无法使用echo进行io重定向。

尝试使用您已有的ystrw.WriteLine(...);发送到plink,或者创建一个yes.txt文件,在其中放置一个y并进行plink读取其内容为plink < yes.txt

plinks manual page的快速扫描显示没有参数可以指定&#34;全是模式&#34;。

答案 2 :(得分:-1)

只需执行此代码....它将占用缓存密钥...  string sPlinkPath = @“”“C:\ Program Files(x86)\ PuTTY \ plink.exe”“”;

        string sCommandToStoreKeyInCach = "echo y |"+ sPlinkPath + clsGlobalVariables.sIpAdd + " -pw XXXX exit";

        Process GetCpuInfo = new Process();

        // Redirect the output stream of the child process.
        GetCpuInfo.StartInfo.UseShellExecute = false;
        GetCpuInfo.StartInfo.RedirectStandardInput = true;
        GetCpuInfo.StartInfo.RedirectStandardOutput = true;
        GetCpuInfo.StartInfo.RedirectStandardError = true;

        GetCpuInfo.StartInfo.FileName = @"C:\Windows\System32\cmd.exe";
        GetCpuInfo.StartInfo.Arguments = "/c " + sCommandToStoreKeyInCach;

        GetCpuInfo.StartInfo.CreateNoWindow = true;
        GetCpuInfo.Start();

        GetCpuInfo.WaitForExit();

告诉我这是不是......工作......