Implemented protocol parts:

* Added exceptions for all protocol errors (4xx, 5xx).
 * Implement commands: help, quit, adda, dela, updt, list.
 * Added Backend#prot_msg_body, let Backend#prot_msg do the outputting.
 * Added Server::Backend and Server::Account (empty stub implementations).


git-svn-id: svn+ssh://svn.luon.net/svn/ildus/trunk@4 65a33f86-aa00-0410-91be-cd1bf5efb309
This commit is contained in:
paul 2005-09-27 14:28:59 +00:00
parent 50062f3b9f
commit 55bf169b2c
4 changed files with 219 additions and 24 deletions

View File

@ -10,8 +10,6 @@
require 'gserver'
require 'yaml'
require 'ildus/server/handler'
module Ildus
class Server < GServer
@ -72,3 +70,8 @@ module Ildus
end # class Server
end # module Ildus
# Require the rest of the server library.
require 'ildus/server/account'
require 'ildus/server/backend'
require 'ildus/server/handler'

View File

@ -0,0 +1,53 @@
# = ildus/server/account - server account library
#
# Copyright (C) 2005 Paul van Tilburg <paul@luon.net>
#
# Ildus is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation; either version 2 of the License, or (at your option)
# any later version.
require 'yaml'
module Ildus
class Server
class Account
attr_reader :user, :pass
def self.register_account(user, pass)
end
def self.unregister_account(user, pass)
end
def initialize
@user = nil
@pass = nil
@auth = false
end
def user=(username)
raise Handler::AlreadyAuthError if @auth
@user = username
end
def pass=(password)
raise Handler::AlreadyAuthError if @auth
@pass = password
## STUB
@auth = rand(2).zero?
##
end
def authenticated?
@auth
end
end # class Account
end # class Server
end # module Ildus

View File

@ -0,0 +1,47 @@
# = ildus/server/backend - generic server backend library
#
# Copyright (C) 2005 Paul van Tilburg <paul@luon.net>
#
# Ildus is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation; either version 2 of the License, or (at your option)
# any later version.
require 'singleton'
module Ildus
class Server
class Backend
include Singleton
def hostnames_of(user)
raise Handler::NotImplementedError
end
def add_hostname(user)
raise Handler::NotImplementedError
end
def remove_hostname(user)
raise Handler::NotImplementedError
end
def update_hostname(user, host, addr)
raise Handler::NotImplementedError
end
def add_alias(user, new_alias, host)
raise Handler::NotImplementedError
end
def remove_alias(user, old_alias, host)
raise Handler::NotImplementedError
end
end # class Backend
end # class Server
end # module Ildus

View File

@ -13,12 +13,20 @@ module Ildus
class Handler
class ProtocolException < StandardError; end
class CmdUnknownError < ProtocolException; end
class ArgsSyntaxError < ProtocolException; end
class NotImplementedError < ProtocolException; end
class AlreadyAuthError < ProtocolException; end
class TooManyUnknownError < ProtocolException; end
class ProtocolException < StandardError; end
class HandlerExit < ProtocolException; end # 221
class HostNotFoundError < ProtocolException; end # 425
class RecordNotFoundError < ProtocolException; end # 426
class CmdUnknownError < ProtocolException; end # 500
class ArgsSyntaxError < ProtocolException; end # 501
class NotImplementedError < ProtocolException; end # 502
class TooManyUnknownError < ProtocolException; end # 503
class AlreadyAuthError < ProtocolException; end # 504
class BackendError < ProtocolException; end # 506
class NotAuthError < ProtocolException; end # 530
MaxCmdErrs = 3
@ -49,35 +57,46 @@ module Ildus
530 => "Not authenticated!"
}
def intialize(server, io)
@server = server
@io = io
def initialize(server, io)
@server = server
@io = io
@account = Account.new
@backend = Backend.instance
end
def handle_client
io.puts prot_msg(220, "localhost", Program, Version, Time.now.to_s)
prot_msg 220, "localhost", Program, Version, Time.now.to_s
cmd_errs = 0
io.each_line do |line|
@io.each_line do |line|
begin
cmd, *args = line.split /\s+/
handle_command(io, cmd, args)
cmd, *args = line.split
handle_command(cmd, args)
rescue HandlerExit
prot_msg 221, "localhost"
break
rescue CmdUnknownError # 500
raise TooManyUnknownError if cmd_errs > MaxCmdErrs
io.puts prot_msg(500, cmd)
cmd_errs = cmd_errs + 1
prot_msg 500, cmd
rescue ArgsSyntaxError # 501
io.puts prot_msg(501)
raise TooManyUnknownError if cmd_errs > MaxCmdErrs
cmd_errs = cmd_errs + 1
prot_msg 501
rescue NotImplementedError # 502
io.puts prot_msg(502)
prot_msg 502
rescue AlreadyAuthError # 504
io.puts prot_msg(504)
prot_msg 504
rescue BackendError => msg # 506
prot_msg 506, msg
rescue NotAuthError # 530
prot_msg 530
end
end
rescue TooManyUnknownError # 503
io.puts prot_msg(503)
prot_msg 503
rescue RuntimeError => msg # 505
io.puts prot_msg(505, msg)
prot_msg 505, msg
raise
end
@ -85,16 +104,89 @@ module Ildus
private
#########
def handle_command(io, cmd, args)
def handle_command(cmd, args)
method_name = cmd.downcase + "_cmd"
meth = method(method_name)
meth.call(*args)
rescue NameError
rescue ArgumentError
raise ArgsSyntaxError
rescue NameError => e
$stderr.puts "#{e.class}: #{e}"
$stderr.puts e.backtrace
raise CmdUnknownError
end
def prot_msg(code, *args)
code.to_s << " " << ProtocolCodeMapping[code] % args
msg = code.to_s + " " + (ProtocolCodeMapping[code] % args)
@io.puts msg
end
def prot_msg_with_body(code, body, *args)
@io.print code.to_s, "-", body
prot_msg(code, *args)
end
##################
# Commands methods
def user_cmd(username)
@account.user = username
prot_msg 331
end
def pass_cmd(password)
@account.pass = password
if @account.authenticated?
prot_msg 230, @account.user
else
raise NotAuthError
end
end
def updt_cmd(hostname, addr)
raise NotAuthError unless @account.authenticated?
@backend.update_hostname(@account.user, hostname, addr)
rescue HostNotFoundError
prot_msg 425, hostname
rescue RecordNotFoundError
prot_msg 426, type, hostname
else
prot_msg 240, hostname, addr
end
def adda_cmd(hostname, new_alias)
raise NotImplementedError
end
def dela_cmd(hostname, old_alias)
raise NotImplementedError
end
def list_cmd
raise NotAuthError unless @account.authenticated?
user = @account.user
#list = @backend.hostnames_of(user)
prot_msg_with_body 215,
"Listing of hosts (and aliases) for user #{user}\n"
end
def help_cmd
prot_msg_with_body 214,
<<-EOT, "ildus-admin@localhost"
The following commands are recognized:
HELP\t\t\tshow this help
QUIT\t\t\tclose connection
USER <user>\t\tsupply username
PASS <passwd>\t\tgive password
LIST\t\t\tlist hostnames (and aliases)\t[auth. required]
UPDT <host> <ip>\tupdate ip for host\t\t[auth. required]
ADDA <host> <alias>\tadd alias to host\t\t[auth. required]
DELA <host> <alias>\tdelete alias from host\t\t[auth. required]
EOT
end
def quit_cmd
raise HandlerExit
end
end # class Handler