How to Run Commands by Sudo and Enter Password by Ssh .Net C#

How to run commands by sudo and enter password by ssh .net c#

The most secure way to do it, as already mentioned by a comment, is to use CreateShellStream and just write the password directly to the stream after running the sudo command. The password gets sent just as if you had been using an interactive terminal. This might not be a convenient solution, though, if you don't want to be locked into using an endless stream for the rest of what you want to do. Example:

var promptRegex = new Regex(@"\][#$>]"); // regular expression for matching terminal prompt
var modes = new Dictionary<Renci.SshNet.Common.TerminalModes, uint>();
using (var stream = ssh.CreateShellStream("xterm", 255, 50, 800, 600, 1024, modes))
{
stream.Write("sudo iptables -L -n\n");
stream.Expect("password");
stream.Write("mypassword\n");
var output = stream.Expect(promptRegex);
}

The downside is that your output will include junk you don't really want: control characters, prompts, and everything else that gets sent over the stream.

If you want to avoid using a shell stream then you may be able to (depending on security settings) provide a password via stdin. THIS IS INSECURE because commands get logged in various places and you might be revealing your password to other users with root access. If you're the only user, or if you don't care that everybody else can see your password, then this might be more convenient for you.

Example:

using (var cmd = ssh.RunCommand("echo -e 'mypassword\n' | sudo -S iptables -L -n"))
{
if (cmd.ExitStatus == 0)
Console.WriteLine(cmd.Result);
else
Console.WriteLine(cmd.Error);
}

Finally, it's also possible to have a script print your password to stdin. This way your password won't get logged along with the rest of the command line; but this still isn't much more secure since anyone with root access could potentially read the script and see the password:

using (var cmd = ssh.RunCommand("~/printpasswd.sh | sudo -S iptables -L -n"))
{
if (cmd.ExitStatus == 0)
Console.WriteLine(cmd.Result);
else
Console.WriteLine(cmd.Error);
}

and inside printpasswd.sh:

#!/bin/bash
echo -e 'mypassword\n'

Providing subcommands to a command (sudo/su) executed with SSH.NET SshClient.CreateShellStream

Just write the "commands" to the StreamWriter.

writer.WriteLine("sudo su - wwabc11");
writer.WriteLine("whoami");
// etc

See also C# send Ctrl+Y over SSH.NET.


Though note that using CreateShellStream ("shell" channel) is not the correct way to automate a commands execution. You should use CreateCommand/RunCommand ("exec" channel). Though SSH.NET limited API to the "exec" channel does not support providing an input to commands executed this way. And whoami and the others are actually inputs to sudo/su command.

A solution would be to provide the commands to su on its command-line, like:

sudo su - wwabc11 -c "whoami ; cd /wwabc11/batch/bin/ ; pwd"

For an example of code that uses CreateCommand to execute a command and reads its output, see see SSH.NET real-time command output monitoring.

Linux with SSH.NET : “sorry, you must have a tty to run sudo”

Presumably my command has sudo in it?

sudo is interactive, requesting a password, and RunCommand doesn't provide anyway to send input to the command.

You need to use ShellStream instead.

var sh = client.CreateShellStream("", 0, 0, 0, 0);
sh.WriteLine("my command");
sh.WriteLine("sudo password");

SSH and sudo connection to MySQL instance from C#

I just wanted to update this thread with the solution that worked for me. I ended up using a mysql connector as suggested above.

using MySql.Data;
using MySql.Data.MySqlClient;
using System;
using System.Collections.Generic;
using System.Net.NetworkInformation;

namespace DBconnector
{
class DBConnect
{
public MySqlConnection connection;
private string server;
private string database;
private string uid;
private string password;

//Constructor
public DBConnect()
{
Initialize();
}

private void Initialize()
{
Console.WriteLine("Initializing Connection...");
server = "192.168.0.60";
database = "devDB";
uid = "user";
password = "password";
string connectionString;
connectionString = "SERVER="+server+";" + "UID="+uid+";" + "DATABASE="+database+";" + "PASSWORD="+password+";";

connection = new MySqlConnection(connectionString);
}


/* Sample select statement from a table in the DB */
public List<string> SelectFBOEntries(String statement)
{
string query = statement;
List<string> response = new List<string>();
if (this.OpenConnection())
{
MySqlCommand cmd = new MySqlCommand(query, connection);
MySqlDataReader dataReader = cmd.ExecuteReader();

//Read the data and store them in the list
while (dataReader.Read())
{
response.Add(dataReader["ID"] + "");
response.Add(dataReader["Name"] + "");
response.Add(dataReader["Age"] + "");
response.Add(dataReader["DOB"] + "");
response.Add(dataReader["ZIP"] + "");
}
dataReader.Close();
this.CloseConnection();
return response;
}
else
{
return response;
}
}

public bool CloseConnection()
{
try
{
connection.Close();
return true;
}
catch (MySqlException ex)
{
Console.WriteLine("Error Closing Connection");
return false;
}
}


Providing input/subcommands to a command (cli) executed with SSH.NET SshClient.RunCommand

AFAIK, cli is a kind of a shell/interactive program. So I assume you have tried to do something like:

client.RunCommand("cli");
client.RunCommand("some cli subcommand");

That's wrong. cli will keep waiting for subcommands and never exit, until you explicitly close it with a respective command (like exit). And after it exits, the server will try to execute the cli subcommand as a separate top-level command, failing too.


You have to feed the "cli subcommand" to the input of the cli command. But SSH.NET unfortunately does not support providing an input with the SshClient.RunCommand/SshClient.CreateCommand interface. See Allow writing to SshCommand.


There are two solutions:

  • Use the appropriate syntax of the server's shell to generate the input on the server, like:

    client.RunCommand("echo \"cli subcommand\" | cli");
  • Or use a shell session (what is otherwise a not recommended approach for automating a command execution).

    Use SshClient.CreateShellStream or SshClient.CreateShell and send the commands to its input:

    "cli\n" + "cli subcommand\n"

    For a sample code see Providing subcommands to a command (sudo/su) executed with SSH.NET SshClient.CreateShellStream or C# send Ctrl+Y over SSH.NET.



Related Topics



Leave a reply



Submit