Я пытаюсь создать клиент python для bacula, но у меня есть некоторые проблемы с аутентификацией.
Алгоритм:
import hmac
import base64
import re
...
challenge = re.search("auth cram-md5 ()", data)
#exemple ''
passwd = 'b489c90f3ee5b3ca86365e1bae27186e'
hm = hmac.new(passwd, challenge).digest()
rep = base64.b64encode(hm).strp().rstrip('=')
#result with python : 9zKE3VzYQ1oIDTpBuMMowQ
#result with bacula client : 9z+E3V/YQ1oIDTpBu8MowB'
Есть ли способ, более простой, чем перенос выполнения бакулы базы 64?
int bin_to_base64(char *buf, int buflen, char *bin, int binlen, int compatible) { uint32_t reg, save, mask; int rem, i; int j = 0; reg = 0; rem = 0; buflen--; /* allow for storing EOS */ for (i=0; i >= (rem - 6); if (j
Чтобы проверить вашу реализацию CRAM-MD5, лучше всего использовать некоторые простые тестовые векторы и проверить комбинации входов (вызов, пароль, имя пользователя) против ожидаемого результата.
Вот один пример (из http://blog.susam.in/2009/02/auth-cram-md5.html):
import hmac
username = '[email protected]'
passwd = 'drowssap'
encoded_challenge = 'PDc0NTYuMTIzMzU5ODUzM0BzZGNsaW51eDIucmRzaW5kaWEuY29tPg=='
challenge = encoded_challenge.decode('base64')
digest = hmac.new(passwd, challenge).hexdigest()
response = username + ' ' + digest
encoded_response = response.encode('base64')
print encoded_response
# Zm9vQHN1c2FtLmluIDY2N2U5ZmE0NDcwZGZmM2RhOWQ2MjFmZTQwNjc2NzIy
Тем не менее, я определенно нашел примеры в сети, где ответ, созданный вышеуказанным кодом, отличается от ожидаемого ответа, указанного на соответствующем сайте, поэтому я все еще не совсем понимаю, что происходит в этих случаях.
Я УБИЛ ЭТО.
Я столкнулся с той же проблемой, что и вы, и потратил около 4 часов на выявление проблемы и повторил ее.
Проблема в том, что Bacula base64 БРОКЕН, И НЕПРАВИЛЬНО!
Есть две проблемы:
Во-первых, входящие байты обрабатываются как подписанные, а не без знака. Эффект от этого заключается в том, что если бит имеет самый старший бит ( > 127), то он рассматривается как отрицательное число; когда он объединен с "оставшимися" битами из предыдущих байтов, все установлены в (двоичный 1).
Во-вторых, после того, как b64 обработал все полные 6-битные выходные блоки, может остаться 0, 2 или 4 бит (в зависимости от модуля входного блока 3). Стандартный способ Base64 для этого состоит в том, чтобы умножить оставшиеся биты, поэтому они являются ВЫСОКИМИ битами в последнем 6-битном блоке и обрабатывают их - Bacula оставляет их как LOWEST бит.
Обратите внимание, что некоторые версии Bacula могут принимать как "Bacula broken base64 encoding", так и стандартные, для входящей аутентификации; они, похоже, используют сломанный для их аутентификации.
def bacula_broken_base64(binarystring):
b64_chars="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
remaining_bit_count=0
remaining_bits=0
output=""
for inputbyte in binarystring:
inputbyte=ord(inputbyte)
if inputbyte>127:
# REPRODUCING A BUG! set all the "remaining bits" to 1.
remaining_bits=(1 << remaining_bit_count) - 1
remaining_bits=(remaining_bits<<8)+inputbyte
remaining_bit_count+=8
while remaining_bit_count>=6:
# clean up:
remaining_bit_count-=6
new64=(remaining_bits>>remaining_bit_count) & 63 # 6 highest bits
output+=b64_chars[new64]
remaining_bits&=(1 << remaining_bit_count) - 1
if remaining_bit_count>0:
output+=b64_chars[remaining_bits]
return output
Я понимаю, что прошло 6 лет с тех пор, как вы спросили, но, возможно, кто-то найдет это полезным.