I have spent a couple hours trying to debug this but this is not working on a mac. This code is from http://wiki.mikrotik.com/wiki/API_in_C. From what I can tell the issue is in the md5 conversion. I tested the md5 on just my password and that worked correctly according to md5 converters online. I then tested it with the challenge hash in place and it was then wrong. I worked with another piece of code that works in C# to try and figure out where and why it is not working but I cant seem to figure out what is wrong. Any ideas? I attached a log file for the login process to follow as well.
The first login is working fine. The second is failing.
int MikrotikAPI::login(int fdSock, char *username, char *password)
{
struct Sentence stReadSentence;
struct Sentence stWriteSentence;
char *szMD5Challenge;
char *szMD5ChallengeBinary;
char *szMD5PasswordToSend;
char *szLoginUsernameResponseToSend;
char *szLoginPasswordResponseToSend;
md5_state_t state;
md5_byte_t digest[16];
char cNull[1] = {0};
writeWord(fdSock, "/login");
writeWord(fdSock, "");
stReadSentence = readSentence(fdSock);
DEBUG ? printSentence (&stReadSentence) : 0;
if (stReadSentence.iReturnValue != DONE)
{
printf("error.\n");
exit(0);
}
// extract md5 string from the challenge sentence
szMD5Challenge = strtok(stReadSentence.szSentence[1], "=");
szMD5Challenge = strtok(NULL, "=");
DEBUG ? printf("MD5 of challenge = %s\n", szMD5Challenge) : 0;
// convert szMD5Challenge to binary
szMD5ChallengeBinary = md5ToBinary(szMD5Challenge);
// get md5 of the password + challenge concatenation
md5_init(&state);
md5_append(&state, (const md5_byte_t *) cNull, 1);
md5_append(&state, (const md5_byte_t *)password, strlen(password));
md5_append(&state, (const md5_byte_t *)szMD5ChallengeBinary, strlen(szMD5ChallengeBinary));
md5_finish(&state, digest);
// convert this digest to a string representation of the hex values
// digest is the binary format of what we want to send
// szMD5PasswordToSend is the "string" hex format
szMD5PasswordToSend = md5DigestToHexString(digest);
DEBUG ? printf("szPasswordToSend = %s\n", szMD5PasswordToSend) : 0;
// put together the login sentence
initializeSentence(&stWriteSentence);
addWordToSentence(&stWriteSentence, "/login");
addWordToSentence(&stWriteSentence, "=name=");
addPartWordToSentence(&stWriteSentence, username);
addWordToSentence(&stWriteSentence, "=response=00");
addPartWordToSentence(&stWriteSentence, szMD5PasswordToSend);
DEBUG ? printSentence(&stWriteSentence) : 0;
writeSentence(fdSock, &stWriteSentence);
stReadSentence = readSentence(fdSock);
DEBUG ? printSentence (&stReadSentence) : 0;
if (stReadSentence.iReturnValue == DONE)
{
return 1;
}
else
{
return 0;
}
}
[Session started at 2010-02-02 05:44:46 -0800.]
Connecting to 64.126.135.214
Successfully connected to 64.126.135.214
Word to write is /login
length of word is 6
Word to write is
length of word is 0
readSentence
initializeSentence
start readLen()
byte1 = 0x5
1-byte encoded length
readWord iLen=5
word = !done
return sentence contains !done
start readLen()
byte1 = 0x25
1-byte encoded length
readWord iLen=25
word = =ret=7482c02112f004b6cc5685bc1a1563e7
start readLen()
byte1 = 0
1-byte encoded length
readWord iLen=0
stReturnSentence.szSentence[0] = !done
stReturnSentence.szSentence[1] = =ret=7482c02112f004b6cc5685bc1a1563e7
Sentence iLength = 2
Sentence iReturnValue = 1
Sentence iLength = 2
Sentence iReturnValue = 1
>>> !done
>>> =ret=7482c02112f004b6cc5685bc1a1563e7
MD5 of challenge = 7482c02112f004b6cc5685bc1a1563e7
cBinWork = 74
116
cBinWork = 82
130
cBinWork = c0
192
cBinWork = 21
33
cBinWork = 12
18
cBinWork = f0
240
cBinWork = 04
4
cBinWork = b6
182
cBinWork = cc
204
cBinWork = 56
86
cBinWork = 85
133
cBinWork = bc
188
cBinWork = 1a
26
cBinWork = 15
21
cBinWork = 63
99
cBinWork = e7
231
szPasswordToSend = 6047dbf2c1b49e19130e426aee2674f0
initializeSentence
Sentence iLength = 3
Sentence iReturnValue = 0
Sentence iLength = 3
Sentence iReturnValue = 0
>>> /login
>>> =name=test
>>> =response=006047dbf2c1b49e19130e426aee2674f0
Writing sentence
Sentence iLength = 3
Sentence iReturnValue = 0
Sentence iLength = 3
Sentence iReturnValue = 0
>>> /login
>>> =name=test
>>> =response=006047dbf2c1b49e19130e426aee2674f0
Word to write is /login
length of word is 6
Word to write is =name=test
length of word is 10
Word to write is =response=006047dbf2c1b49e19130e426aee2674f0
length of word is 44
Word to write is
length of word is 0
readSentence
initializeSentence
start readLen()
byte1 = 0x5
1-byte encoded length
readWord iLen=5
word = !trap
return sentence contains !trap
start readLen()
byte1 = 0x16
1-byte encoded length
readWord iLen=16
word = =message=cannot log in
start readLen()
byte1 = 0
1-byte encoded length
readWord iLen=0
readSentence
initializeSentence
start readLen()
byte1 = 0x5
1-byte encoded length
readWord iLen=5
word = !done
return sentence contains !done
start readLen()
byte1 = 0
1-byte encoded length
readWord iLen=0
stReturnSentence.szSentence[0] = !done
stReturnSentence.szSentence[0] = !trap
stReturnSentence.szSentence[1] = =message=cannot log in
Sentence iLength = 2
Sentence iReturnValue = 2
Sentence iLength = 2
Sentence iReturnValue = 2
>>> !trap
>>> =message=cannot log in
Closing socket
Invalid username or password.