class AuthD::Request IPC::JSON.message AskPasswordRecovery, 3 do property login : String? = nil property email : String? = nil def initialize(@login = nil, @email = nil) end def handle(authd : AuthD::Service, fd : Int32) if @login.nil? && @email.nil? return Response::ErrorUserNotFound.new end user = if l = @login authd.user? l elsif mail = @email authd.users_per_email.get? Base64.encode(mail).chomp else nil end # This is a way for an attacker to know what are the valid logins. # Not sure I care enough to fix this. return Response::ErrorUserNotFound.new if user.nil? # Create a new random key for password renewal. user.password_renew_key = UUID.random.to_s authd.users_per_uid.update user.uid.to_s, user # TODO: this is debug information. Should be removed once tested. # Once the user is created and stored, we try to contact him if authd.configuration.print_password_recovery_parameters pp! user.login, user.contact.email.not_nil!, user.password_renew_key.not_nil! end u_login = user.login u_email = user.contact.email.not_nil! u_token = user.password_renew_key.not_nil! send_recovery_token authd, u_login, u_email, u_token Response::PasswordRecoverySent.new end end AuthD.requests << AskPasswordRecovery IPC::JSON.message PasswordRecovery, 4 do property user : UserID property password_renew_key : String property new_password : String def initialize(@user, @password_renew_key, @new_password) end def handle(authd : AuthD::Service, fd : Int32) user = authd.user? @user # This is a way for an attacker to know what are the valid logins. # Not sure I care enough to fix this. return Response::ErrorUserNotFound.new if user.nil? if user.password_renew_key == @password_renew_key user.password_hash = authd.hash_password @new_password else return Response::ErrorInvalidRenewKey.new end user.password_renew_key = nil authd.users_per_uid.update user.uid.to_s, user Response::PasswordRecovered.new end end AuthD.requests << PasswordRecovery end