Stilts.js Unable to connect to websocket server with secure true - javascript

I am having issues with subscribing to my websocket server when I turn the secure option to true. I ran an SSL validator to make sure it was set up properly and everything passed. Also to be safe, I also checked with my hosting provider so I dont believe that is the issue. And also, everything does work when secure is set to false.
The WSS is running on port 8676, and I did make sure that port is open.
I am using the Stomp Javascript library. I downloaded the latest version from their github master branch (https://github.com/projectodd/stilts/blob/master/stomp-client-js/src/main/javascript/stomp.js).
I keep getting this error inside the _transmit() function: can't call transmit on undefined
It seems to not be setting the _transport property inside of _buildConnector() function. I added some console.logs and it always goes to the else statement in this function.
Any ideas on a fix? Or am I just missing something?
This is how I am initializing my connection:
client = new Stomp.Client('my.ip.address', 8676, true);
Here is where I am logging some of the functions:
Stomp.Client = function(host, port, secure) {
console.log('host param: ' + host);
console.log('port param: ' + port);
console.log('secure param: ' + secure);
this._host = host || Stomp.DEFAULT_HOST;
this._port = port || Stomp.DEFAULT_PORT || 8675;
this._secure = secure || Stomp.DEFAULT_SECURE_FLAG || false;
console.log('this._host: ' + this._host);
console.log('this._port: ' + this._port);
console.log('this._secure: ' + this._secure);
}
Output:
host param: my.ip.address
port param: 8676
secure param: true
this._host: my.ip.address
this._port: 8676
this._secure: true
_buildConnector: function(transports, i) {
console.log('INSIDE _buildConnector()');
var callback = this._connectCallback;
var client = this;
if ( i < transports.length ) {
console.log('IF!!!');
return function() {
var fallback = client._buildConnector( transports, i+1, callback );
try {
console.log('_buildConnector::IF::TRY');
transports[i].connect( function() {
client._transport = transports[i];
callback();
}, fallback );
} catch (err) {
console.log('_buildConnector::IF::CATCH');
fallback();
}
};
} else {
console.log('_buildConnector::ELSE');
return client.connectionFailed.bind(this);
}
}
Output:
INSIDE _buildConnector()
IF!!!
INSIDE _buildConnector()
IF!!!
_buildConnector::IF::TRY
INSIDE _buildConnector()
_buildConnector::ELSE
_buildConnector::IF::TRY
connectionFailed: function() {
console.log('INSIDE connectionFailed()');
if (this._errorCallback)
{
console.log('connectionFailed::IF');
console.log('this._errorCallback');
console.log(this._errorCallback);
console.log('arguments');
console.log(arguments);
this._errorCallback.apply(this._errorCallback, arguments);
}
else
{
console.log('connectionFailed::ELSE');
console.log('unable to connect :(');
Stomp.logger.log( "unable to connect" );
}
}
Output:
No output..

I discovered this node.js tool called wscat which can be used to send messages to a websocket server (http://einaros.github.io/ws/).
When entering the command using the external address:
wscat -c wss://my.ip.address:8676
I kept getting the following error: error: Error: Hostname/IP doesn't match certificate's altnames
But when I changed it to my domain name:
wscat -c wss://mydomain.com:8676
I was given this message: connected (press CTRL+C to quit)
Which led me to:
I am setting the host value in Javascript as the external ip address of the server where STOMP lives. But the SSL cert is configured for a domain name. This led me to think that I should use mydomain.com instead of my.ip.address for the host parameter in new Stomp.Client. But this is resulting in the following error in the Torquebox log file:
NoSuchHostException: No such host: mydomain.com
So then in the torquebox.yml file the host property needed to be configured to mydomain.com as well.
So the conclusion is: You need to use the domain name that was registered to the SSL cert when trying to connect to your websocket server, not the external ip address. huzzah!
Credit to: #bobmcwhirter who helped lead me to this solution here: https://github.com/projectodd/stilts/issues/20

Related

Javascript Websocket fails to receive TCP data

I'm trying to receive json data from an ESP32 via TCP to a website hosted thru WAMP (localhost -> ESP32 IP address on local network is 10.11.125:23). Below is my javascript function. My browser (Firefox Developer) generates a "SecurityError: The operation is insecure" when executing the line var connection = new webSocket('ws://10.11.13.125:23'). What am I missing??
function openWebsocket() {
console.log("open Websocket.....");
var connection = new WebSocket('ws://10.11.13.125:23');
connection.onerror = function(error) {
$("#Connection").html("Connection Error");
console.log("Websocket Error: " + error);
}
connection.onopen = function(evt) {
$("#Connection").html("Connected");
}
connection.binaryType = 'arraybuffer';
connection.onmessage = function(evt) {
console.log("Server: " + evt.data.byteLength);
}
console.log("ReadyState: "+connection.readyState);
}
I found the problem. The Chromium browser yields a more descriptive error message. Port 23 is not available. Switched over to
var connection = new WebSocket('ws://10.11.13.125:80');
and voila, everything works as expected.
Sorry for posting about an issue that in the end I found the solution for myself.

Paho MQTT host invalid argument when using an IP address as hostname?

REVISION: Please note I am now using IP address 10.0.0.15, my device publishing to the MQTT broker is 10.0.0.122. This is still all working through terminal.
I think I am getting somewhere with an MQTT connector. I have moved forward after having issues as describe in the post below
Can't connect to localhost Mosquitto Broker with Javascript?
I am now seeing the following error.
mqttws31.js:1585 Uncaught Error: AMQJS0013E Invalid argument
169.254.118.199 for host.
at new M (mqttws31.js:1585)
at startConnect (n.js:29)
at HTMLInputElement.onclick ((index):107)
which according to the js file indicates a match error. I have tried prefixing the ip address to be wss://169.254.118.199 but this doesn't resolve the issue. Do you know what could be causing this?
I have tried the following
wss://169.254.118.199
ws://169.254.118.199
wss://localhost
tcp://169.254.118.199
tcp://localhost
They all produce the same error
This is the bit of code in mqttws31.js that the error points to.
if (arguments.length == 2) {
// host: must be full ws:// uri
// port: clientId
clientId = port;
uri = host;
var match = uri.match(/^(wss?):\/\/((\[(.+)\])|([^\/]+?))(:(\d+))?
(\/.*)$/);
if (match) {
host = match[4]||match[2];
port = parseInt(match[7]);
path = match[8];
} else {
--> this is where error is pointing throw new Error(format(ERROR.INVALID_ARGUMENT,[host,"host"]));
}
} else {
if (arguments.length == 3) {
clientId = path;
path = "/mqtt";
}
if (typeof port !== "number" || port < 0)
throw new Error(format(ERROR.INVALID_TYPE, [typeof port, "port"]));
if (typeof path !== "string")
throw new Error(format(ERROR.INVALID_TYPE, [typeof path, "path"]));
var ipv6AddSBracket = (host.indexOf(":") != -1 && host.slice(0,1) != "[" &&
host.slice(-1) != "]");
uri = "ws://"+(ipv6AddSBracket?"["+host+"]":host)+":"+port+path;
}
EDIT: in the print out I am seeing the following being sent to the Paho client on my webpage:
Connecting to: 10.0.0.122 on port: 8083
Using the following client value: clientID-64
I am hoping to sucessfully connect with the IP address and get the MQTT payload
To get the error you are seeing, you can not be using the code you have posted in the other questions:
clientID = "clientID-" + parseInt(Math.random() * 100);
// Fetch the hostname/IP address and port number from the form
host = document.getElementById("host").value;
port = document.getElementById("port").value;
// Print output for the user in the messages div
// Initialize new Paho client connection
client = new Paho.MQTT.Client(host, Number(port), clientID);
That error can only happen if you only pass 2 arguments to the Paho.MQTT.Client() constructor not 3. In which case the first argument is interpreted as a full URI (e.g. ws://10.0.0.122:8083/mqtt), the second as the ClientID.

Angular 2: window.crypto.subtle.importKey works in 'localhost' but not on 'ip'

I am a rookie in Angular 2. I am trying to implement a login form that sends the emailid and password after certain encryption steps to the server.
I have implemented AES-ECB by using AES-CTR from,
https://github.com/diafygi/webcrypto-examples
I have used the 'importKey' and 'encrypt' method as follows,
public deriveAKey(input, encryptKey, cryptoIV) {
var ref: TopDivComponent = this;
console.log('Testing before importKey...');
window.crypto.subtle.importKey(
"raw",
ref.stringToArrayBuffer(encryptKey),
{
name: "AES-CTR",
},
true,
["encrypt"]
).then(function (key) {
console.log('Inside then...');
var newvar = ref.stringToArrayBuffer(cryptoIV);
var encrypt = window.crypto.subtle.encrypt(
{
name: "AES-CTR",
counter: newvar,
length: 128,
},
key,
ref.stringToArrayBuffer(input)
).then(function (encrypted) {
var temp = ref.arrayBufferToString(encrypted);
console.log('Encrypted First: ' + encrypted);
console.log('Temp: ' + temp);
console.log('Key: ' + key);
let fin_encrypted = btoa(temp);
// console.log('Encrypted Snc/d: ' + fin_encrypted);
ref.response(fin_encrypted);
// console.log('From deriveKey: ' + fin_encrypted);
});
});
}
I use a local server to obtain the response. Everything works fine when using localhost. The Request and Response are properly sent and obtained from the server. But, when connected over IP, it shows an error “NotSupportedError: Only secure origins are allowed”.
When I used Chrome canary, it said that importKey method is not recognized. So when I 'console'ed it with Chrome, the control did not go beyond the importKey method. What could possibly be the problem?
Chrome restricts the usage of WebCryptographyApi to secure origins. It means 'https'. localhost is a special address enabled for development. Therefore, to use WebCrypto in a real environment you need to setup a SSL/TLS server

registration using sip.js and websockets in Node (wss or ws)

I'm trying to register SIP agents using sip.js and Node to start load testing to my Kamailio
Node version v0.10.32
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0"
global.WebSocket = require('ws')
// SipJS Initialization
var SIP = require('./sip-0.6.0.js');
var Uaconfig = {
traceSip: true,
register: true,
userAgentString: 'sipJS Test tool',
uri: 'ramenlabs.io',
wsServers: ['wss://ramenlabs.io:5063'],
authorizationUser: 'gogasca',
password: '********'
//hackIpInContact: true
};
var userAgent = new SIP.UA(Uaconfig);
When I run I get an error:
Thu Oct 16 2014 03:40:53 GMT+0000 (UTC) | sip.transport | WebSocket connection error: Error: unexpected server response (400)
Because initial Websocket from Sip.js lacks Sec-WebSocket-Protocol: sip to indicate SIP Protocol.
If i use sample web page it works perfectly with same parameters, but not from my node command line.
How to force this?
In API js I do see the 'sip' extra header but contains the window.Websocket
try {
this.ws = new window.WebSocket(this.server.ws_uri, 'sip');
}
catch(e) {
this.logger.log('Error connecting to WebSocket ' + this.server.ws_uri + ': ' + e);
//return false;
}
You can set debug=3 in kamailio.cfg, restart and try again. Then look in syslog file (/var/log/syslog or /var/log/messages) for debug messages from Kamailio to see if you get a hint on why the connection is not accepted.

Websockets in Firefox not working with several HTTPS pages

I have a websocket client-server application. Here's client's simplified code:
const HOST = "wss://localhost:8000";
const SUB_PROTOCOL= "sub-protocol";
var websocket = new WebSocket(HOST, SUB_PROTOCOL);
websocket.onopen = function(evt) { ... };
websocket.onclose = function(evt) { ... };
websocket.onerror = function(evt) { ... };
websocket.onmessage = function(evt) { ... };
And here's server:
const PORT = 8000;
const SUBPROTOCOL = 'sub-protocol';
var WebSocketServer = require('websocket').server;
var https = require('https');
var fs = require('fs');
// Private key and certification (self-signed for now)
var options = {
key: fs.readFileSync('cert/server.key'),
cert: fs.readFileSync('cert/server.crt')
};
var server = https.createServer(options, function(request, response) {
console.log((new Date()) + ' Received HTTP(S) request for ' + request.url);
response.writeHead(404);
response.end();
});
// bind server object to listen to PORT number
server.listen(PORT, function() {
console.log((new Date()) + ' Server is listening on port ' + PORT);
});
wsServer = new WebSocketServer({
httpServer: server,
// You should not use autoAcceptConnections for production
// applications, as it defeats all standard cross-origin protection
// facilities built into the protocol and the browser. You should
// *always* verify the connection's origin and decide whether or not
// to accept it.
autoAcceptConnections: false
});
function originIsAllowed(origin) {
// put logic here to detect whether the specified origin is allowed.
return true;
}
// If autoAcceptConnections is set to false, a request event will be emitted
// by the server whenever a new WebSocket request is made
wsServer.on('request', function(request) {
if (!originIsAllowed(request.origin)) {
// Make sure we only accept requests from an allowed origin
request.reject();
console.log((new Date()) + ' Connection from origin ' + request.origin + ' rejected.');
return;
}
// accepts connection and return socket for this connection
var connection = request.accept(SUB_PROTOCOL, request.origin);
console.log((new Date()) + ' Connection accepted.');
// when message is received
connection.on('message', function(message) {
// echo
connection.send(connection, message.utf8Data);
});
connection.on('close', function(reasonCode, description) {
console.log((new Date()) + ' Peer ' + connection.remoteAddress + ' disconnected.');
});
});
Both client and server works as expected even with some HTTPS pages (tested on Twitter, mail.ru,). But for some reason doesn't for example with Facebook or GitHub.
In JavaScript console I get this:
Exception { message: "", result: 2153644038, name: "", filename: "", lineNumber: 0, columnNumber: 0, inner: null, data: null }
Then huge stack trace follows: pasted it here
and at the end:
Content Security Policy: The page's settings blocked the loading of a resource at wss://localhost:8000/ ("connect-src https://github.com:443 https://ghconduit.com:25035 https://live.github.com:443 https://uploads.github.com:443 https://s3.amazonaws.com:443").
I don't see how does these page differ from pages, which works. I'd also like to point out, that these pages works in Chrome.
(tested in Firefox 31)
The pages where the WebSocket connection fails have a Content-Security-Policy header with the connect-src directive set to only allow connections to a set of whitelisted domains. This means that all connections from that page to any non-whitelisted domain will fail.
Its not clear how you're running this code. It seems possible that Chrome allows extensions to bypass that header restriction while Firefox does not, or something to that effect.

Categories

Resources