-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Decode objectGUI from binary string. #60
Decode objectGUI from binary string. #60
Conversation
I had a look on this, not a Typescript developer, but I managed to come up with something: const testPairs = [
["5M3HPmBsh0SbNM61wk8yhw==", "e4cdc73e-606c-8744-9b34-ceb5c24f3287"],
["TSHX64TMpUe0LxqVJ8Z+2w==", "4d21d7eb-84cc-a547-b42f-1a9527c67edb"],
["/fKTMip56kKvF9C+tAnrTg==", "fdf29332-2a79-ea42-af17-d0beb409eb4e"],
];
function decodeBase64ToBinary(base64String: string): Uint8Array {
const binaryString = atob(base64String);
const binaryData = new Uint8Array(binaryString.length);
for (let i = 0; i < binaryString.length; i++) {
binaryData[i] = binaryString.charCodeAt(i);
}
return binaryData;
}
function objectGUIDToUUID(objectGUID: Uint8Array) {
const dashPos = [4, 6, 8, 10];
let guid = "";
for (let i = 0; i < objectGUID.length; i++) {
if (dashPos.includes(i)) {
guid += "-";
}
guid += objectGUID[i].toString(16).padStart(2, "0");
}
return guid;
}
for (let i = 0; i < testPairs.length; i++) {
const pair = testPairs[i];
console.log(`Value: ${pair[1]} Expected: ${objectGUIDToUUID(decodeBase64ToBinary(pair[0]))}`)
} So this works and the values I used as Base64-encoded binary data are real-life GUIDs from an Entra system on my side. However, looking at the code on your side I saw that the function accepts a string parameter:
Digging further, I saw that this actually comes from how ldapjs works: https://github.com/ldapjs/attribute/blob/d1cba4723fb6953a932a71b53a8d842eeab564c7/index.js#L88 Then I also see that the value should already be a Base64-encoded string, or at least this is how I understand it: https://github.com/ldapjs/attribute/blob/d1cba4723fb6953a932a71b53a8d842eeab564c7/index.js#L342 To summarize, maybe it's as easy as replacing I realize I should have actually forked the repo instead of writing a novel here. Sorry 😄 |
@petarov thank you so much for coming up with this implementation! I have incorporated this into the changeset. Somehow, for me, the Would you be in a position to test the changes? You may find the new You may install the By default the attributes below are treated as binary and will be rendered as Base64 (except
Thanks! |
@fengtan Looks great! I tested with 2 different Windows AD servers, checking about 5 different users and 3 different groups, and the Just an understanding question: does it make sense for Thanks a lot for working on this. Really appreciate it. |
Thanks for testing! 👍 @gwythan, since you also showed interest in this feature in #33, do you happen to be in a position to test and confirm whether the decoded objectGUID's are correct on your side?
If was not sure how to handle this myself, but, indeed, if |
I forgot to uncheck the |
@fengtan I need to come back on this, because I finally managed to run and test with ADS and you are right that the guid values differ. I read some more about this and now I think I know why. Apparently the So this is where the discrepancy comes from. My implementation does not take this into account and displays the UUID string in little-endian order instead of big-endian like ADS. On my side it looked ok, because I used an internal tool that does not convert to big-endian order and I also just got Microsoft AD servers here, so I never noticed this. The implementation needs to be adjusted, but I still wonder how to determine the original order of the function objectGUIDToUUID(objectGUID: Uint8Array, bigEndian = false): string {
const dashPos = [4, 6, 8, 10];
let guid = "";
const objectGUIDOrdered = bigEndian ? [
...Array.from(objectGUID.slice(0, 4).reverse()),
...Array.from(objectGUID.slice(4, 6).reverse()),
...Array.from(objectGUID.slice(6, 8).reverse()),
...Array.from(objectGUID.slice(8, 16)),
] : objectGUID;
for (let i = 0; i < objectGUIDOrdered.length; i++) {
if (dashPos.includes(i)) {
guid += "-";
}
guid += objectGUIDOrdered[i].toString(16).padStart(2, "0");
}
return guid;
} |
Wow amazing, thank you so much for finding out about this @petarov! Indeed if I reorder the bytes using the algorithm you suggested (ecd3992) then the values are identical to those of Apache Directory Studio (I use Active Directory myself). I don't see a way to automatically detect whether an LDAP server runs on Microsoft, or which type of endianness a |
You're right, That being said I just remembered that I had to also deal with Google AD earlier this year and they do use the by-the-spex Actually, authenticating via a JKS file instead of bind user/pass would be a nice feature to add, since that's what Google prefer, but let's leave that for another issue. |
Merged - thanks again @petarov! |
No description provided.