Community discussions

MikroTik App
 
taz
just joined
Topic Author
Posts: 11
Joined: Thu Feb 03, 2005 6:16 pm

API login and MD5

Wed Feb 06, 2008 6:01 pm

Hi,

i can not login to routeros . i send >

<<< /login (send as length = 6 and "/login" as byte)
<<< (send 0 )

routeros answer
>>> !done
>>> =ret=9dda3fbe58072fed523fe5f6c4ce0644

i send
<<< /login
<<< =name=admin
<<< =response=00+md5New

md5New is >
string retOld = 9dda3fbe58072fed523fe5f6c4ce0644
string password = "1234"
MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
byte[] md5Hash = md5.ComputeHash(ASCIIEncoding.ASCII.GetBytes("00" + StringToHex(password) + RetOld));
string md5New = BitConverter.ToString(md5Hash);
md5New = md5New.Replace("-",""); // from 5A-6D-55 to 5A6D55 e.g. 
md5New = md5New.ToLower(); // from 5a6d55 e.g.

Mikrotik answer >
>>>♣
>>>!trap▬=message=cannot log in ♣!done

pls help...

thx
 
User avatar
janisk
MikroTik Support
MikroTik Support
Posts: 6263
Joined: Tue Feb 14, 2006 9:46 am
Location: Riga, Latvia

Re: API login and MD5

Thu Feb 07, 2008 9:58 am

it looks like basic and i do not know much about that, so i will give you example how i did it in java all what i need to login

mainly check login() method and other what i posted here is what i used in that login method

here is the thread:
http://forum.mikrotik.com/viewtopic.php ... api#p83404

so here it goes

this method is used to send last string of the command to the RouterOS, of course, it can be implemented some more elegant way, this is used to finish a command but:
    private void writeln(String s){
        try {
            out.writeByte( new Integer(s.length()).byteValue());
            out.writeBytes( s + "\0");
            System.out.println(s);
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }


same as above, just sends one line of the command
    private void write(String s){
        try {
            Integer t = new Integer(s.length());
            out.writeByte(t.byteValue());
            out.writeBytes(s);
            System.out.println(s);
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
this reads stuff that is returned by routeros API
    private String[] read(){
        String s="";
        boolean haveSymbols = true;
        try {
            char ch;
            while (true){
                while (haveSymbols){
                    byte b = in.readByte();
                    if (b!=0x00){
                        s+="\n";
                        
                        for (int count=0;count<b;count++){
                            ch = (char)(in.readByte() & 0xFF);
                            s+=ch;
                        }
                    }else haveSymbols=false;
                    
                }
                if (s.contains("!done")) return  s.split("\n");
                
                haveSymbols = true;
                
            }
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        return null;
    }
this is how to make connection using java
    public boolean connect(String ipAddress, int ipPort){
        boolean ret = false;
        try {
            socket = new Socket(ipAddress,ipPort);
            in = new DataInputStream(socket.getInputStream());
            out = new DataOutputStream(socket.getOutputStream());
            ret = true;
        } catch (UnknownHostException ex) {
            ex.printStackTrace();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        return ret;
    }

this is how i managed the login
    
    public boolean login(String login, String password){
        String[] readIn;
        String transition ="";
        boolean ret = false;
        writeln("/login");
        readIn = read();
        for (int i=0; i<readIn.length;i++){
            System.out.println(readIn[i]);
        }
        String[] tmp = readIn[2].split("=ret=");
        transition = tmp[tmp.length-1];
        String chal="";
        chal=MessageDigestHelper.myHexStrToStr("00") + password + MessageDigestHelper.myHexStrToStr(transition);
        chal = MessageDigestHelper.myMD5Helper(chal);
        write("/login");
        write("=name="+login);
        writeln("=response=00"+chal);
        readIn = read();
        for (int i=0; i<readIn.length;i++){
            System.out.println(readIn[i]);
        }
        if (readIn[readIn.length-1].contains("!done")){
            if (readIn[1].contains("!trap")){
                return false;
            } else
                return true;
        }
        return ret;
    }
and now missing peaces that i used in login method (hope they are self explanatory:
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 *
 * @author janisk
 */
public class MessageDigestHelper {
    
    /** Creates a new instance of MessageDigestHelper */
    public MessageDigestHelper() {
    }
    static public String myMD5Helper(String s){
        String md5val = "";
        MessageDigest algorithm = null;
        try {
            algorithm = MessageDigest.getInstance("MD5");
        } catch (NoSuchAlgorithmException nsae) {
            System.out.println("Cannot find digest algorithm");
            System.exit(1);
        }
        byte[] defaultBytes = new byte[s.length()];
        for (int i=0;i<s.length();i++){
            defaultBytes[i] = (byte)(0xFF & s.charAt(i));
        }
        algorithm.reset();
        algorithm.update(defaultBytes);
        byte messageDigest[] = algorithm.digest();
        StringBuffer hexString = new StringBuffer();
        
        for (int i = 0; i < messageDigest.length; i++) {
            String hex = Integer.toHexString(0xFF & messageDigest[i]);
            if (hex.length() == 1) {
                hexString.append('0');
            }
            hexString.append(hex);
        }
        return hexString.toString();
    }
    static public String myHexStrToStr(String s){
        String ret ="";
        for (int i = 0; i<s.length();i+=2){
            ret += (char)Integer.parseInt(s.substring(i,i+2),16);
        }
        return ret;
    }
}
 
User avatar
janisk
MikroTik Support
MikroTik Support
Posts: 6263
Joined: Tue Feb 14, 2006 9:46 am
Location: Riga, Latvia

Re: API login and MD5

Thu Feb 07, 2008 10:04 am

one missing method

it is used to send commands and receive the results
    public String[] progTalk(String text){
        text=text.trim();
        int counter = 0;
        String tag = "";
        if (text.contains("\n")){
            tag = text.substring(0,text.indexOf("\n"));
        } else tag = text;
        text = text.concat("\n.tag="+tag);
        String[] internalText = text.split("\n");
        while (counter < internalText.length-1){
            write(internalText[counter]);
            counter++;
        }
        writeln(internalText[counter]);
        return read();
    }

hope it helps as java is not that different from C#
 
taz
just joined
Topic Author
Posts: 11
Joined: Thu Feb 03, 2005 6:16 pm

Re: API login and MD5

Thu Feb 07, 2008 11:02 am

thx thx thx

i try it and post results
 
User avatar
Chupaka
Forum Guru
Forum Guru
Posts: 8679
Joined: Mon Jun 19, 2006 11:15 pm
Location: Minsk, Belarus
Contact:

Re: API login and MD5

Fri Feb 08, 2008 2:47 am

MikroTik, why do you use md5("\0" + paswd + challenge)? it's easy to bruteforce password, if you know the challenge and the answer! maybe look at HMAC algorithm or others?
Russian-speaking forum: https://forum.mikrotik.by/. Welcome!

For every complex problem, there is a solution that is simple, neat, and wrong.

MikroTik. Your life. Your routing.
 
Aroca
just joined
Posts: 16
Joined: Mon Jun 02, 2008 6:13 pm
Location: Spain

Re: API login and MD5

Thu Jul 10, 2008 2:14 pm

Is it possible to save scan data received form the router when I send via a java API:
/interface/wireless/scan
=.id=X
?
 
User avatar
janisk
MikroTik Support
MikroTik Support
Posts: 6263
Joined: Tue Feb 14, 2006 9:46 am
Location: Riga, Latvia

Re: API login and MD5

Wed Oct 08, 2008 10:42 am

it does not matter much what programming language you use to use API calls on RouterOS.

to get scan you use command:
/interface/wireless/scan
=.id=*4
i would suggest to use TAG, so you can /cancel the command and not every other single command that is running at the moment.

also your =tag= will be used to report back, so you can see the difference from what command you are receiving data.
 
hrico
just joined
Posts: 12
Joined: Wed Dec 16, 2009 2:25 am

Re: API login and MD5

Tue May 04, 2010 10:43 pm

to get scan you use command:
/interface/wireless/scan
=.id=*4
I have two wlan interfaces and if I try either "=.id=*0" or "=.id=*1" it gives me this output:
!trap=message=no such item (4)
!done
... Do you know where could be a problem?
 
SurferTim
Forum Guru
Forum Guru
Posts: 4636
Joined: Mon Jan 07, 2008 10:31 pm
Location: Miramar Beach, Florida

Re: API login and MD5

Tue May 04, 2010 11:15 pm

You need to retrieve the item numbers for the wireless cards. If you are just testing, you can find the id of the cards with this at the command prompt:

/interface wireless
:put [find];

The values displayed should explain themselves.

BTW, you should have started an new topic.
 
hrico
just joined
Posts: 12
Joined: Wed Dec 16, 2009 2:25 am

Re: API login and MD5

Wed May 05, 2010 12:44 am

I tried it and here is the result:

[admin@Mikrotik] /interface wireless> :put [find]
*b;*c

... maybe its too late for the values to explain themselves ;) but I don't get what that *b and *c means. I tried to use it as an .id, but did not work again.

Could you please explain me.

PS:Thanks for warning, next time I ll start a new topic.
 
SurferTim
Forum Guru
Forum Guru
Posts: 4636
Joined: Mon Jan 07, 2008 10:31 pm
Location: Miramar Beach, Florida

Re: API login and MD5

Wed May 05, 2010 1:30 am

I have only one card in my test unit, and it returns *4.
If I do the same in "/interface ethernet", it returns *1;*2;*3
Got me...
 
User avatar
Chupaka
Forum Guru
Forum Guru
Posts: 8679
Joined: Mon Jun 19, 2006 11:15 pm
Location: Minsk, Belarus
Contact:

Re: API login and MD5

Wed May 05, 2010 2:08 pm

by the way, you may use 'name' value in '.id' field: '=.id=wlan1,wlan2,*ab12'
Russian-speaking forum: https://forum.mikrotik.by/. Welcome!

For every complex problem, there is a solution that is simple, neat, and wrong.

MikroTik. Your life. Your routing.
 
charlytik
just joined
Posts: 1
Joined: Tue May 05, 2009 10:56 am

Re: API login and MD5

Thu May 20, 2010 12:44 am

Hi!, i have compiled the classes, i see the log in the mikrotik, and i can login, but i don't understand how to retrieve data.
I have routeros 4.5, and i test the classes as follows:
public static void main(String [] args){
mkt m=new mtk();
m.connect("189...",8728);
m.login("admin","password");
}

Thanks and sorry for my english.
 
User avatar
Chupaka
Forum Guru
Forum Guru
Posts: 8679
Joined: Mon Jun 19, 2006 11:15 pm
Location: Minsk, Belarus
Contact:

Re: API login and MD5

Thu May 20, 2010 1:16 am

it depends on your implementation
Russian-speaking forum: https://forum.mikrotik.by/. Welcome!

For every complex problem, there is a solution that is simple, neat, and wrong.

MikroTik. Your life. Your routing.
 
User avatar
janisk
MikroTik Support
MikroTik Support
Posts: 6263
Joined: Tue Feb 14, 2006 9:46 am
Location: Riga, Latvia

Re: API login and MD5

Thu May 20, 2010 12:12 pm

it should be noted that .ID fields are in hexadecimal system, seeing *5,*b,*c,*10 in decimal would look like *5,*11,*12,*16

data retrieval works similar to CLI, just with small changes
look here for details:
http://wiki.mikrotik.com/wiki/API

and links.

if you are logged in, that means you can read from socket and write to it, you are like 99% done :)

now, just make that you can send other commands and read from socket. you can look at login method to see how reading and writing is done.
 
wraith4
just joined
Posts: 1
Joined: Mon May 09, 2011 2:00 pm

Re: API login and MD5

Mon May 09, 2011 2:46 pm

Hello there,
I really appreciate this example and the example in wiki. But I have little problem with retrieving data from DataInputStream. Basically, when I'm requesting a large amount of data and the Mikrotik device is busy, the DataInputStream (or Socket) doesn't retrieves any data and uses NULL instead. It uses NULL simply because it has no data.

In fact, if the word (row) has length of 100 bytes, we retrive only first 70 bytes, then is delay (made by Mikrotik device), this delay is replaced with NULL by Socker reader. And missing 30 bytes are mixed in the next word (row). The final output looks like this:
=.id=*16
=address=10.20.7.35
=mac-ad
ress=00:00:DB:22:1A:2E=client-id=1:0:0:db:22:1a:2e
=server=dhcp1
=radius=false=dynamic=false=bloc
ed=false=disabled=true]=comment=Piha

We found temporary solution with ugly hack in ReadCommand class:
a = in.read(bb, 0, sk);
Thread.sleep(20);

But haven't anybody experienced this issue too? I don't like our solution and I willl be very grateful for better suggestion.

Thank you.
 
miladcsharp
just joined
Posts: 2
Joined: Sun Oct 02, 2011 1:34 am

Re: API login and MD5

Sun Oct 02, 2011 1:52 am

i wanna add new account on userman (with some options : Profile,User,Pass,Email...) . how can do it with command ? (**in C#.net4 - WinApp**)
 
User avatar
janisk
MikroTik Support
MikroTik Support
Posts: 6263
Joined: Tue Feb 14, 2006 9:46 am
Location: Riga, Latvia

Re: API login and MD5

Mon Oct 03, 2011 1:04 pm

if i have understood you correctly you have to take updated java API that has correct read/write function. It seems that you encounter.

It can read length of up to 0x80 bytes. As result you read only part and then output gets bad. and get a lot of NULLs as result, since buffer you are reading from is empty.

Who is online

Users browsing this forum: Baidu [Spider], kometchtech, mkx and 32 guests