can not login with C API

is there any option howto setup mikrotik logging/API answers more debug?

I compiled C API from this site as libmtik.so on debian stable.
My own aplication (running single threaded in background as deamon ) is not able to login to device.
However utility from example does. Both using same library. I have no idea what is wrong. And logs and outputs are not very helpfull.


output from application

http://pastebin.com/ij9Zg5qS

logs on device

system,error,critical login failure for user admin from 10.x.y.z via winbox


[admin@DE] /system package> print
Flags: X - disabled

NAME VERSION SCHEDULED

0 routeros-mipsbe 3.31
1 system 3.31

Seeing the log, you’re successfully getting a !trap response, so at least we know it’s not a connection or socket problem.

Possible solutions:

  1. In the “/ip services”, make sure the IP you’re accessing the router from is allowed access. Set address to 0.0.0.0/0 if you’re not sure.
  2. In the “/user” menu, make sure the user “admin” is allowed access from the IP you’re accessing the router with. Again, set it to 0.0.0.0/0 if you’re not sure.
  3. In the “/user group” menu, make sure the group “admin” is in (should be the “full” group…) has “api” privileges.
    4. In the “/user active” menu, make sure there’s only one or two active connections. If there are more, reboot the router, and try again first with the daemon. Versions of RouterOS earlier than 5 leave connections hanging. To avoid that, successfull connections need to explicitly close the connection by sending a “/quit” command when they’re done.
  1. and 2. are set properly
  2. admin is in full privilleges group , but threre is no api policy , just winbox
  3. just one active connection via ssh, when I tried login

and sometime it works (1 of 10 ) and sometimes not (9 of 10 ), I couldn’t see the difference between :frowning:.

it’s possible to turn some more debug logging on device ?

Don’t know about that… but it might be a good idea to upgrade RouterOS. 3.31 is pretty old. Tons of API related bugs have been fixed since then.

so, you are able to log-in at least 1 in 10 times, in the rest of the cases you get an error (!trap message)

How fast your log-in sequence goes? from challenge (return to /login) till you have to respond to the that should be less than 10 seconds. And i understand that example client can log-in every single time.

i am trying to login in loop. with 1minute sleep.

and yes you are right example can login almost every single time.

Obviously then, remove the 1 minute sleep, and instead login as soon as you connect.

exactly, there is no need to wait for anything, if you can create connection - log-in immediately. After all that is application interface not user interface.

htat’s the way i am doing right know , here is some pseudo code
while(true)
{
sleep 1min.
dbconnect //postgresql
select * from devices;
for each device do {
apiConnect device
result=apiLogin device
test result
some code
apiDisconnect
}
other code.
dbDisconnect
}



after some TRY - FAIL i figure out , that it goes much better (it fails just cca 1 of 10 attemps ) when i comment out dbDisconnect.

it seems that problem is with your code and not with the router. so you could test with just API essential code and see if that brings any changes. after that add fancy bells and stuff.

from your description it oucld be that problem is with DB stuff - that socket data gets corrupted or something. But i cannot tell since we do not see the code you are using and all we can do is just guess.

i rewrite some test code , put it here http://pastebin.com/sZk357jQ , and it does exactly same problem

file is mikrotik2.c
md5.c and mikrotik-api.c are from wiki page

gargamel:/var/www/lms2/daemon/modules/mikrotik# gcc -g -o test mikrotik2.c mikrotik-api.c md5.c -lpq
gargamel:/var/www/lms2/daemon/modules/mikrotik# ./test
DON'T WORK
DON'T WORK
it work's
DON'T WORK
DON'T WORK
DON'T WORK
DON'T WORK
DON'T WORK
DON'T WORK
DON'T WORK
DON'T WORK

output after i comment PQfinish line

gargamel:/var/www/lms2/daemon/modules/mikrotik# gcc -g -o test mikrotik2.c mikrotik-api.c md5.c -lpq
gargamel:/var/www/lms2/daemon/modules/mikrotik# ./test
DON'T WORK
DON'T WORK
it work's
it work's
it work's
it work's
it work's
it work's
it work's
it work's
it work's
it work's
it work's
it work's
DON'T WORK
it work's

What if you fully comment out everything PQ* related (not just the PQfinish)?

It seems this is what’s messing things up. How exactly do you go about fixing it though… I have two ideas, but am not sure of either:

  1. Take both connections out of the loop. I mean, why do you want to keep reconnecting all the time? Why not keep a single connection on?
  2. Connect and login to RouterOS before you connect and login to the DB. Hopefully, the DB library is written better than the RouterOS library on the wiki, i.e. it won’t be disturbed by the presense of another network connection.
  1. it’s one of the option I already thought about. But this application suppose to work as deamon, so I guess it’s better/easier to connect and disconnect in every loop , rather than check whether connection is still active and working, and if not reconnect.
    (and maybe with same effect for api connect :frowning: )

  2. it’s not possible , because i get info from DB, to which router i have to log in and change the configuration.


    Therefore I started with the oldest device I have (3.31), but I tried this on RouterOS 4.17 and 5.14 , with simmilar behavior.
    There is no sence for me, how can PQfinish affect mikrotik api. And i don’t know how to debug it :frowning:.
    So it’s pretty interesting bug somewhere ,but I don’t know where. Is someone able to reproduce this error ?


    my version of gcc, and libpq , kernel

ii libpq-dev 8.4.11-0squeeze1 header files for libpq5 (PostgreSQL library)
ii libpq5 8.4.11-0squeeze1 PostgreSQL C client library
ii gcc 4:4.4.5-1 The GNU C compiler
ii linux-image-2.6.32-5-amd64 2.6.32-41 Linux 2.6.32 for 64-bit PCs

seeems that problem is with MD5,
i re caalculate all md5 i’ve sent to device, and some of them were wrong.

Wow. I never would’ve guessed that…

Oh well… you could use another MD5 implementation, such as the one in OpenSSL.

e.g.
http://stackoverflow.com/questions/1220046/in-c-how-to-get-md5-hash-of-a-file

i hope it wasn’t ironic :slight_smile:

I did it right after I found , that issue is with md5 , but without succces.
Then I read the code through and through and get suspicion with

szMD5ChallengeBinary = md5ToBinary(szMD5Challenge);
md5_append(&state, (const md5_byte_t *)szMD5ChallengeBinary, strlen(szMD5ChallengeBinary));

of course, it could not calculate right lenght of string , because that string , is not ‘\0’ terminated :wink:,
when I change strlen(szMD5ChallengeBinary) just to number 16 it’s start working. I will test my code. and maybe attach new version of C api here.
Thanx guys for your valuable opinions , and I hope this was the root cause of all the issues.

i hope it wasn’t ironic

It wasn’t. I really would never suspect a hashing implementation to be the problem, because anyone who has the balls to implement or even just define one (as you can guess, I’ve never written or defined any hashing implementation in any language) typically has the skills to implement it right…

of course, it could not calculate right lenght of string , because that string , is not ‘\0’ terminated ,

… and it seems I was half right about that. As you imply, the problem was not the MD5 implementation, but the way the mikrotik-api.c uses it.

I will test my code. and maybe attach new version of C api here.

Yes, please!

(and this too is not ironic)

i was just thinking , that same issue should be on the other c language API’s , and in C API for winsock, and C++, it’s already corrected, so if I carefully read the other code, maybe I’d find it sooner :slight_smile:.

for my c++ code i went for openssl implementation and results compared to working python and java implementations at hand. (that is - regarding hashing)