I'm using SSH.NET in order to get some informations of an external tape drive. Connecting and executing some basic commands works perfectly fine for me:
ConnectionInfo connNfo = new ConnectionInfo("10.12.2.97", 22, "loginuser",
new AuthenticationMethod[]
{
// Password based Authentication
new PasswordAuthenticationMethod("loginuser","password")
}
);
using (var client = new SshClient(connNfo))
{
client.Connect();
//This command works fine
using (var cmd = client.CreateCommand("ls"))
{
string result = cmd.Execute();
}
}
But now i have to switch to root user in order to execute extended commands i need. Initially logging in with root user is not possible because of security restrictions. Referring to this post How to run commands by sudo and enter password by ssh .net c# i tried this code block:
using (var cmd = ssh.RunCommand("echo 'rootpassword' | sudo -u root -S fsstate"))
{
if (cmd.ExitStatus == 0)
Console.WriteLine(cmd.Result);
else
Console.WriteLine(cmd.Error);
}
But then i always receive this error message:
sudo: unknown user: root
sudo: unable to initialize policy plugin
Update 1:
Working PuTTY commands
What i'm doing wrong here?
Related
I need to execute this command on our remote Skype server:
SEFAUtil.exe /server:lyncserver.domain1.co.uk sip:MySelf#domain.com /addteammember:sip:OtherUser#domain.com /delayringteam:10
which adds a colleague to my team call group.
I am able to run the command on the server itself, and the code below works when sending other commands to that server:
var processToRun = new[] { process };
var connection = new ConnectionOptions();
var wmiScope = new ManagementScope(String.Format("\\\\{0}\\root\\cimv2", LyncServer), connection);
var wmiProcess = new ManagementClass(wmiScope, new ManagementPath("Win32_Process"), new ObjectGetOptions());
var reason = wmiProcess.InvokeMethod("Create", processToRun);
However, when process is the string:
"cmd /c cd /d C:\\Program Files\\Microsoft Lync Server 2013\\ResKit && SEFAUtil.exe /server:lyncserver.domain1.co.uk sip:MySelf#domain.com /addteammember:sip:OtherUser#domain.com /delayringteam:10"
Then the user is not added to the team call group.
I can see that reason contains the uint 0, which usually indicates success - but the actual command is clearly failing.
I also tried adding > C:\users\user.name\desktop\output.txt and 2> C:\users\user.name\desktop\output.txt to the end of the command, but they just created empty text files, so not very useful!
Update
I tried changing the command to the following:
const string LyncServer = "server.domain1.co.uk";
const string ResKitPath = #"C:\Program Files\Microsoft Lync Server 2013\ResKit";
var command = "SEFAUtil.exe /server:{LyncServer} sip:MySelf#domain.com /addteammember:sip:OtherUser#domain.com /delayringteam:10";
var process = $"cmd /c cd /d \"{ResKitPath}\" && {command}";
So that the path containing spaces is double-quoted and the slashes are not being escaped, but with the same results.
Does anyone know of another way of debugging this or retrieving the output for the newly created process?
I've had a similar issue, mine was that the command shell needed to run elevated. SEFA is a bit naff at giving good error messages, and fails silently.
I am using C# with SSH.NET.
I want to issue a PWD command but could not find any documentation or help. I do not know how to use 'SshClient' class.
Update:
I also tried experimenting with SshClient class using the below code but it does nothing, neither any error nor any exception.
ConnectionInfo ConnNfo = new ConnectionInfo("FTPHost", 22, "FTPUser",
new AuthenticationMethod[]{
// Pasword based Authentication
new PasswordAuthenticationMethod("FTPUser","FTPPass")
}
);
using (var ssh = new SshClient(ConnNfo))
{
ssh.Connect();
if (ssh.IsConnected)
{
string comm = "pwd";
using (var cmd = ssh.CreateCommand(comm))
{
var returned = cmd.Execute();
var output = cmd.Result;
var err = cmd.Error;
var stat = cmd.ExitStatus;
}
}
ssh.Disconnect();
}
Nothing happens. Neither an error nor an exception. On Visual Studio console, i get the below output.
*SshNet.Logging Verbose: 1 : SendMessage to server 'ChannelRequestMessage': 'SSH_MSG_CHANNEL_REQUEST : #152199'.
SshNet.Logging Verbose: 1 : ReceiveMessage from server:
'ChannelFailureMessage': 'SSH_MSG_CHANNEL_FAILURE : #0'.*
At ssh.RunCommand method call the program goes in some sleep state (or waits for around 1 minute). sshCommand.Result and sshCommand.Error variables are empty.
Here's a quick example - one way to do it.
string host = "myhost";
string user = "root";
string pwd = "#secret#!"; // Don't use hardcoded plain-text passwords if possible - for demonstration only.
using (PasswordAuthenticationMethod auth = new PasswordAuthenticationMethod(user, pwd))
{
ConnectionInfo connection = new ConnectionInfo(host, user, auth);
using (var ssh = new SshClient(connection))
{
ssh.Connect();
SshCommand sshCommand = ssh.RunCommand("pwd");
Console.WriteLine("Command execution result: {0}", sshCommand.Result);
}
}
Note that if you specify an invalid command (e.g. "pwdxxxx"), you won't get an exception, but an error that will be stored in the SshCommand.Error string.
Note also that this uses SSH PasswordAuthentication, which may not be enabled in your SSH config.
Try looking into the documentation of SSH.NET:
SSH.NET at CodePlex
Code sample for executing a command (recommended)
Help file.CHM
I am attempting to initialize and push an initial commit to GitLab repository using LibGit2Sharp.
if (!Directory.Exists("D:\\GitRepos\\" + repositoryName))
{
Directory.CreateDirectory("D:\\GitRepos\\" + repositoryName);
File.Create("D:\\GitRepos\\" + repositoryName + "\\README.md").Close();
}
Repository.Init("D:\\GitRepos\\" + repositoryName);
using (var repo = new Repository("D:\\GitRepos\\" + repositoryName))
{
repo.Index.Add("README.md");
Signature author = new Signature("user", "user#user.com", DateTime.Now);
Signature committer = author;
repo.Commit("Initial Commit", author, committer);
repo.Network.Remotes.Add("origin", validRepoHttpsUrl);
Remote remote = repo.Network.Remotes["origin"];
var options = new PushOptions
{
CredentialsProvider = (_url, _user, _cred) =>
new UsernamePasswordCredentials {Username = "validuser", Password = "validpassword"}
};
string pushRefSpec = #"refs/heads/master";
repo.Network.Push(remote, pushRefSpec, options);
}
}
The repository is created and initialized locally without issue. The README file is created and added to the repo index and commit succeeds. When I try to push the commit to the remote endpoint I receive an error stating :
"Request failed with status code: 411"
If I put a breakpoint right before the push and set the http.postBuffer for the repo with the following command:
git config http.postBuffer 524288000
I receive a new error when the push executes:
Failed to write chunk footer: The connection with the server was terminated abnormally
I was able to quickly stand up a bitbucket git repo and push to it without any issues, seems that this may be a problem with gitlab.
It looks like this is a known issue for libgit2sharp based on RobertN's comment. https://github.com/libgit2/libgit2sharp/issues/905
I was able to work around this temporarily by handling the push with a git CLI call.
Process p = new Process();
// Redirect the output stream of the child process.
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.WorkingDirectory = "D:\\GitRepos\\" + repositoryName;
p.StartInfo.FileName = "git.exe";
p.StartInfo.Arguments = "push -u origin master";
p.Start();
string output = p.StandardOutput.ReadToEnd();
p.WaitForExit();
Something to note is that when this is being run as a windows service as local system the call takes 2-3 minutes for a small commit to push. When i switched the service to run as a domain user it is immediate. Also, this only works because I have ssh and proper keys setup on my host, otherwise git would prompt for a username and password. I had to use the SSH URL instead of HTTP as stated in the original question.
I am trying to create a SSH client using C#. I am using the Tamir.SharpSsh library. I am having issues sending the command and getting an appropriate response from the server.
The way I have been testing it is by sending over the ls command, followed by cd.. command, followed by ls command again -- to see whether or not the cd.. command is being executed properly. However, there is no difference between the first ls command and the second ls command. I am not entirely sure what I am doing wrong. Perhaps I am using the wrong Ssh type. I have provided the code and the output I am getting. I have also added the output that I expect.
using Tamir.SharpSsh;
namespace SSHNetExample
{
class Program
{
static void Main(string[] args)
{
SshExec ssh = null;
try
{
Console.Write("-Connecting...");
ssh = new SshExec(host, username, password);
ssh.Connect();
Console.WriteLine("OK ({0}/{1})", ssh.Cipher, ssh.Mac);
Console.WriteLine("Server version={0}, Client version={1}", ssh.ServerVersion, ssh.ClientVersion);
Console.WriteLine("-Use the 'exit' command to disconnect.");
Console.WriteLine();
while(true)
{
string command = Console.ReadLine();
if(command == "exit")
break;
string data = ssh.RunCommand(command);
Console.WriteLine(data);
}
}
catch(Exception e)
{
Console.WriteLine(e.Message);
}
if(ssh != null)
{
Console.WriteLine("Disconnecting...");
ssh.Close();
Console.WriteLine("OK");
}
}
}
}
Output:
Expected Output:
The SshExec class is for executing a single command. It logs into the server for each command, and executes the command you asked it to. It's similar (but not the same) as you logging in, typing cd .., logging out again, logging in again and typing ls - when you logged in the second time you were redirected to the home directory.
If you want to continue to use the SshExec, you should combine your commands so you can just execute a single command. In this instance, for example, you would execute ls ...
If you want to be able to issue multiple commands like an interactive session, look at the SshShell class instead of SshExec.
I am trying to figure out if the Active Directory Domain Services are installed a windows server.
I know they show up in the Server Manager, but can I programmatically get if the role is installed on a server using C# code
If you know the name of the server you want to test and can run the program with domain admin privileges remotely, you can use WMI:
internal static bool IsDomainController(string ServerName)
{
StringBuilder Results = new StringBuilder();
try
{
ManagementObjectSearcher searcher =
new ManagementObjectSearcher("\\\\" + ServerName + "\\root\\CIMV2",
"SELECT * FROM Win32_ServerFeature WHERE ID = 10");
foreach (ManagementObject queryObj in searcher.Get())
{
Results.AppendLine(queryObj.GetPropertyValue("ID").ToString());
}
}
catch (ManagementException)
{
//handle exception
}
if (Results.Length > 0)
return true;
else
return false;
}
If you're running that locally on the server, the WMI path changes to:
ManagementObjectSearcher searcher =
new ManagementObjectSearcher("root\\CIMV2",
"SELECT * FROM Win32_ServerFeature WHERE ID = 10");
See the MSDN reference on Win32_ServerFeature for a full list of roles and their ID numbers.
If your question is to see if a server is a domain controller, you can enumerate the domain controllers in the domain and check the hostname of the server you are sitting on to see if it matches any of them. To get the list of domain controllers:
var domainControllers = new List<string>();
var domain = Domain.GetCurrentDomain();
foreach (var dc in domain.DomainControllers)
{
domainControllers.Add(dc.Name);
}
string whoami = Dns.GetHostname();
Make sure to add requisite error handling (like if you run this on a workgroup computer, it will die).
EDIT:
Alternate ways of detecting DCPROMO (because it's possible to install Domain Services without DCPROMO, and that is a bad thing):
1) Parse out (and check for the existence of) the debug log that is created when DCPROMO does its thing. Should be located at c:\windows\debug\dcpromo.log
2) This DSQUERY command is FAST and will give you all the servers where DCPROMO was ran:
dsquery * "cn=Sites,cn=Configuration,dc=MyDomain,dc=com" -Filter "(cn=NTDS Settings)" -attr distinguishedName whenCreated
Problem is getting that from command line output if you started it using Process. Working on a way to do this and will update once I have it tested, as I haven't done AD filtering in a query for a while.