1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

version 1.1.16

o smtp.rb:  SMTP AUTH (contributed by Kazuhiro Izawa)


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@677 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
aamine 2000-04-25 09:23:21 +00:00
parent ee38413bf0
commit acbb1c9434
2 changed files with 56 additions and 7 deletions

View file

@ -15,7 +15,7 @@ require 'socket'
module Net module Net
Version = '1.1.15' Version = '1.1.16'
=begin =begin
@ -346,6 +346,7 @@ Object
SyntaxErrorCode = ErrorCode.mkchild( ProtoSyntaxError ) SyntaxErrorCode = ErrorCode.mkchild( ProtoSyntaxError )
FatalErrorCode = ErrorCode.mkchild( ProtoFatalError ) FatalErrorCode = ErrorCode.mkchild( ProtoFatalError )
ServerErrorCode = ErrorCode.mkchild( ProtoServerError ) ServerErrorCode = ErrorCode.mkchild( ProtoServerError )
AuthErrorCode = ErrorCode.mkchild( ProtoAuthError )
RetriableCode = ReplyCode.mkchild( ProtoRetriableError ) RetriableCode = ReplyCode.mkchild( ProtoRetriableError )
UnknownCode = ReplyCode.mkchild( ProtoUnknownError ) UnknownCode = ReplyCode.mkchild( ProtoUnknownError )

View file

@ -11,6 +11,7 @@ You can freely distribute/modify this library.
require 'net/protocol' require 'net/protocol'
require 'md5'
module Net module Net
@ -32,10 +33,13 @@ Net::Protocol
=== Methods === Methods
: start( helo_domain = ENV['HOSTNAME'] ) : start( helo_domain = ENV['HOSTNAME'] || ENV['HOST'], account = nil, password = nil, authtype = nil )
This method opens TCP connection and start SMTP. This method opens TCP connection and start SMTP.
If protocol had been started, do nothing and return false. If protocol had been started, do nothing and return false.
If account and password are given, is trying to get authentication
by using AUTH command. "authtype" is :plain (symbol) or :cram_md5.
: sendmail( mailsrc, from_addr, to_addrs ) : sendmail( mailsrc, from_addr, to_addrs )
This method sends 'mailsrc' as mail. SMTPSession read strings This method sends 'mailsrc' as mail. SMTPSession read strings
from 'mailsrc' by calling 'each' iterator, and convert them from 'mailsrc' by calling 'each' iterator, and convert them
@ -102,12 +106,15 @@ Net::Protocol
@command.data @command.data
end end
def do_start( helodom = ENV['HOSTNAME'] ) def do_start( helodom = nil,
user = nil, secret = nil, authtype = nil )
unless helodom then unless helodom then
raise ArgumentError, "cannot get hostname" helodom = ENV['HOSTNAME'] || ENV['HOST']
unless helodom then
raise ArgumentError, "cannot get hostname"
end
end end
@esmtp = false
begin begin
if @esmtp then if @esmtp then
@command.ehlo helodom @command.ehlo helodom
@ -122,6 +129,15 @@ Net::Protocol
raise raise
end end
end end
if user and secret then
begin
mid = 'auth_' + (authtype || 'cram_md5').to_s
@command.send mid, user, secret
rescue NameError
raise ArgumentError, "wrong auth type #{authtype.to_s}"
end
end
end end
end end
@ -154,6 +170,35 @@ Net::Protocol
end end
# "PLAIN" authentication [RFC2554]
def auth_plain( user, secret )
critical {
getok sprintf( 'AUTH PLAIN %s',
["\0#{user}\0#{secret}"].pack('m').chomp )
}
end
# "CRAM-MD5" authentication [RFC2195]
def auth_cram_md5( user, secret )
critical {
rep = getok( 'AUTH CRAM-MD5', ContinueCode )
challenge = rep.msg.split(' ')[1].unpack('m')[0]
secret = MD5.new( secret ).digest if secret.size > 64
isecret = secret + "\0" * (64 - secret.size)
osecret = isecret.dup
0.upto( 63 ) do |i|
isecret[i] ^= 0x36
osecret[i] ^= 0x5c
end
tmp = MD5.new( isecret + challenge ).digest
tmp = MD5.new( osecret + tmp ).hexdigest
getok [user + ' ' + tmp].pack('m').chomp
}
end
def mailfrom( fromaddr ) def mailfrom( fromaddr )
critical { critical {
getok sprintf( 'MAIL FROM:<%s>', fromaddr ) getok sprintf( 'MAIL FROM:<%s>', fromaddr )
@ -198,7 +243,6 @@ Net::Protocol
arr = read_reply arr = read_reply
stat = arr[0][0,3] stat = arr[0][0,3]
klass = UnknownCode
klass = case stat[0] klass = case stat[0]
when ?2 then SuccessCode when ?2 then SuccessCode
when ?3 then ContinueCode when ?3 then ContinueCode
@ -206,9 +250,11 @@ Net::Protocol
when ?5 then when ?5 then
case stat[1] case stat[1]
when ?0 then SyntaxErrorCode when ?0 then SyntaxErrorCode
when ?3 then AuthErrorCode
when ?5 then FatalErrorCode when ?5 then FatalErrorCode
end end
end end
klass ||= UnknownCode
Response.new( klass, stat, arr.join('') ) Response.new( klass, stat, arr.join('') )
end end
@ -217,7 +263,9 @@ Net::Protocol
def read_reply def read_reply
arr = [] arr = []
while (str = @socket.readline)[3] == ?- do # ex: "210-..." while true do
str = @socket.readline
break unless str[3] == ?- # ex: "210-..."
arr.push str arr.push str
end end
arr.push str arr.push str