Mikrotik API Integration via RAW TCP CLIENT Need help

Hello everyone. I hope someone could be of assistance for me.

So I am trying to integrate a mikrotik via a 3rd party device via api on port 8728.
The limitation that i have is all commands are to be send via a raw tcp client. I assumed that this would not be a problem. As the wiki documentation did show there is a method to send the login command via plain text. See wiki source at Header: Initial login > Login method post-v6.43.

Unfortunately all attempts i have tried has failed. I can perfectly simulate a login via the older method (Login method pre-v6.43:) but as i have no method to do the md5 this would not be possible.
test.png
The raw hex of the login method pre v6.43 would have been:

Client: {06}/login{00} {/login}
Response: {05}!done%=ret=ed00d2eaecf6d019692e2159f85dfcfb{00}
Client: {06}/login{0B}=name=admin,=response=00**********************************{00}

i need to be able to do an single string client login request such as the last one shown, where except for =response= i need to add password. Unfortunately i am not successful with this?

Is there something that i am missing? should i have a specific end string? i have tried 0d but that did not work and received no response.

There is a python example client that works with both pre and post 6.43 versions.

Look at the code, it will show exactly what you need to do
https://wiki.mikrotik.com/wiki/Manual:API#Example_client

I think there is a breakdown in communication.

I can easily accomplish this task if i where to use programing languages. I have looked at the code, and got it working via Python. But unfortunately this code use the pre 6.43 iteration when i investigate the packets via wire-shark.

I need to able to send the data via a raw tcp client connection, and unfortunately i am missing something as i can’t get it working?

Do you have an sample that only uses the post 6.43 method?

No, example as per API documentation uses post 6.43 login method by default

  • on first attempt sends /login =name=xxx =password=yyy
  • if it returns !trap exit
  • if it returns “=ret”, then fall back to pre 6.43 login method

you can see this in “login” function.

    def login(self, username, pwd):
        for repl, attrs in self.talk(["/login", "=name=" + username,
                                      "=password=" + pwd]):
          if repl == '!trap':
            return False
          elif '=ret' in attrs.keys():
        #for repl, attrs in self.talk(["/login"]):
            chal = binascii.unhexlify(attrs['=ret'])
            md = md5.new()
            md.update('\x00')
            md.update(pwd)
            md.update(chal)
            for repl2, attrs2 in self.talk(["/login", "=name=" + username,
                   "=response=00" + binascii.hexlify(md.digest())]):
              if repl2 == '!trap':
                return False
        return True