129 lines
3.5 KiB
C
129 lines
3.5 KiB
C
//sorry
|
|
#define LDAP_DEPRECATED 1
|
|
|
|
#include <ldap.h>
|
|
#include <string.h>
|
|
#include <strings.h>
|
|
#include <stdio.h>
|
|
#include <assert.h>
|
|
#include <inttypes.h>
|
|
#include <openssl/sha.h>
|
|
#include "config.h"
|
|
|
|
const int NO_SUCH_CARD = LDAP_NO_SUCH_OBJECT;
|
|
|
|
// fucking gcc
|
|
size_t strnlen(const char *s, size_t maxlen);
|
|
|
|
static char* ldap_attrs_hashes[] = {
|
|
"uid",
|
|
"mifareIDHash",
|
|
0,
|
|
};
|
|
|
|
int hash_mifare(char *MifareID, char *salt, char* target) {
|
|
SHA256_CTX sha_c;
|
|
bzero(target, 130);
|
|
SHA256_Init(&sha_c);
|
|
SHA256_Update(&sha_c, salt, strnlen(salt, 64));
|
|
SHA256_Update(&sha_c, MifareID, strnlen(MifareID, 64));
|
|
strncat(target, salt, 63);
|
|
strcat(target, "$");
|
|
unsigned char hash[65];
|
|
SHA256_Final(hash, &sha_c);
|
|
target = target + strnlen(target, 64);
|
|
for(int i = 0; i < SHA256_DIGEST_LENGTH; ++i) {
|
|
sprintf(target, "%02x", hash[i]);
|
|
target += 2;
|
|
}
|
|
*(target + 1) = 0;
|
|
}
|
|
|
|
int ldap_dn_by_mifare(char *MifareID, char *DNOut, int *DNLength)
|
|
{
|
|
int i;
|
|
|
|
LDAP *ld;
|
|
LDAPMessage *msg, *entry;
|
|
int result = 0, version = LDAP_VERSION3, nentries;
|
|
unsigned char **values, crypt_hash[130],
|
|
entry_salt[20];
|
|
|
|
if(LDAP_SUCCESS != (result = ldap_initialize(&ld, LDAP_URL))) {
|
|
goto finalize;
|
|
}
|
|
if(LDAP_SUCCESS != (result = ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &version))) {
|
|
goto finalize;
|
|
}
|
|
/* if(LDAP_SUCCESS != (result = ldap_start_tls_s(ld, NULL, NULL))) {
|
|
goto finalize;
|
|
}*/
|
|
if(LDAP_SUCCESS != (result = ldap_bind_s(ld, LDAP_DN, LDAP_PW, LDAP_AUTH_SIMPLE))) {
|
|
goto finalize;
|
|
}
|
|
if(LDAP_SUCCESS != (result = ldap_search_s(ld, LDAP_BASE, LDAP_SCOPE_SUBTREE,
|
|
LDAP_FILTER_HASHES, ldap_attrs_hashes, 0, &msg))) {
|
|
goto search_finalize;
|
|
}
|
|
nentries = ldap_count_entries(ld, msg);
|
|
result = LDAP_NO_SUCH_OBJECT;
|
|
for(entry = ldap_first_entry(ld, msg); entry != NULL; entry = ldap_next_entry(ld, entry)) {
|
|
values = (unsigned char**)ldap_get_values(ld, entry, "mifareIDHash");
|
|
if(values) {
|
|
for(i = 0; values[i] != NULL; ++i) {
|
|
bzero(entry_salt, 20);
|
|
int hash_len = strcspn(values[i], "$");
|
|
strncpy(entry_salt, values[i], hash_len);
|
|
hash_mifare(MifareID, entry_salt, crypt_hash);
|
|
if(!strncmp(crypt_hash, values[i], 128)) {
|
|
char *dn = ldap_get_dn(ld, entry);
|
|
strncpy(DNOut, dn, *DNLength);
|
|
DNOut[*DNLength - 1] = 0;
|
|
*DNLength = strlen(dn);
|
|
ldap_memfree(dn);
|
|
result = 0;
|
|
}
|
|
}
|
|
ldap_value_free((char **)values);
|
|
}
|
|
}
|
|
search_finalize:
|
|
ldap_msgfree(msg);
|
|
finalize:
|
|
ldap_unbind_s(ld);
|
|
return result;
|
|
}
|
|
|
|
// because fuck you that's why
|
|
int ldap_uid_from_dn(char *DN, char *UIDOut)
|
|
{
|
|
char *KeyPair = DN;
|
|
int KeyPairLength = 0;
|
|
|
|
for (char *i = DN; i < DN + strlen(DN); i++)
|
|
{
|
|
if (*i == ',')
|
|
{
|
|
char *KeyPairSplit;
|
|
for (KeyPairSplit = KeyPair; *KeyPairSplit != '='; KeyPairSplit++) {}
|
|
|
|
int KeyLength = KeyPairSplit - KeyPair;
|
|
char *Key = KeyPair;
|
|
int ValueLength = KeyPairLength - KeyLength - 1;
|
|
char *Value = KeyPairSplit + 1;
|
|
|
|
|
|
if (KeyLength == 3 && strncmp(Key, "uid", KeyLength) == 0)
|
|
{
|
|
memcpy(UIDOut, Value, ValueLength);
|
|
UIDOut[ValueLength] = 0;
|
|
}
|
|
|
|
KeyPair = i + 1;
|
|
KeyPairLength = 0;
|
|
}
|
|
else
|
|
KeyPairLength++;
|
|
}
|
|
}
|