ssh.net maintain conversation with server - ssh.net

I am looking to persist a conversation with a remote server using ssh.net
What i am doing is connecting to a host, sending a command like change directory... to some directory besides root. Store the results value off as a global.
Then i am sending another command via RunCommand() to check the current directory...
What is happening is, i am getting the root directory, not the directory i just changed to in the initial run command.
What it seems is happening is, while the connection to the server has remained open i have somehow reset the terminal session thereby losing the conversation i was having with the server.
Does anyone know how to persist a conversation with a remote server using ssh.net so i can send multiple commands and have the state persist?
E.g. command 1 = cd/somedir
command 2 = pwd and the result of command 2 to is /somedir

E.g. command 1 = cd/somedir command 2 = pwd and the result of command 2 to is /somedir
Your example seems just fine. But I think, you are expecting to change directory and run the second command in that directory.
Server connection is an ssh tunnel to the server, it doesn't start a shell. RunCommand() creates a shell and runs a command, the second RunCommand also creates a new shell and runs the command, so change directory does not persist between commands.
After establishing connection, use a ShellStream to create a shell from which you can send and receive interactive commands from.
A sample from codeplex:
string command = "your command";
using (var ssh = new SshClient(connectionInfo))
{
ssh.Connect();
string reply = String.Empty;
try
{
using (var shellStream = ssh.CreateShellStream("dumb", 0, 0, 0, 0, BUFFERSIZE))
{
// Wait for promt for 10 seconds, if time expires, exception is thrown
reply = shellStream.Expect(new Regex(#":.*>"), new TimeSpan(0, 0, 10));
shellStream.WriteLine(command);
// Wait for Read for 10 seconds, if time expires, exception is thrown
string result = shellStream.ReadLine(new TimeSpan(0, 0, 10));
}
}
catch
{
// Do something
}
}

Related

How do I send several commands to the same cmd instance in perl?

My problem is that I need to build a script that will send commands to the single win32 CMD instance.
The "system #cmd" or "`` #cmd" won't help here, since they always create a new instance.
It should look like this in pseudo code:
my $consoleWindow = CreateConsole;
my $cmdargs1 = "foo";
my $cmdargs2 = "bar";
Send($cmdargs1, $consoleWindow);
sleep(1);
Send($cmdargs2, $consoleWindow); #send to the same instance
I believe, that I would have to create new cmd window, hook to it and then send my commands to it. How can I achieve this?

how can i prevent a script from running while I'm launching the server?

I have a script that queries a third party API when the script is called from within my sinatra application, but I do not want it to run when I am launching my Thin server. Is there a way to prevent my code from running until I call it directly? for instance, can I run a check to see if my server is running from within ruby/sinatra to prevent my code from running?
# the following code is inside a class and gets initialized when my server launch script is executed
authToken = ENV['EVERNOTE_AUTH_TOKEN']
evernoteHost = "www.evernote.com"
userStoreUrl = "https://#{evernoteHost}/edam/user"
userStoreTransport = Thrift::HTTPClientTransport.new(userStoreUrl)
userStoreProtocol = Thrift::BinaryProtocol.new(userStoreTransport)
userStore = Evernote::EDAM::UserStore::UserStore::Client.new(userStoreProtocol)
# this line of code executes on server start
noteStoreUrl = userStore.getNoteStoreUrl(authToken)
It appears that ruby does a syntax check when running each file, and my API is being called against my will on the last line, i want to write an if statement that makes it un-callable unless my server is already running

Laravel SSH - create tmux session

I have the following:
\Config::set('remote.connections.runtime.host', $server->server_ip);
$commands = [
'tmux'
];
\SSH::run($commands, function($line) {
echo $line.PHP_EOL;
});
dd();
This outputs the following error:
open terminal failed: not a terminal
Is it possible to create a tmux session this way?
There's nothing you can do to make this work with Laravel SSH. However, Laravel's SSH component uses phpseclib SSH internally which is more flexible when used directly.
Now I'm assuming you're trying to create a tmux session to start some process that you want to continue running in the background after the SSH connection has ended. The good part is that since phpseclib is a dependency of Laravel SSH it's already there so there's no need to install it. I'm not very familiar with tmux and it's options, but I can offer a solution that uses screen instead:
use \phpseclib\Net\SSH2;
use \phpseclib\File\ANSI;
$ssh = new SSH2('host');
$ansi = new ANSI();
if ($ssh->login('username', 'password')) {
// The command below will start a screen
// session and automatically detach it
$ssh->write("screen -m -d -S processes top\n");
// You can include the lines below to see the
// output of the write command converted to HTML
$ansi->appendString($ssh->read());
echo $ansi->getScreen();
}
This creates a new automatically detached screen session named processes and runs the top command in it. To connect to the session you can simply run this in your console:
ssh username#host -t "screen -r processes"
This will reattach the processes session so you can see what's going on. Of course you could adapt this to use tmux if that's you're preference.

Open file as another user, using node.js

I have a node.js program running as a service on my windows PC which I use to open files. The only way I have found to make this work is to use node.js to open PSExec, as node doesn't appear to have the ability to open a program as another user (in windows).
The code below works, however it is somewhat insecure, as the username and password can be discovered by watching process monitor, or even the command line column in task manager. I don't store the password in the source by the way, just put it there to keep the example simple.
var EventLogger = require('node-windows').EventLogger;
var log = new EventLogger('File Launcher starting');
var exec = require('child_process').exec;
var userName = "mike";
var password= "mikesPassword";
var fullPath= "C:\folder\file.xls";
exec("PSExec.exe -accepteula -h -d -u "+userName+" -p "+password+" -i 1 C:\\WINDOWS\\SYSTEM32\\CMD.EXE /c start \"\" \""+fullPath+"\"",{cwd: process.cwd}, function(error, stdout, stderror) {
if(error){
log.error(stderror.replace('\n','').replace('\r',''));
}
if(stdout){
log.info(stdout.replace('\n','').replace('\r',''));
}
Is there some other way I can get node.js to launch a file as another user without exposing the username and password?
I attempted to do it using powershell, but it seems SYSTEM is not allowed to launch files as other users.

Execute multiple commands via SSH and PowerShell

I successfully managed to connect to a Cisco IE-2000-L switch via SSH. I used the Renci SSH.NET library.
Starting guide: http://vwiki.co.uk/SSH_Client_(PowerShell)
My working code is
# Load SSH library (for .NET 4.0 and PowerShell 3)
$DllPath = "D:\temp\Renci.SshNet.dll"
[void][reflection.assembly]::LoadFrom( (Resolve-Path $DllPath) )
# Connect to switch (Cisco IE2000-L) with IP, port, username, password
$SshClient = New-Object Renci.SshNet.SshClient('172.20.91.30', 22, 'admin', 'mypassword')
$SshClient.Connect()
# execute one command on Cisco switch
$SshCommand = $SshClient.RunCommand('show arp')
# show result
$SshCommand.Result
# close SSH connection
$SshCommand.Dispose()
$SshClient.Disconnect()
$SshClient.Dispose()
My problem is
The above code sends just one command. But I want to execute several commands consecutively without closing and reopening a session.
If I add a second command right after the first one
# execute one command on Cisco switch
$SshCommand = $SshClient.RunCommand('show arp')
$SshCommand = $SshClient.RunCommand('show start')
...the script hangs and never finishes. What am I doing wrong?
Minor relevant information
My main goal is to send multiple commands at once to a Cisco switch
I already tried Plink together with batch cmd input. It's not reliable enough. It works sometimes and sometimes not.
I already tried telnet scripting. Too awkward.

Resources