Community discussions

MikroTik App
 
si458
Frequent Visitor
Frequent Visitor
Topic Author
Posts: 65
Joined: Fri Jun 22, 2012 7:51 pm
Contact:

api javascript help

Tue Mar 22, 2016 4:25 am

Hi All,

im hoping someone can help me or even point me in the correct direction

im trying to create an front end in javascript and using chrome.sockets.tcp https://developer.chrome.com/apps/sockets_tcp

ive got the browser to connect to the api port correctly and check its alive but i cant even do the a basic thing like login!

http://pastebin.com/vXMKfhTN - here is my simple code i have made up

the /login command is made into an ArrayBuffer, then passed to the tcp and fired to the port,

but whats weird is i dont get an reply from the api ?

have i missed something in the firing to the api?

i have read on the API page http://wiki.mikrotik.com/wiki/Manual:API#Protocol about encoding my command?

i am completely lost as to what it means!

i tried to decipher the php and nodejs api's that have been made, but no luck :(

any help wouldnt go a miss!

Regards

Simon
 
User avatar
boen_robot
Forum Guru
Forum Guru
Posts: 2400
Joined: Thu Aug 31, 2006 4:43 pm
Location: europe://Bulgaria/Plovdiv

Re: api javascript help

Tue Mar 22, 2016 4:12 pm

You need to send both the length and the actual string which is that many bytes long.

From your example, it seems you're sending just the length byte, but never the actual message. You don't get any reply, because RouterOS is still waiting for the bytes you told it to wait for. i.e. you send 0x06, but you never send "/login" through the socket.

But anyway... Why make a "frontend"? Having the web client see the RouterOS password would be bad if the app is publically visible. Having it be at the backend ensures nobody sees it.
 
si458
Frequent Visitor
Frequent Visitor
Topic Author
Posts: 65
Joined: Fri Jun 22, 2012 7:51 pm
Contact:

Re: api javascript help

Tue Mar 22, 2016 4:21 pm

You need to send both the length and the actual string which is that many bytes long.

From your example, it seems you're sending just the length byte, but never the actual message. You don't get any reply, because RouterOS is still waiting for the bytes you told it to wait for. i.e. you send 0x06, but you never send "/login" through the socket.

But anyway... Why make a "frontend"? Having the web client see the RouterOS password would be bad if the app is publically visible. Having it be at the backend ensures nobody sees it.
thank you for the help,
i am a developer of html javascript php etc but i dont really deal with sockets and bytes etc... so maybe abit more googline is in order :)

when i mean frontend, i want to write a html app that can connect to the mikrotik to get me stats etc, but i dont want to require a server

my idea was to use tcp sockets for javascript, bootstrap framework, then i can create a mobile app with phonegap/cordova

this is purely for our own use and maybe resell if i can get it working correct :)
 
User avatar
boen_robot
Forum Guru
Forum Guru
Posts: 2400
Joined: Thu Aug 31, 2006 4:43 pm
Location: europe://Bulgaria/Plovdiv

Re: api javascript help

Tue Mar 22, 2016 4:31 pm

Oh, so a mobile app, not a web app, I see. Well, in that case, it's limited to the device, so yeah, you could have it at JavaScript.

I'd think you can use NodeJS client as a starting point, seeing that the core language APIs are almost the same. Just replace its sockets with the chrome sockets or whatever, and you should be done with it.
 
si458
Frequent Visitor
Frequent Visitor
Topic Author
Posts: 65
Joined: Fri Jun 22, 2012 7:51 pm
Contact:

Re: api javascript help

Tue Mar 22, 2016 4:34 pm

Oh, so a mobile app, not a web app, I see. Well, in that case, it's limited to the device, so yeah, you could have it at JavaScript.
I'd think you can use NodeJS client as a starting point, seeing that the core language APIs are almost the same. Just replace its sockets with the chrome sockets or whatever, and you should be done with it.
I tried to copy the nodejs client to a javascript one but had no luck!

I could just do with some help understanding how to send the command in the BufferArray then I think I can handle everything else myself :)
 
User avatar
boen_robot
Forum Guru
Forum Guru
Posts: 2400
Joined: Thu Aug 31, 2006 4:43 pm
Location: europe://Bulgaria/Plovdiv

Re: api javascript help

Tue Mar 22, 2016 4:48 pm

Just add another call to chrome.sockets.tcp.send that sends "message", or better yet, make a single call that sends "abc + message", rather than just "abc".
 
si458
Frequent Visitor
Frequent Visitor
Topic Author
Posts: 65
Joined: Fri Jun 22, 2012 7:51 pm
Contact:

Re: api javascript help

Tue Mar 22, 2016 5:21 pm

Just add another call to chrome.sockets.tcp.send that sends "message", or better yet, make a single call that sends "abc + message", rather than just "abc".
chrome.sockets.tcp.send(createInfo.socketId, abc+"/login", function(send){ console.log('send'); });

Error in Success callbackId: ChromeSocketsTcp1742531529 : Error: chrome.sockets.tcp.send - data is not an Array Buffer! (Got: String) :(
 
User avatar
boen_robot
Forum Guru
Forum Guru
Posts: 2400
Joined: Thu Aug 31, 2006 4:43 pm
Location: europe://Bulgaria/Plovdiv

Re: api javascript help

Tue Mar 22, 2016 6:50 pm

Oooh... I see. So the buffer is the thing that needs to be sent, and has to contain all the data, and the constructor of ArrayBuffer is just the size (I thought it was the initial content).

Well then, in that case... it seems what you're actually doing is the opposite - you have the data "/login", but you don't have the length sent before that. Your buffer needs to also have an additional 1 byte to store the encoded length in.

In the end, you need to send the sequence
0x06 0x2F 0x6C 0x6F 0x67 0x69 0x6E
over the socket, but you're instead sending
0x2F 0x6C 0x6F 0x67 0x69 0x6E
meaning that RouterOS expects you to send far more bytes before it starts responding.


Soo... maybe
function str2ab2(message){
        //TODO: Encode word length according to the spec
        var encodedLength = message.length;
        
        var buffer = new ArrayBuffer(1/*byte length of the binary representation of encodedLength ?*/ + message.length);
        var bufferView = new Uint8Array(buffer);
        bufferView[0] = encodedLength;
        for (var i = 1; i <= message.length; ++i) {
                bufferView[i] = message.charCodeAt(i);
        }
        return buffer;
}
 
si458
Frequent Visitor
Frequent Visitor
Topic Author
Posts: 65
Joined: Fri Jun 22, 2012 7:51 pm
Contact:

Re: api javascript help

Tue Mar 22, 2016 8:16 pm

function str2ab2(message){
	var encodedLength = message.length;
	var buffer = new ArrayBuffer(encodedLength+2);
	var bufferView = new Uint8Array(buffer);
	bufferView[0] = encodedLength;
	for (var i = 0; i < message.length; i++) {
    		bufferView[i+1] = message.charCodeAt(i);
    	}
	bufferView[encodedLength+1] = "";
	return buffer;
}
YOU ARE A GENIUS!!! I LOVE YOU SO MUCH!!! :D

IF YOU LIVED IN THE UK AND NEAR MANCHESTER OR LIVERPOOL I WOULD BUY YOU A BEER!!!

I changed it slightly to send the command right after, but it works!!!
 
si458
Frequent Visitor
Frequent Visitor
Topic Author
Posts: 65
Joined: Fri Jun 22, 2012 7:51 pm
Contact:

Re: api javascript help

Sun Mar 27, 2016 2:20 pm

Hi,

ok now im having a problem logging in :(

i get the mikrotik to reply cannot login in, and i get a failed login in the logs

for some reason my challenge that is getting returned i cant convert it correctly to get its values?

example nodejs: =ret=cf 94 f9 5d 81 b0 fb 04 3e 01 8c 59 ec e6 fc 18 - focus on the 81
0x81
129


exmaple javascript: =ret=fc da 81 0e 23 8e d1 3e 77 f5 0e 93 0c 08 f9 34 - again focus on the 81
[Log] 0x81 (index.js, line 96)
[Log] 129 (index.js, line 97)
[Log]  (index.js, line 98)

any idea how i achieve getting the correct symbol?

also is this correct how i should be returning my response?
=response="00"+CryptoJS.MD5(String.fromCharCode(0)+vars.pass+challenge);

Simon
 
User avatar
boen_robot
Forum Guru
Forum Guru
Posts: 2400
Joined: Thu Aug 31, 2006 4:43 pm
Location: europe://Bulgaria/Plovdiv

Re: api javascript help

Thu Mar 31, 2016 8:10 pm

The challenge is a hex string that needs to be transformed to a binary string (which you can do by hex decoding the hex string), while the MD5 needs to be outputted in hex (which it seems CryptoJS already does...).

I think CryptoJS is referring to that as a "Latin1" encoding format... Just for a test drive prior, I tested everything with the string "apple". It's hash MD5 is "1f3870be274f6c49b3e31a0c6728957f" and the binary string of that hash is "8p¾'OlI³ãg(•".

After confirming the above, I believe you should be able to do it with
"00"+CryptoJS.MD5(String.fromCharCode(0)+vars.pass+CryptoJS.enc.Hex.parse(challenge).toString(CryptoJS.enc.Latin1))

BTW, now is as good as time as any to ask you... Please consider publishing your API client when you have it in some semi-useful state, and consider making it NodeJS compatible too, by adding a conditional "module.export" at the end.
 
si458
Frequent Visitor
Frequent Visitor
Topic Author
Posts: 65
Joined: Fri Jun 22, 2012 7:51 pm
Contact:

Re: api javascript help

Sun Apr 03, 2016 8:45 pm

Hi,

Im still having no look and I just don't no what I'm doing wrong :(

[code]
var thechallenge = data[1].substring(5); // 7e3f5affe828fd31f9d0b83f163c33c7
var x = CryptoJS.enc.Hex.parse(thechallenge).toString(CryptoJS.enc.Latin1); // ~?Zÿè(ý1ùи?<3Ç
var y = CryptoJS.MD5(String.fromCharCode(0)+vars.pass+x).toString(); // 457fe6ec93b698a9dc027734058f6b67
var response = "=response=00"+y; // =response=00457fe6ec93b698a9dc027734058f6b67
[/code]

reply from mikrotik is !trap=message=cannot log in!done

Simon
 
User avatar
boen_robot
Forum Guru
Forum Guru
Posts: 2400
Joined: Thu Aug 31, 2006 4:43 pm
Location: europe://Bulgaria/Plovdiv

Re: api javascript help

Sun Apr 03, 2016 9:54 pm

The full thing that needs to go on the network after you get the challenge is ANOTHER /login (prefixed with its encoded length), followed by the response attribute word (prefixed with its encoded length), followed by a null byte (a.k.a. a zero length word). Are you sure you're sending all of this? If you're only sending the attribute word, that can get you this error.
 
si458
Frequent Visitor
Frequent Visitor
Topic Author
Posts: 65
Joined: Fri Jun 22, 2012 7:51 pm
Contact:

Re: api javascript help

Sun Apr 03, 2016 10:10 pm

The full thing that needs to go on the network after you get the challenge is ANOTHER /login (prefixed with its encoded length), followed by the response attribute word (prefixed with its encoded length), followed by a null byte (a.k.a. a zero length word). Are you sure you're sending all of this? If you're only sending the attribute word, that can get you this error.
I think am already doing this so I don't get what I'm doing wrong? its giving me headaches at the mo

this is my code AFTER i send the FIRST /login command to get the challenge
function str2ab(message,end){
	end = end || false;
	var buffer = "";
	var bufferView = "";
	if(end&&message===''){
		buffer = new ArrayBuffer(1);
		bufferView = new Uint8Array(buffer);
		bufferView[0] = String.fromCharCode(0);
	}else{
		var encodedLength = message.length;
		buffer = new ArrayBuffer(encodedLength+1);
		bufferView = new Uint8Array(buffer);
		bufferView[0] = encodedLength;
		for (var i = 0; i < message.length; i++) {
			bufferView[i+1] = message.charCodeAt(i);
		}
	}
	console.log(buffer);
	return buffer;
}
var thechallenge = data[1].substring(5);
var x = CryptoJS.enc.Hex.parse(thechallenge).toString(CryptoJS.enc.Latin1);
var y = CryptoJS.MD5(String.fromCharCode(0)+vars.pass+x).toString();
var response = "=response=00"+y;
chrome.sockets.tcp.send(vars.socketId, str2ab("/login",false), function(send){
	console.log(send);
	chrome.sockets.tcp.send(vars.socketId, str2ab("=name="+vars.user,false), function(send){
		console.log(send);
		chrome.sockets.tcp.send(vars.socketId, str2ab(response,false), function(send){
			console.log(send);
			chrome.sockets.tcp.send(vars.socketId, str2ab("", true), function(send){
				console.log(send);
			});
		});
	});
});		
 
User avatar
boen_robot
Forum Guru
Forum Guru
Posts: 2400
Joined: Thu Aug 31, 2006 4:43 pm
Location: europe://Bulgaria/Plovdiv

Re: api javascript help

Sun Apr 03, 2016 10:53 pm

What exactly (length bytes included) do the logs say you've sent?
 
si458
Frequent Visitor
Frequent Visitor
Topic Author
Posts: 65
Joined: Fri Jun 22, 2012 7:51 pm
Contact:

Re: api javascript help

Sun Apr 03, 2016 11:04 pm

What exactly (length bytes included) do the logs say you've sent?
which logs are you referring to, is it possible to enable debug on the mikrotik router and see what it is receiving and decoding as?

this is my javascript logs:
[Log] done (index.js, line 190)
[Log] ["done", "=ret=b4fb9b6b1245780d464e3d9091e77bc4"] (2) (index.js, line 205)
[Log] b4fb9b6b1245780d464e3d9091e77bc4 (index.js, line 102)
[Log] ´û›kExFN=‘ç{Ä (index.js, line 162)
[Log] 329664b76a9a3b8bee007aeb7565cf66 (index.js, line 164)
[Log] =response=00329664b76a9a3b8bee007aeb7565cf66 (index.js, line 166)
[Log] ArrayBuffer {byteLength: 7} (index.js, line 18)
[Log] {bytesSent: 7, resultCode: 0} (index.js, line 168)
[Log] ArrayBuffer {byteLength: 12} (index.js, line 18)
[Log] {bytesSent: 12, resultCode: 0} (index.js, line 170)
[Log] ArrayBuffer {byteLength: 45} (index.js, line 18)
[Log] {bytesSent: 45, resultCode: 0} (index.js, line 172)
[Log] ArrayBuffer {byteLength: 1} (index.js, line 18)
[Log] {bytesSent: 1, resultCode: 0} (index.js, line 174)
[Log] !trap=message=cannot log in!done (index.js, line 28)
when i use wireshark and sniff the packets that get sent,
i can see from my laptop that it sends the individual bytes correctly as
/login =user=admin =response=00329664b76a9a3b8bee007aeb7565cf66
 
User avatar
boen_robot
Forum Guru
Forum Guru
Posts: 2400
Joined: Thu Aug 31, 2006 4:43 pm
Location: europe://Bulgaria/Plovdiv

Re: api javascript help

Sun Apr 03, 2016 11:12 pm

Wait, "=user="? You should be sending "=name=", and your code had it right... but the wireshark shows that's not what's sent in the end?
 
si458
Frequent Visitor
Frequent Visitor
Topic Author
Posts: 65
Joined: Fri Jun 22, 2012 7:51 pm
Contact:

Re: api javascript help

Sun Apr 03, 2016 11:15 pm

Wait, "=user="? You should be sending "=name=", and your code had it right... but the wireshark shows that's not what's sent in the end?
please forgive me its been a long day, I miss-typed/miss-spelt my post lol,
im sending it as =name= and still same results...
 
User avatar
boen_robot
Forum Guru
Forum Guru
Posts: 2400
Joined: Thu Aug 31, 2006 4:43 pm
Location: europe://Bulgaria/Plovdiv

Re: api javascript help

Sun Apr 03, 2016 11:32 pm

The other possibilities are that the sentence was ok, but login was refused. The API user needs to have the "api" permission, the address property needs to be empty or otherwise allow for your IP... and needless to say your password must be correct.

Try to login with another API client, and see if you get the same result.
 
si458
Frequent Visitor
Frequent Visitor
Topic Author
Posts: 65
Joined: Fri Jun 22, 2012 7:51 pm
Contact:

Re: api javascript help

Mon Apr 04, 2016 12:28 am

The other possibilities are that the sentence was ok, but login was refused. The API user needs to have the "api" permission, the address property needs to be empty or otherwise allow for your IP... and needless to say your password must be correct.

Try to login with another API client, and see if you get the same result.
I have created a test user with a group of test and only allowing api = not working
tried another mikrotik router with different credentials and ip addresses = not working

but yet if i use another api client, like NodeJS,php,java, it works fine!

so i dont follow what i am doing wrong?
 
si458
Frequent Visitor
Frequent Visitor
Topic Author
Posts: 65
Joined: Fri Jun 22, 2012 7:51 pm
Contact:

Re: api javascript help

Mon Apr 04, 2016 3:12 pm

Ok i have created a very simple test file for people to download to see where i am going wrong!
MikrotikTest.zip
it uses chrome.sockets.tcp so you can add the folder in chrome extensions as an app to test

http://pastebin.com/hTd9XTCG - this is my index.js file which is where all the magic should happen but doesnt :(
You do not have the required permissions to view the files attached to this post.

Who is online

Users browsing this forum: No registered users and 5 guests