v0.9.3 -- single class -- checking if this helps us with a couple of issues
This commit is contained in:
parent
4dc121eb76
commit
260a545369
103
plugin.rb
103
plugin.rb
@ -4,12 +4,100 @@
|
||||
|
||||
# name: discourse-md5_authentication
|
||||
# about: A plugin to authenticate users with MD5 passwords from legacy systems
|
||||
# version: 0.7
|
||||
# version: 0.9.3
|
||||
# authors: saint
|
||||
# url: https://gitea.federated.computer/saint/discourse-md5_authentication.git
|
||||
|
||||
# require 'digest'
|
||||
|
||||
after_initialize do
|
||||
class ::SessionController < ApplicationController
|
||||
ITOA64 = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
|
||||
|
||||
def to64(value, length)
|
||||
result = ""
|
||||
length.times do
|
||||
result << ITOA64[value & 0x3f]
|
||||
value >>= 6
|
||||
end
|
||||
result
|
||||
end
|
||||
|
||||
def gossamer_md5_crypt(password, legacy_hash)
|
||||
# Extract the salt from the legacy hash
|
||||
parts = legacy_hash.split('$')
|
||||
salt = parts[2]
|
||||
|
||||
# Limit the salt to 8 characters
|
||||
salt = salt[0, 8]
|
||||
|
||||
magic = "$GT$"
|
||||
Rails.logger.debug "MD5 magic: #{magic}"
|
||||
|
||||
ctx = Digest::MD5.new
|
||||
ctx.update(password)
|
||||
ctx.update(magic)
|
||||
ctx.update(salt)
|
||||
|
||||
final = Digest::MD5.new
|
||||
final.update(password)
|
||||
final.update(salt)
|
||||
final.update(password)
|
||||
final_digest = final.digest
|
||||
|
||||
password_length = password.length
|
||||
|
||||
while password_length > 0
|
||||
ctx.update(final_digest[0, [password_length, 16].min])
|
||||
password_length -= 16
|
||||
end
|
||||
|
||||
password_length = password.length
|
||||
while password_length > 0
|
||||
if password_length & 1 != 0
|
||||
ctx.update("\x00")
|
||||
else
|
||||
ctx.update(password[0, 1])
|
||||
end
|
||||
password_length >>= 1
|
||||
end
|
||||
|
||||
final_digest = ctx.digest
|
||||
Rails.logger.debug "MD5 final_digest: #{final_digest}"
|
||||
|
||||
1000.times do |i|
|
||||
ctx1 = Digest::MD5.new
|
||||
if i & 1 != 0
|
||||
ctx1.update(password)
|
||||
else
|
||||
ctx1.update(final_digest)
|
||||
end
|
||||
ctx1.update(salt) if i % 3 != 0
|
||||
ctx1.update(password) if i % 7 != 0
|
||||
if i & 1 != 0
|
||||
ctx1.update(final_digest)
|
||||
else
|
||||
ctx1.update(password)
|
||||
end
|
||||
final_digest = ctx1.digest
|
||||
end
|
||||
|
||||
result = ''
|
||||
result << to64((final_digest[0].ord << 16) | (final_digest[6].ord << 8) | final_digest[12].ord, 4)
|
||||
result << to64((final_digest[1].ord << 16) | (final_digest[7].ord << 8) | final_digest[13].ord, 4)
|
||||
result << to64((final_digest[2].ord << 16) | (final_digest[8].ord << 8) | final_digest[14].ord, 4)
|
||||
result << to64((final_digest[3].ord << 16) | (final_digest[9].ord << 8) | final_digest[15].ord, 4)
|
||||
result << to64((final_digest[4].ord << 16) | (final_digest[10].ord << 8) | final_digest[5].ord, 4)
|
||||
result << to64(final_digest[11].ord, 2)
|
||||
|
||||
"#{magic}#{salt}$#{result}"
|
||||
end
|
||||
|
||||
def verify_gossamer_password(password, legacy_hash)
|
||||
generated_hash = gossamer_md5_crypt(password, legacy_hash)
|
||||
generated_hash == legacy_hash
|
||||
end
|
||||
|
||||
def create
|
||||
params.require(:login)
|
||||
params.require(:password)
|
||||
@ -27,28 +115,26 @@ after_initialize do
|
||||
custom_password_md5 = user.custom_fields['custom_password_md5']
|
||||
|
||||
# Check for MD5 password in custom field
|
||||
Rails.logger.debug "Check for MD5 password in custom field"
|
||||
if custom_password_md5.present?
|
||||
|
||||
# MD5 password is present
|
||||
if Digest::MD5.hexdigest(password) == custom_password_md5
|
||||
Rails.logger.debug "MD5 password is present custom_password_md5: #{custom_password_md5} password: #{password}"
|
||||
|
||||
if verify_gossamer_password(password, custom_password_md5)
|
||||
# MD5 matches, so update the user's password to the new one and remove the custom field
|
||||
Rails.logger.debug "MD5 matches"
|
||||
user.password = password
|
||||
user.custom_fields['custom_password_md5'] = nil
|
||||
user.save!
|
||||
Rails.logger.debug "Updated MD5 password for user: #{user.id}"
|
||||
|
||||
else
|
||||
|
||||
# MD5 doesn't match, so we have a failed login attempt.
|
||||
Rails.logger.debug "Password incorrect for user: #{user.id}"
|
||||
Rails.logger.debug "MD5 Password incorrect for user: #{user.id}"
|
||||
invalid_credentials
|
||||
return
|
||||
end
|
||||
|
||||
# If their password is incorrect
|
||||
elsif !user.confirm_password?(password)
|
||||
|
||||
# There is no MD5 password and the password was incorrect.
|
||||
Rails.logger.debug "Password incorrect for user: #{user.id}"
|
||||
invalid_credentials
|
||||
@ -90,3 +176,4 @@ after_initialize do
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user