Pergunta

I'm using plink from c# to connect to Linux servers and run some programs. Both the c# console program and the plink.exe are on the same windows machine.

The problem is when I connect to a Linux server for the first time, plink asks me if I want to accept and store the SSH key from the Linux server. I always want to respond yes to this because all the servers are in my LAN and there is no security issue.

I'm using c# Process type, pass the correct argument to plink, redirect the output and start. Now the problem is when plink prompts, the process.StandardOutput.ReadToEnd(); hangs and I have no way of figuring out whether I'm prompted by plink to accept the key or actually logged into the Linux server.

        string output = string.Empty;
        string error = string.Empty;
        string arguments = @" -ssh -pw password root@12.12.12.12 ./Install_xxx.bin";

        using (Process process = new Process())
        {
            ProcessStartInfo psi = new ProcessStartInfo();
            psi.FileName = "plink";
            psi.Arguments = arguments;
            psi.ErrorDialog = false;
            psi.UseShellExecute = false;
            psi.RedirectStandardError = true;
            psi.RedirectStandardInput = true;
            psi.RedirectStandardOutput = true;
            psi.CreateNoWindow = true;

            process.StartInfo = psi;
            process.Start();

            output = process.StandardOutput.ReadToEnd();
            error = process.StandardError.ReadToEnd();
        }

Thanks

Foi útil?

Solução

Your Deadlock problem is explained in the Process docu. When the process waits for input it cannot close stdin so it will block. StandardOutput will not be closed because the process is still waiting for your input from stdin: Deadlock. You can either use the asynchronous apis to read line by line or you use for the other stream another thread.

Outras dicas

Instead of using an external executable to make your SSH connection, why not use a SSH library and do it (more reliably) through code?

sharpSsh (most recent version here) is a C# port of Jsch, a BSD-licensed Java library. I've used it in my C# projects very successfully; you'll be able to programmatically handle all aspects of the SSH connection, including the key negotiation.

In order to seamlessly connect to a remote server via PLINK, the first time and on subsequent times, you have to manually coordinate your SSH keys. That is, use PUTTYGEN to create your .ppk private key file that PLINK will use, and store the corresponding public key in the ~/.ssh/authorized_keys file on the server beforehand.

You also need to coordinate the sshd's host keys, so use PUTTYGEN to generate a set of private key files ssh_host_rsa_key and ssh_host_dsa_key under /etc/ssh (look at the existing files to figure out which key formats to export to), and then run ssh-keygen -y -f /etc/ssh/ssh_host_rsa_key > /etc/ssh/ssh_host_rsa_key.pub to create the corresponding public key files (do the same to create the ssh_host_dsa_key.pub file).

If you have more than one server you want to PLINK to, and don't mind using the same key to connect to all of them (this will depend on your local IT security policy), then just copy the same key files onto each server.

THEN, on your Windows machine that you're using PLINK, manually connect to any server using PUTTY or PLINK, and interactively accept the host key. Once you do that, PUTTY/PLINK stores that key in the Windows registry, under HKCU\Software\SimonTatham\PuTTY\SshHostKeys. You'll notice a entry like rsa2@22:host, where host is your server's host name.

Now, for the crux of the procedure, you need to copy the REG_SZ hex value 0x23,... into your C# app, where you'll have to manually use the Microsoft.Win32.RegistryKey classes to write this value for all other servers using the same rsa2@22:host naming scheme before you shell out to PLINK (whether you consider this registry value to be security-sensitve is up to you, so protect it somehow in your C# app if you have to).

Like others have mentioned, you may want to consider using an SSH library to get more programmatic feedback on your connection process, but to use PLINK, this is what you need to do.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top