class EM::FTPD::Memory::Authenticator

Constants

TOKEN_VALIDITY_PERIOD

Public Class Methods

getAuthenticatorByRealm(realm) click to toggle source
# File lib/em/ftpd/memory/authenticator.rb, line 32
def self.getAuthenticatorByRealm(realm)
  if @@realms[realm].nil?
    @@realms[realm] = Authenticator.new
  end
  @@realms[realm]
end
new() click to toggle source
# File lib/em/ftpd/memory/authenticator.rb, line 39
def initialize
  @users = Hash.new
  @used_tokens = Array.new
end

Public Instance Methods

<<(user) click to toggle source
# File lib/em/ftpd/memory/authenticator.rb, line 44
def <<(user)
  unless self.respond_to?("#{user.algo}_authentication".to_sym)
    raise InvalidPasswordAlgorithmError.new
  end
  user.algo = "#{user.algo}_authentication".to_sym
  @users[user.name] = user
end
authenticate(username, credential) click to toggle source
# File lib/em/ftpd/memory/authenticator.rb, line 56
def authenticate(username, credential)
  if @users[username].nil?
    raise NoSuchUserError.new
  end
  self.send(@users[username].algo, username, credential)
end
delete(user) click to toggle source
# File lib/em/ftpd/memory/authenticator.rb, line 52
def delete(user)
  @users.delete(user.name)
end
groups(username) click to toggle source
# File lib/em/ftpd/memory/authenticator.rb, line 109
def groups(username)
  if @users[username].nil?
    raise NoSuchUserError.new
  end
  @users[username].groups
end
none_authentication(username, credential) click to toggle source

this can be used for anonymous accounts

# File lib/em/ftpd/memory/authenticator.rb, line 64
def none_authentication(username, credential)
  return true
end
otp_authentication(username, credential) click to toggle source
# File lib/em/ftpd/memory/authenticator.rb, line 95
def otp_authentication(username, credential)
  passwords = @users[username].credential.split(/\n/)
  if passwords.empty?
    raise NoFurtherCredentialsAvailable.new
  end
  current_password = passwords.shift
  if credential == current_password
    @users[username].credential = passwords.join("\n")
    return true
  else
    raise InvalidCredentialError.new        
  end
end
plain_authentication(username, credential) click to toggle source
# File lib/em/ftpd/memory/authenticator.rb, line 68
def plain_authentication(username, credential)
  if @users[username].credential != credential
    raise InvalidCredentialError.new
  else
    return true
  end
end
timed_md5_authentication(username, credential) click to toggle source
# File lib/em/ftpd/memory/authenticator.rb, line 76
def timed_md5_authentication(username, credential)
  seed, time, hash = credential.split(/:/, 3)
  if hash.nil? or hash.length != 32
    raise MalformatedCredentialError.new
  end
  if (time.to_i - Time.now.to_i).abs > TOKEN_VALIDITY_PERIOD
    raise ExpiredCredentialError.new
  else
    if Digest::MD5.hexdigest("#{seed}:#{time}:#{@users[username].credential}") == hash
      unless check_and_set_token(time.to_i, seed)
        raise ReplayCredentialError.new
      end
      return true
    else
      raise InvalidCredentialError.new
    end
  end
end

Private Instance Methods

check_and_set_token(time, token) click to toggle source
# File lib/em/ftpd/memory/authenticator.rb, line 118
def check_and_set_token(time, token)
  # clean up stale tokens
  @used_tokens.reject! {|t| t.time < Time.now.to_i - TOKEN_VALIDITY_PERIOD}
  # check if token is replayed
  if @used_tokens.find {|t| t.time == time and t.token == token}
    return false
  end
  # add new token
  @used_tokens << TimedToken.new(time, token)
  true
end