38 lines
1.1 KiB
Julia
38 lines
1.1 KiB
Julia
import MD5
|
|
|
|
function isuser(n::AbstractString, users)::Union{Nothing,User}
|
|
m = findfirst(u -> u.name == n, users)
|
|
m === nothing ? nothing : users[m]
|
|
end
|
|
|
|
checksalt(u::User, s, t) = checksalt(u.password, s, t)
|
|
checksalt(p, s, t) = bytes2hex(MD5.md5(string(p, s))) == t
|
|
|
|
function passcomp(a, b)
|
|
## FIXME: Use Nettle.jl to compare passwords and prevent time attacks
|
|
sleep(Random.rand())
|
|
a == b
|
|
end
|
|
|
|
checkpass(u::User, p::AbstractString) = checkpass(u.password, p)
|
|
function checkpass(p1::AbstractString, p2::AbstractString)::Bool
|
|
startswith(p2, "enc:") && return passcomp(String(hex2bytes(split(p2, ":")[2])),p1)
|
|
passcomp(p1, p2)
|
|
end
|
|
|
|
function checkpass(name::AbstractString,
|
|
salt::AbstractString, token::AbstractString,
|
|
password::AbstractString)::Union{Nothing,User}
|
|
global users
|
|
isempty(name) && return nothing
|
|
user = isuser(name, users)
|
|
user == nothing && return nothing
|
|
|
|
if !isempty(salt)
|
|
checksalt(user, salt, token) && return user
|
|
elseif !isempty(password)
|
|
checkpass(user, password) && return user
|
|
end
|
|
nothing
|
|
end
|