[#35688] サブクラスのオブジェクト生成時に、スーパークラスの初期化を行うには ? — Onodera Takafumi <onodera-tak@...>

9 messages 2002/08/01

[#35772] Unsecure world writeable dirの警告 — "井上 浩一" <kyoui32@...>

=1B$B0f>e$G$9!#=1B(B

31 messages 2002/08/26
[#35774] Re: Unsecure world writeable dir の警告 — matz@... (Yukihiro Matsumoto) 2002/08/26

まつもと ゆきひろです

[#35775] Re: Unsecure world writeabledir の警告 — nobu.nakada@... 2002/08/26

なかだです。

[#35776] Re: Unsecure world writeabledir の警告 — matz@... (Yukihiro Matsumoto) 2002/08/26

まつもと ゆきひろです

[#35778] Re: Unsecure world writeabledir の警告 — nobu.nakada@... 2002/08/26

なかだです。

[#35779] Re: Unsecure world writeabledir の警告 — WATANABE Hirofumi <eban@...> 2002/08/26

わたなべです。

[#35780] Re: Unsecure world writeabledir の警告 — nobu.nakada@... 2002/08/26

なかだです。

[#35784] Re: Unsecure world writeabledir の警告 — "U.Nakamura" <usa@...> 2002/08/26

こんにちは、なかむら(う)です。

[#35854] Re: Unsecure world writeabledir の警告 — "Inoue" <rubyist@...1.117.ne.jp> 2002/09/04

井上です。

[#35865] Re: Unsecure world writeabledir の警告 — Koji Arai <JCA02266@...> 2002/09/05

新井です。

[#35866] Re: Unsecure world writeabledir の警告 — matz@... (Yukihiro Matsumoto) 2002/09/06

まつもと ゆきひろです

[#35789] multipart な CGI を速くしたい — Takashi Kanai <kanai@...4u.or.jp>

Windows上でRubyとMySQLを使ってショッピングサイトのようなものを作って

17 messages 2002/08/28

[ruby-list:35729] SMTP サーバクラス

From: とみたまさひろ <tommy@...>
Date: 2002-08-08 14:05:31 UTC
List: ruby-list #35729
とみたです。

ふと、SMTP サーバのようなものを作りたくなって、SMTPD クラスを作ってみ
ました。

こんな風にして使えます。どんなもんでしょう。興味ある人います?

・他のサーバに中継するだけの例

	require 'socket'
	require 'smtpd'
	require 'net/smtp'

	class MySMTPD < SMTPD
	  def comm_data(arg)
	    super do |msg|
	      Net::SMTP::start("smtpserver",25) do |s|
		s.send_mail msg, @sender, @recipients
	      end
	    end
	  end
	end

	sock = TCPServer::new(25)
	loop do
	  s = sock.accept
	  fork do
	    MySMTPD::new s, 'myhostname'
	  end
	  s.close
	end

・送信者や宛先で制限をする例

		〜〜
	class MySMTPD < SMTPD
	  def comm_rcpt(arg)
	    super do |rcpt|
	      if rcpt !~ /@my\.domain$/ then
		error "553 reject relay access"
	      end
	      if sender == "spammer@spam.domain" then
		error "553 you are spammer"
	      end
	    end
	  end
		〜〜

-- 
とみたまさひろ <tommy@tmtm.org>

Attachments (1)

smtpd.rb (2.64 KB, text/x-ruby)
# $Id$

class SMTPD

  def initialize(sock, domain)
    @sock = sock
    @domain = domain
    @sock.puts "220 #{@domain} service ready\r\n"
    @recipients = []
    while comm = @sock.gets do
      catch :next_comm do
	comm.sub!(/\r\n/,'')
	comm, arg = comm.split(/\s+/,2)
	case comm.upcase
	when 'HELO'; comm_helo arg
	when 'MAIL'; comm_mail arg
	when 'RCPT'; comm_rcpt arg
	when 'DATA'; comm_data arg
	when 'RSET'; comm_rset arg
	when 'NOOP'; comm_noop arg
	when 'QUIT'; comm_quit arg
	else
	  error '502 Error: command not implemented'
	end
      end
    end
  end

  def comm_helo(arg)
    args = arg.split
    if args.length != 1 then
      error '501 Syntax: HELO hostname'
    end
    yield args[0] if block_given?
    @helo_name = args[0]
    reply "250 #{@domain}"
  end

  def comm_mail(arg)
    if @sender != nil then
      error '503 Error: nested MAIL command'
    end
    if arg !~ /^FROM:/i then
      error '501 Syntax: MAIL FROM: <address>'
    end
    sender = parse_addr $'
    if sender == nil then
      error '501 Syntax: MAIL FROM: <address>'
    end
    yield sender if block_given?
    @sender = sender
    reply '250 Ok'
  end

  def comm_rcpt(arg)
    if @sender == nil then
      error '503 Error: need MAIL command'
    end
    if arg !~ /^TO:/i then
      error '501 Syntax: RCPT TO: <address>'
    end
    rcpt = parse_addr $'
    if rcpt == nil then
      error '501 Syntax: RCPT TO: <address>'
    end
    yield rcpt if block_given?
    @recipients << rcpt
    reply '250 Ok'
  end

  def comm_data(arg)
    if @recipients.size == 0 then
      error '503 Error: need RCPT command'
    end
    if arg != nil then
      error '501 Syntax: DATA'
    end
    reply '354 End data with <CR><LF>.<CR><LF>'
    msg = ''
    while l = @sock.gets do
      if l == ".\r\n" then break end
      msg << l
      if $message_size_limit and msg.length > $message_size_limit then
	error '552 Error: message too large'
      end
    end
    yield msg if block_given?
    reply '250 Ok'
  end

  def comm_rset(arg)
    if arg != nil then
      error '501 Syntax: RSET'
    end
    @sender = nil
    @recipients = []
    reply '250 Ok'
  end

  def comm_noop(arg)
    if arg != nil then
      error '501 Syntax: NOOP'
    end
    reply '250 Ok'
  end

  def comm_quit(arg)
    if arg != nil then
      error '501 Syntax: QUIT'
    end
    reply '221 Bye'
    exit
  end

  def parse_addr(str)
    str = str.sub(/^\s+/,'').sub(/\s+$/,'')
    if str =~ /^<(.*)>$/ then
      return $1
    end
    if str =~ /\s/ then
      return nil
    end
    str
  end

  def reply(msg)
    @sock.puts msg+"\r\n"
  end

  def error(msg)
    sleep 5
    @sock.puts msg+"\r\n"
    throw :next_comm
  end

end

In This Thread

Prev Next