Using npm package ssh2 within an Angular2 application running under electron - node.js

I want to create an Angular2 service which uses the npm package ssh2 - https://www.npmjs.com/package/ssh2.
I have installed and configured it as I would expect - the code for my service can be seen below (this code is based on the first example shown on the ssh2 npm site and github repo(the only change being I am using a password rather than a key for authentication)):
const Client = require('ssh2').Client;
const fs = require('fs');
import { NextObserver } from 'rxjs/Observer';
import { Observable } from 'rxjs/Rx';
export class SSHClient {
username: string;
password: string;
host: string;
port: number;
ssh: any;
constructor() {
}
init(username, password, host, port) {
console.log("initiating SSH connection to:" + host + "on port:" + port);
this.username = username;
this.password = password;
this.host = host;
this.port = port;
console.log("Connecting now...");
var conn = new Client();
conn.on('ready', function() {
console.log('Client :: ready');
conn.exec('uptime', function(err, stream) {
if (err) throw err;
stream.on('close', function(code, signal) {
console.log('Stream :: close :: code: ' + code + ', signal: ' + signal);
conn.end();
}).on('data', function(data) {
console.log('STDOUT: ' + data);
}).stderr.on('data', function(data) {
console.log('STDERR: ' + data);
});
});
}).connect({
host: this.host,
port: this.port,
username: this.username,
password: this.password
});
console.log("SSH Client created and demo has run");
}
}
I make my call to the service as per this from within my component:
this.ssh.init("username","password","my.little.host",22);
And I expect to get back the output of the uptime command having executed over SSH on my server - via the console. However instead of that - I get this:
EXCEPTION: Uncaught (in promise): Error: Error in ./ServerBrowserComponent class ServerBrowserComponent_Host - inline template:0:0 caused by: Cannot read property 'connect' of undefined
TypeError: Cannot read property 'connect' of undefined
at SSHClient.init (file:///Users/myapp/build/app.js:40259:12)
at new ServerBrowserComponent (file:///Users/myapp/build/app.js:34158:19)
at new Wrapper_ServerBrowserComponent (/AppModule/ServerBrowserComponent/wrapper.ngfactory.js:7:18)
at DebugAppView._View_ServerBrowserComponent_Host0.createInternal (/AppModule/ServerBrowserComponent/host.ngfactory.js:16:38)
at DebugAppView.AppView.create (file:///Users/myapp/build/app.js:27754:26)
at DebugAppView.create (file:///Users/myapp/build/app.js:27954:49)
at ComponentFactory.create (file:///Users/myapp/build/app.js:24393:41)
at ViewContainerRef_.createComponent (file:///Users/myapp/build/app.js:23441:50)
at RouterOutlet.activate (file:///Users/myapp/build/app.js:72709:45)
at ActivateRoutes.placeComponentIntoOutlet (file:///Users/myapp/build/app.js:72207:21)
ORIGINAL STACKTRACE:
Error: Uncaught (in promise): Error: Error in ./ServerBrowserComponent class ServerBrowserComponent_Host - inline template:0:0 caused by: Cannot read property 'connect' of undefined
TypeError: Cannot read property 'connect' of undefined
at SSHClient.init (ssh.service.ts:49)
at new ServerBrowserComponent (server.browser.component.ts:31)
at new Wrapper_ServerBrowserComponent (wrapper.ngfactory.js:7)
at DebugAppView._View_ServerBrowserComponent_Host0.createInternal (host.ngfactory.js:16)
at DebugAppView.AppView.create (core.umd.js:9170)
at DebugAppView.create (core.umd.js:9370)
at ComponentFactory.create (core.umd.js:5809)
at ViewContainerRef_.createComponent (core.umd.js:4857)
at RouterOutlet.activate (router.umd.js:3457)
at ActivateRoutes.placeComponentIntoOutlet (router.umd.js:2955)
at resolvePromise (zone-node.js:468)
at zone-node.js:445
at ZoneDelegate.invoke (zone-node.js:232)
at Object.onInvoke (core.umd.js:6206)
at ZoneDelegate.invoke (zone-node.js:231)
at Zone.run (zone-node.js:114)
at zone-node.js:502
at ZoneDelegate.invokeTask (zone-node.js:265)
at Object.onInvokeTask (core.umd.js:6197)
at ZoneDelegate.invokeTask (zone-node.js:264)
Unhandled Promise rejection: Error in ./ServerBrowserComponent class ServerBrowserComponent_Host - inline template:0:0 caused by: Cannot read property 'connect' of undefined ; Zone: angular ; Task: Promise.then ; Value: ViewWrappedError TypeError: Cannot read property 'connect' of undefined
at SSHClient.init (file:///Users/myapp/build/app.js:40259:12)
at new ServerBrowserComponent (file:///Users/myapp/build/app.js:34158:19)
at new Wrapper_ServerBrowserComponent (/AppModule/ServerBrowserComponent/wrapper.ngfactory.js:7:18)
at DebugAppView._View_ServerBrowserComponent_Host0.createInternal (/AppModule/ServerBrowserComponent/host.ngfactory.js:16:38)
at DebugAppView.AppView.create (file:///Users/myapp/build/app.js:27754:26)
at DebugAppView.create (file:///Users/myapp/build/app.js:27954:49)
at ComponentFactory.create (file:///Users/myapp/build/app.js:24393:41)
at ViewContainerRef_.createComponent (file:///Users/myapp/build/app.js:23441:50)
at RouterOutlet.activate (file:///Users/myapp/build/app.js:72709:45)
at ActivateRoutes.placeComponentIntoOutlet (file:///Users/myapp/build/app.js:72207:21)
Error: Uncaught (in promise): Error: Error in ./ServerBrowserComponent class ServerBrowserComponent_Host - inline template:0:0 caused by: Cannot read property 'connect' of undefined(…)
The bulk of that seems to be struggling because : Cannot read property 'connect' of undefined -- yet I am following the example documentation. Can somebody please help my understand why this is not working - and how I can fix it?
I tried to pull the code out of my project and into its own file which looks like:
const Client = require('ssh2').Client;
console.log("Connecting now...");
var conn = new Client();
conn.on('ready', function() {
console.log('Client :: ready');
conn.exec('uptime', function(err, stream) {
if (err) throw err;
stream.on('close', function(code, signal) {
console.log('Stream :: close :: code: ' + code + ', signal: ' + signal);
conn.end();
}).on('data', function(data) {
console.log('STDOUT: ' + data);
}).stderr.on('data', function(data) {
console.log('STDERR: ' + data);
});
});
}).connect({
host: 'my.little.host',
port: 22,
username: 'uname',
password: 'pwd'
});
console.log("SSH Client created and demo has run");
But I get the same error:
var conn = new Client();
^
ReferenceError: Client is not defined
at Object.<anonymous> (/Users/myapp/attempt.js:2:21)
at Module._compile (module.js:541:32)
at Object.Module._extensions..js (module.js:550:10)
at Module.load (module.js:458:32)
at tryModuleLoad (module.js:417:12)
at Function.Module._load (module.js:409:3)
at Module.runMain (module.js:575:10)
at run (node.js:348:7)
at startup (node.js:140:9)
at node.js:463:3
So something simple is going wrong here, what could it be!?

the ssh2-package is for node.js, not frontend/web.
The browser can't use network like that (electron uses two processes, the browser/renderer -process does not have access to the network features you need)
does your electron app have a main.js file?
that's where you need to implement the ssh functionality.
i.e. in the main-process, not in the renderer-process.
http://electron.atom.io/docs/tutorial/quick-start/#main-process

In my wrapper of ssh2 (ssh2shell) I have this.connection = new require('ssh2')(); within the constructor of the class or it could be put in the init function. Creating it within the instance might help.
"use strict";
class SSHClient {
constructor() {}
init(username, password, host, port) {
console.log("initiating SSH connection to:" + host + "on port:" + port);
var ssh = require('ssh2').Client
this._conn = new ssh();
console.log("Connecting");
console.log('Client :: ready');
var self = this
this._conn.on('ready', function() {
self._conn.exec('uptime', function(err, stream) {
if (err) throw err;
stream.on('data', function(data) {
console.log('STDOUT: ' + data);
}).stderr.on('data', function(data) {
console.log('STDERR: ' + data);
}).on('close', function(code, signal) {
console.log('Stream :: close :: code: ' + code + ', signal: ' + signal);
self._conn.end();
});
});
}).connect({
host: host,
port: port,
username: username,
password: password
});
console.log("SSH Client created and demo has run");
}
}
module.exports = SSHClient
Or using my package ssh2shell the ssh connection instance is within the sope of ssh2shell instance so you don't have to worry about it.
"use strict";
class SSHClient {
constructor() {}
init(username, password, host, port) {
console.log("initiating SSH connection to:" + host + "on port:" + port);
var host = {
server: {
host: host,
port: port,
userName: username,
password: password
},
commands: [ "uptime" ]
}
var SSH2Shell = require ('ssh2shell'),
//Use a callback function to handle the response text
callback = function(sessionText){
console.log("SSH Client created and demo has run");
console.log("Response:\n" + sessionText)
}
//Create a new instance passing in the host object
this._conn = new SSH2Shell(host)
//Start the process
this._conn.connect(callback);
}
}
module.exports = SSHClient

Related

How do I get around Internal Server Error when testing Azure Function

Does this Nodejs code look right? Is there anything missing?
const mysql = require('mysql');
const fs = require('fs');
var config =
{
host: 'mydemoserver.mysql.database.azure.com',
user: 'myadmin#mydemoserver',
password: 'your_password',
database: 'quickstartdb',
port: 3306,
ssl: {ca: fs.readFileSync("your_path_to_ca_cert_file_BaltimoreCyberTrustRoot.crt.pem")}
};
const conn = new mysql.createConnection(config);
conn.connect(
function (err) {
if (err) {
console.log("!!! Cannot connect !!! Error:");
throw err;
}
else {
console.log("Connection established.");
readData();
}
});
function readData(){
conn.query('SELECT * FROM inventory',
function (err, results, fields) {
if (err) throw err;
else console.log('Selected ' + results.length + ' row(s).');
for (i = 0; i < results.length; i++) {
console.log('Row: ' + JSON.stringify(results[i]));
}
console.log('Done.');
})
conn.end(
function (err) {
if (err) throw err;
else console.log('Closing connection.')
});
};
This is to go inside an Azure Function that reads data from a Azure for MySQL database.
When I run it inside the Kudu window by just typing node index.js it works
When I try and test it on there Azure Function Test Page it throws a Internal Server Error 500 with the following error message
Unable to determine function entry point. If multiple functions are exported, you must indicate the entry point, either by naming it 'run' or 'index', or by naming it explicitly via the 'entryPoint' metadata property.' Stack: Error: Worker was unable to load function ListBrands: 'Unable to determine function entry point. If multiple functions are exported, you must indicate the entry point, either by naming it 'run' or 'index', or by naming it explicitly via the 'entryPoint' metadata property.' at C:\Program Files (x86)\SiteExtensions\Functions\4.14.0\workers\node\dist\src\worker-bundle.js:2:13853 at t.LegacyFunctionLoader. (C:\Program Files (x86)\SiteExtensions\Functions\4.14.0\workers\node\dist\src\worker-bundle.js:2:14092) at Generator.next () at o (C:\Program Files (x86)\SiteExtensions\Functions\4.14.0\workers\node\dist\src\worker-bundle.js:2:12538) at processTicksAndRejections (node:internal/process/task_queues:96:5)
Thanks in advance
Todd

Can I connect to ssh2 without the privateKey?

I can connect to ssh2 without the privateKey
I am trying to enter a server with SFTP but when I get the following error ...
Timed out while waiting for handshake
I'm looking for an example and almost everyone uses the privateKey, is it mandatory? and how is one generated?
My code is the following ...
var Client = require ('ssh2'). Client;
var conn = new Client ();
conn.on ('error', function (err) {
console.log ('SSH - Connection Error:' + err);
});
conn.on ('end', function () {
console.log ('SSH - Connection Closed');
});
conn.on ('ready', function () {
console.log ("------ enter ------");
// code to work with SSH
});
conn.connect ({
host: 'host',
username: 'user',
port: 22
password: 'password',
});

How to make a SSH to postgres server with help of ssh2 library and query using pg libary?

I am trying to make a connection to Postgres remote host using the SSH tunnel from node application(library:ssh2) and query the data(lib:pg).
Before I used mysql2(node library) make a tunnel using ssh2(node library) and connected to Mysql remote host as well as able to query the data. But I want to do the same in Postgres remote host I am not able to connect to it.
pg Client obj config does not support the stream from ssh2 forwardOut..!
Or, Is there any library available to make this happen instead of that ssh2, pg
PS: In mysql2 when I try to make a connection with a mysql config with stream: stream key value.
var Clientssh = require('ssh2').Client;
var conn = new Clientssh();
conn.on('ready', function() {
console.log('Client :: ready');
conn.forwardOut(
'127.0.0.1',
5434,
'localhost',
5432,
function(err, stream) {
if (err) throw err;
let conf = {
host: 'localhost',
port: 5434,
user: 'test',
database: 'test',
password: 'test'
}
let remoteConnection = new Client(conf);
remoteConnection.connect(function(err) {
if (err) {
console.log(err);
console.log("Unable to connect to postgre");
res.send(err);
} else {
remoteConnection.query('SELECT * FROM test', function(err, testResult) {
remoteConnection.end();
if (err) {
console.log("Unable to fetch data");
res.send(err);
} else {
console.log("Succcess");
res.send(testResult);
}
});
}
});
});
}).connect({
host: 'hostaddress',
port: 'hostport',
username: 'hostusername',
privateKey: require('fs').readFileSync('path/for/key')
});
It shows the Connection terminated unexpectedly from this line
Client :: ready
Error: Connection terminated unexpectedly
at Connection.con.once (/node-postgres/node_modules/pg/lib/client.js:235:9)
at Object.onceWrapper (events.js:286:20)
at Connection.emit (events.js:198:13)
at Channel.<anonymous> (/node-postgres/node_modules/pg/lib/connection.js:131:10)
at Channel.emit (events.js:203:15)
at endReadableNT (_stream_readable.js:1129:12)
at process._tickCallback (internal/process/next_tick.js:63:19)
Unable to connect to postgre

Error: All configured authentication methods failed levels: 'client-authentication'

I am using node.js ssh2 module.I have installed ssh2 module by executing the command 'npm install ssh2'.However, when I use ssh2 to connect to a remote server, it always output the error:
[Error: All configured authentication methods failed] levels: 'client-authentication'
This is my code
var Client = require('ssh2').Client
var conn = new Client();
var option = {
host: '10.171.65.154',
port: 22,
username: 'root',
password: '123456'
};
conn.on('ready', function(){
console.log('Client :: ready');
conn.sftp(function(err, sftp){
if(err) throw err;
sftp.readdir('home', function(err, list){
if(err) throw err;
console.dir(list);
conn.end();
});
});
}).on('error', function(err){
console.log(err);
}).connect(option);
However, I can not connect successfully.I am sure the username and password are correct and I can connect successfully by SecureCRT.
it always output the error:
[Error: All configured authentication methods failed] levels: 'client-authentication'
Probably, you have to handle keyboard-interactive authentication (which is not the same as password). Try something like this:
connection.on('ready', function(){
console.log("Connected!");
}).on('error', function(err){
console.error(err);
}).on('keyboard-interactive', function (name, descr, lang, prompts, finish) {
// For illustration purposes only! It's not safe to do this!
// You can read it from process.stdin or whatever else...
var password = "your_password_here";
return finish([password]);
// And remember, server may trigger this event multiple times
// and for different purposes (not only auth)
}).connect({
host: "your.host.or.ip",
port: 22,
username: "your_login",
tryKeyboard: true
});

Host-based ssh authentication using nodejs

I have installed the ssh2 package for node but can not get the host based authentication working.
var Connection = require('./node_modules/bis-package/node_modules/ssh2');
var conn = new Connection();
conn.on('ready', function() {
conn.exec('cmviewcl -v -f line', function(err, stream) {
if (err) throw err;
stream.on('exit', function(code, signal) {
console.log('Stream :: exit :: code: ' + code + ', signal: ' + signal);
}).on('close', function() {
console.log('Stream :: close');
conn.end();
}).on('data', function(data) {
console.log('STDOUT: ' + data);
}).stderr.on('data', function(data) {
console.log('STDERR: ' + data);
});
});
}).connect({
host: 'server',
port: 22,
username: 'root'
});
I get the following error
Error: Authentication failure. Available authentication methods: publickey,gssapi-with-mic,password,hostbased
at Connection._tryNextAuth (/opt/bis/node/node_modules/bis-package/node_modules/ssh2/lib/Connection.js:1010:13)
at onUSERAUTH_FAILURE (/opt/bis/node/node_modules/bis-package/node_modules/ssh2/lib/Connection.js:2449:8)
at Parser.<anonymous> (/opt/bis/node/node_modules/bis-package/node_modules/ssh2/lib/Connection.js:141:5)
at Parser.emit (events.js:98:17)
at Parser.parsePacket (/opt/bis/node/node_modules/bis-package/node_modules/ssh2/lib/Parser.js:488:12)
at Parser.execute (/opt/bis/node/node_modules/bis-package/node_modules/ssh2/lib/Parser.js:249:14)
at Socket.<anonymous> (/opt/bis/node/node_modules/bis-package/node_modules/ssh2/lib/Connection.js:536:18)
at Socket.emit (events.js:95:17)
at Socket.<anonymous> (_stream_readable.js:748:14)
at Socket.emit (events.js:92:17)
We use host based authentication which allows us password free logins. In Perl I use the following:
my( $SSH ) = "/usr/bin/ssh -t -o PreferredAuthentications=hostbased 2>/dev/null";
$run->run( map { qq{$SSH $_ "$CMD"} } #hosts );
I am not sure how I could do that with the nodejs ssh2 package.
Any idea how I could do that?
There is no support for hostbased authentication yet. I plan to add support for it in the upcoming next major release. The relevant issue is here.

Resources