Hello I creating a webapp that has a working SSH terminal similar to Putty. I'm using SSH Library as a means of handling the ssh stream. However there is a problem. I can log into a Cisco 2950 and type in commands but it comes out jumbled and in one line.
Also when I try "conf t" it gets into the configuration terminal but then you can't do anything and this pops up "Line has invalid autocommand "?".
Here is the code I have so far:
This is the SSH.cs that interacts with the library.
public class SSH
{
public string cmdInput { get; set; }
public string SSHConnect()
{
var PasswordConnection = new PasswordAuthenticationMethod("username", "password");
var KeyboardInteractive = new KeyboardInteractiveAuthenticationMethod("username");
// jmccarthy is the username
var connectionInfo = new ConnectionInfo("10.56.1.2", 22, "username", PasswordConnection, KeyboardInteractive);
var ssh = new SshClient(connectionInfo);
ssh.Connect();
var cmd = ssh.CreateCommand(cmdInput);
var asynch = cmd.BeginExecute(delegate(IAsyncResult ar)
{
//Console.WriteLine("Finished.");
}, null);
var reader = new StreamReader(cmd.OutputStream);
var myData = "";
while (!asynch.IsCompleted)
{
var result = reader.ReadToEnd();
if (string.IsNullOrEmpty(result))
continue;
myData = result;
}
cmd.EndExecute(asynch);
return myData;
}
}
This the code in the .aspx.cs that displays the code on the web page.
protected void CMD(object sender, EventArgs e)
{
SSH s = new SSH();
s.cmdInput = input.Text;
output.Text = s.SSHConnect();
}
Any help would be appreciated.
From looking through the test cases in the code for the SSH.NET library, you can use the RunCommand method instead of CreateCommand, which will synchronously process the command. I also added a using block for the SshClient ssh object since it implements iDisposable. Remember to call Disconnect as well so you don't get stuck with open connections.
Also the SshCommand.Result property (used in the command.Result call below), encapsulates the logic to pull the results from the OutputSteam, and uses this._session.ConnectionInfo.Encoding to read the OutputStream using the proper encoding. This should help with the jumbled lines you were receiving.
Here is an example:
public string SSHConnect() {
var PasswordConnection = new PasswordAuthenticationMethod("username", "password");
var KeyboardInteractive = new KeyboardInteractiveAuthenticationMethod("username");
string myData = null;
var connectionInfo = new ConnectionInfo("10.56.1.2", 22, "username", PasswordConnection, KeyboardInteractive);
using (SshClient ssh = new SshClient(connectionInfo)){
ssh.Connect();
var command = ssh.RunCommand(cmdInput);
myData = command.Result;
ssh.Disconnect();
}
return myData;
}
Related
ModbusFactory modbus = new ModbusFactory();
TcpClient tcpClient = new TcpClient("127.0.0.1", 5000);
var master = modbus.CreateMaster(tcpClient);
var data = master.ReadHoldingRegisters(0, 0, 2);
This is my NModbus code. In this case, I expect to get the result data of only response ReadHoldingRegisters(). However, I want to get not only response data but also the request byte array.
The above picture is the ModbusSlave program's communication log. That shows RX/TX with a timestamp. How can I get like this RX/TX log in my C# NModbus code?
There are no available logging methods in a document of NModbus GitHub.
public class GetLogMessage : ModbusLogger
{
public List<string> _message { get; set; } = new List<string>();
public GetLogMessage(LoggingLevel minimumLoggingLevel) : base(minimumLoggingLevel)
{
}
protected override void LogCore(LoggingLevel level, string message)
{
_message.Add(message);
if (level == LoggingLevel.Trace) _message.Add(message);
Trace.WriteLine($"[{level}]".PadRight(4) + message);
}
}
I found how can get a trace log.
First, we create a new class that inherits ModbusLogger. Then create LogCore and Constructure.
Now we can get RX/TX data in _message.
GetLogMessage logger = new GetLogMessage(LoggingLevel.Trace);
ModbusFactory modbus = new ModbusFactory(null,true, logger);
TcpClient client = new TcpClient("127.0.0.1", 5000);
IModbusMaster master = modbus.CreateMaster(client);
ushort[] res = master.ReadHoldingRegisters(0,0,2);
var getlog = logger._message;
Console.WriteLine(getlog[0]);
Console.WriteLine(getlog[5]);
Results
I wanted to write a Program that reads an online Calendar, compares it with Names in a Database and uses this Data in some way. But if I use the WebClient, it reads the Source Code of the Website, not the Content. This is my Code:
using System;
using System.Diagnostics;
using System.Net;
using MySql.Data.MySqlClient;
namespace CalendarCrawler
{
class Program
{
static void KillTask(string Task)
{
Process[] Process = new Process[] { };
Process = Process.GetProcessesByName(Task);
foreach (Process Instance in Process)
{
Instance.Kill();
}
}
static String ReadContent(String Website)
{
WebClient web = new WebClient();
System.IO.Stream stream = web.OpenRead(Website);
using (System.IO.StreamReader reader = new System.IO.StreamReader(stream))
{
String text = reader.ReadToEnd();
return text;
}
}
static void Main(string[] args)
{
Console.WriteLine("Getting Connection ...");
var datasource = "localhost";//your server
var database = "database"; //your database name
var username = "username"; //username of server to connect
var password = "password"; //password
//your connection string
string connStr = $"Server={datasource};Database={database};Uid={username};Pwd={password}";
//create instanace of database connection
using (var conn = new MySqlConnection(connStr))
{
try
{
Console.WriteLine("Openning Connection ...");
//open connection
conn.Open();
Console.WriteLine("Connection successful!");
}
catch (Exception e)
{
Console.WriteLine("Error: " + e.Message);
}
String Websitetext = ReadContent("http://www.esel.at/termine");
var stm = $"INSERT INTO content(Content) VALUES (#1);";
var cmd = new MySqlCommand(stm, conn);
cmd.Parameters.AddWithValue("#1", Websitetext);
cmd.ExecuteNonQuery();
Console.WriteLine(Websitetext);
KillTask("CalendarCrawler");
}
}
}
}
The Killtask Method is only to Clear it from the Background Processes, so there are no Problems with building a new Version.
I hope someone can help me.
There are effectively 2 different users of the web. People and computers. People like shiney things like buttons and tables (UI), computers prefer things like XML or JSON (API).
Your calendar web site has a UI, this is what you are currently seeing (both in a browser and when you 'download the code'). It probably has an API too and that is what you should be using in your program.
I've just had a quick look at esel.at and it doesn't appear to have a (public) API (but maybe that is because Google can't translate the page properly).
I am using Renci.SshNet in c# on framework 3.5 and running a command on unix box like below.
string host = "localhost";
string user = "user";
string pass = "1234";
SshClient ssh = new SshClient(host, user, pass);
using (var client = new SshClient(host, user, pass))
{
client.Connect();
var terminal = client.RunCommand("/bin/run.sh");
var output = terminal.Result;
txtResult.Text = output;
client.Disconnect();
}
every thing works well, my question here is that "Is there a way that it should not wait for client.RunCommand to be finish" My prog doesn't need a output from unix and hence I don't want to wait for the RunCommand to finish. This command took 2 hours to execute so wanted to avoid that wait time on my application.
As i assume SSH.NET doesn't expose a true asynchronous api, you can queue RunCommand on the threadpool:
public void ExecuteCommandOnThreadPool()
{
string host = "localhost";
string user = "user";
string pass = "1234";
Action runCommand = () =>
{
SshClient client = new SshClient(host, user, pass);
try
{
client.Connect();
var terminal = client.RunCommand("/bin/run.sh");
txtResult.Text = terminal.Result;
}
finally
{
client.Disconnect();
client.Dispose();
}
};
ThreadPool.QueueUserWorkItem(x => runCommand());
}
}
Note if you use this inside WPF or WinForms then you will need to txtResult.Text = terminal.Result with Dispatcher.Invoke or Control.Invoke, respectively.
What about
public static string Command(string command)
{
var cmd = CurrentTunnel.CreateCommand(command); // very long list
var asynch = cmd.BeginExecute(
//delegate { if (Core.IsDeveloper) Console.WriteLine("Command executed: {0}", command); }, null
);
cmd.EndExecute(asynch);
if (cmd.Error.HasValue())
{
switch (cmd.Error) {
//case "warning: screen width 0 suboptimal.\n" => add "export COLUMNS=300;" to command
default: MessageBox.Show(cmd.Error); break;
}
}
return cmd.Result;
}
I'm trying to run a command on a remote server via SSH.
I need the output of the command that is run to be saved in a file on that remote server.
I've been attempting to this the following way
// ssh is the SshClient which is already set up
ssh.Connect();
ssh.RunCommand("echo 1 > C:\test.csv"); //Doesn't create a file
ssh.Disconnect();
Why doesn't this work with SSH.NET? If I run this via putty using the same credentials it works perfectly fine.
EDIT (Working Code):
I did some more playing around and have found the following to work:
// ssh is the SshClient which is already set up
ssh.Connect();
var shell = ssh.CreateShellStream("cmd.exe", 80, 24, 800, 600, 1024);
var reader = new StreamReader(shell);
var writer = new StreamWriter(shell);
writer.AutoFlush = true;
while (!shell.DataAvailable)
System.Threading.Thread.Sleep(1000); //This wait period seems required
writer.WriteLine("echo 1 > C:\test.csv");
while (!shell.DataAvailable)
System.Threading.Thread.Sleep(1000); //This wait period seems required
ssh.Disconnect();
While that works I still don't understand what's really happening here. Could someone explain?
Try this function:
Just save the result to a variable or write the result using StreamWriter
private void writeMe()
{
using (StreamWriter sw = new StreamWriter(filename)
{
string result = eSshCom(command);
sw.WriteLine(result);
}
}
private string eSshCom(string getCommand)
{
this.res = "";
var connectionInfo = new KeyboardInteractiveConnectionInfo(ipaddress, 22, username);
connectionInfo.AuthenticationPrompt += delegate(object asender, AuthenticationPromptEventArgs xe)
{
foreach (var prompt in xe.Prompts)
{
if (prompt.Request.Equals("Password: ", StringComparison.InvariantCultureIgnoreCase))
{
prompt.Response = password;
}
}
};
using (var ssh = new SshClient(connectionInfo))
{
ssh.Connect();
var cmd = ssh.RunCommand(getCommand);
this.res = cmd.Result;
ssh.Disconnect();
}
return this.res;
}
I'm current looking at Thrift to use as a RPC framework for our apps (mostly written in C# and Silverlight). I've come as far as implementing a service and consuming it from a C# console app (using a socket as transport).
For the C# server side code my code looked like: (basically copying the tutorials included with the source code)
MyServiceHandler handler = new MyServiceHandler();
MyService.Processor processor = new MyService.Processor(handler);
TServerTransport serverTransport = new TServerSocket(9090);
TServer server = new TSimpleServer(processor, serverTransport);
server.Serve();
For the client side code it looked like:
TTransport transport = new TSocket("localhost", 9090);
TProtocol protocol = new TBinaryProtocol(transport);
MyService.Client client = new MyService.Client(protocol);
transport.Open();
client.SomeServiceCall();
However, we will be consuming the service from a Silverlight client, and unfortunately there is no support for sockets in Silverlight for Thrift. I assume I'm forced to use HTTP communication between the client and service, using Thrift's C# THttpClient and THttpHandler classes? I could not find any examples of how to do this out there, can anyone point me in the right direction? Some example server and client side code would be appreciated.
It seems that this issue was already addressed by this guy. According to this JIRA, the fix is available in Thrift 0.9. You can either try this snapshot (note that, as it's not a final release, it might not be stable) or you can apply this patch to the 0.8 release.
I believe by now you would have understood, there is no direct way of communicating from Silverlight to the Cassandra database either using Thrift or any other clients.
I have one simple option related to this. Write a Silverlight enabled web service and consume it from the client.
For example, on the server side you can have a web service which does insert/update/read etc., like this. I just managed to pull out some code which we use for our project. Hope this helps.
using Apache.Cassandra;
using Thrift.Protocol;
using Thrift.Transport;
namespace CassandraWebLibrary
{
public class MyDb
{
String _host;
int _port;
String _keyspace;
bool _isConnected;
TTransport _transport = null;
Apache.Cassandra.Cassandra.Client _client = null;
String columnFamily = "ColumnFamilyName";
public VazhikaattiDB(String host, int port, String keyspace)
{
_host = host;
_port = port;
_keyspace = keyspace;
_isConnected = false;
}
public bool Connect()
{
try
{
_transport = new TFramedTransport(new TSocket(_host, _port));
TProtocol protocol = new TBinaryProtocol(_transport);
_client = new Apache.Cassandra.Cassandra.Client(protocol);
_transport.Open();
_client.set_keyspace(_keyspace);
_isConnected = true;
}
catch (Exception ex)
{
log.Error(ex.ToString());
}
return _isConnected;
}
public bool Close()
{
if (_transport.IsOpen)
_transport.Close();
_isConnected = false;
return true;
}
public bool InsertData(Send your data as parameters here)
{
try
{
List<Column> list = new List<Column>();
string strKey = keyvalue;
#region Inserting into Coulmn family
List<Byte> valbytes = new List<byte>(BitConverter.GetBytes(value)); //You might have to pad this with more bytes to make it length of 8 bytes
Column doublecolumn1 = new Column()
{
Name = Encoding.UTF8.GetBytes("column1"),
Timestamp = timestampvalue,
Value = valbytes.ToArray()
};
list.Add(doublecolumn1);
Column stringcolumn2 = new Column()
{
Name = Encoding.UTF8.GetBytes("column2"),
Timestamp = timestampvalue,
Value = Encoding.UTF8.GetBytes("StringValue")
};
list.Add(stringcolumn2);
Column timecolumn3 = new Column()
{
Name = Encoding.UTF8.GetBytes("column3"),
Timestamp = timestampvalue,
Value = BitConverter.GetBytes(DateTime.Now.Ticks)
};
list.Add(timecolumn3);
#endregion
ColumnParent columnParent = new ColumnParent();
columnParent.Column_family = columnFamily;
Byte[] key = Encoding.UTF8.GetBytes(strKey);
foreach (Column column in list)
{
try
{
_client.insert(key, columnParent, column, ConsistencyLevel.QUORUM);
}
catch (Exception e)
{
log.Error(e.ToString());
}
}
return true;
}
catch (Exception ex)
{
log.Error(ex.ToString());
return false;
}
}
public List<YourReturnObject> GetData(parameters)
{
try
{
ColumnParent columnParent = new ColumnParent();
columnParent.Column_family = columnFamily;
DateTime curdate = startdate;
IndexExpression indExprsecondkey = new IndexExpression();
indExprsecondkey.Column_name = Encoding.UTF8.GetBytes("column");
indExprsecondkey.Op = IndexOperator.EQ;
List<Byte> valbytes = PadLeftBytes((int)yourid, 8);
indExprsecondkey.Value = valbytes.ToArray();
indExprList.Add(indExprsecondkey);
IndexClause indClause = new IndexClause()
{
Expressions = indExprList,
Count = 1000,
Start_key = Encoding.UTF8.GetBytes("")
};
SlicePredicate slice = new SlicePredicate()
{
Slice_range = new SliceRange()
{
//Start and Finish cannot be null
Start = new byte[0],
Finish = new byte[0],
Count = 1000,
Reversed = false
}
};
List<KeySlice> keyslices = _client.get_indexed_slices(columnParent, indClause, slice, ConsistencyLevel.ONE);
foreach (KeySlice ks in keyslices)
{
String stringcolumnvalue = Encoding.UTF8.GetString(cl.Column.Value);
double doublevalue= (Double)BitConverter.ToDouble(cl.Column.Value);
long timeticks = BitConverter.ToInt64(cl.Column.Value, 0);
DateTime dtcolumntime = new DateTime(timeticks);
}
}
catch (Exception ex)
{
log.Error(ex.ToString());
}
return yourdatalist;
}
}
}
Now the above class can be used by your webservice, which in turn will be used by Silverlight. Btw, you'll have to take care of other silverlight issues like size of data to be downloaded from server/webservice etc.,
FYI, our client service of Cassandra runs on port 9160..