|
16 | 16 |
|
17 | 17 | require "socket"
|
18 | 18 | require "monitor"
|
19 |
| -require "digest/md5" |
20 |
| -require "strscan" |
21 | 19 | require 'net/protocol'
|
22 | 20 | begin
|
23 | 21 | require "openssl"
|
@@ -292,31 +290,6 @@ def self.max_flag_count=(count)
|
292 | 290 | @@max_flag_count = count
|
293 | 291 | end
|
294 | 292 |
|
295 |
| - # Adds an authenticator for Net::IMAP#authenticate. +auth_type+ |
296 |
| - # is the type of authentication this authenticator supports |
297 |
| - # (for instance, "LOGIN"). The +authenticator+ is an object |
298 |
| - # which defines a process() method to handle authentication with |
299 |
| - # the server. See Net::IMAP::LoginAuthenticator, |
300 |
| - # Net::IMAP::CramMD5Authenticator, and Net::IMAP::DigestMD5Authenticator |
301 |
| - # for examples. |
302 |
| - # |
303 |
| - # |
304 |
| - # If +auth_type+ refers to an existing authenticator, it will be |
305 |
| - # replaced by the new one. |
306 |
| - def self.add_authenticator(auth_type, authenticator) |
307 |
| - @@authenticators[auth_type] = authenticator |
308 |
| - end |
309 |
| - |
310 |
| - # Builds an authenticator for Net::IMAP#authenticate. |
311 |
| - def self.authenticator(auth_type, *args) |
312 |
| - auth_type = auth_type.upcase |
313 |
| - unless @@authenticators.has_key?(auth_type) |
314 |
| - raise ArgumentError, |
315 |
| - format('unknown auth type - "%s"', auth_type) |
316 |
| - end |
317 |
| - @@authenticators[auth_type].new(*args) |
318 |
| - end |
319 |
| - |
320 | 293 | # The default port for IMAP connections, port 143
|
321 | 294 | def self.default_port
|
322 | 295 | return PORT
|
@@ -1124,7 +1097,6 @@ def self.format_datetime(time)
|
1124 | 1097 | SSL_PORT = 993 # :nodoc:
|
1125 | 1098 |
|
1126 | 1099 | @@debug = false
|
1127 |
| - @@authenticators = {} |
1128 | 1100 | @@max_flag_count = 10000
|
1129 | 1101 |
|
1130 | 1102 | # :call-seq:
|
@@ -3901,182 +3873,6 @@ def parse_error(fmt, *args)
|
3901 | 3873 | end
|
3902 | 3874 | end
|
3903 | 3875 |
|
3904 |
| - # Authenticator for the "LOGIN" authentication type. See |
3905 |
| - # #authenticate(). |
3906 |
| - class LoginAuthenticator |
3907 |
| - def process(data) |
3908 |
| - case @state |
3909 |
| - when STATE_USER |
3910 |
| - @state = STATE_PASSWORD |
3911 |
| - return @user |
3912 |
| - when STATE_PASSWORD |
3913 |
| - return @password |
3914 |
| - end |
3915 |
| - end |
3916 |
| - |
3917 |
| - private |
3918 |
| - |
3919 |
| - STATE_USER = :USER |
3920 |
| - STATE_PASSWORD = :PASSWORD |
3921 |
| - |
3922 |
| - def initialize(user, password) |
3923 |
| - @user = user |
3924 |
| - @password = password |
3925 |
| - @state = STATE_USER |
3926 |
| - end |
3927 |
| - end |
3928 |
| - add_authenticator "LOGIN", LoginAuthenticator |
3929 |
| - |
3930 |
| - # Authenticator for the "PLAIN" authentication type. See |
3931 |
| - # #authenticate(). |
3932 |
| - class PlainAuthenticator |
3933 |
| - def process(data) |
3934 |
| - return "\0#{@user}\0#{@password}" |
3935 |
| - end |
3936 |
| - |
3937 |
| - private |
3938 |
| - |
3939 |
| - def initialize(user, password) |
3940 |
| - @user = user |
3941 |
| - @password = password |
3942 |
| - end |
3943 |
| - end |
3944 |
| - add_authenticator "PLAIN", PlainAuthenticator |
3945 |
| - |
3946 |
| - # Authenticator for the "CRAM-MD5" authentication type. See |
3947 |
| - # #authenticate(). |
3948 |
| - class CramMD5Authenticator |
3949 |
| - def process(challenge) |
3950 |
| - digest = hmac_md5(challenge, @password) |
3951 |
| - return @user + " " + digest |
3952 |
| - end |
3953 |
| - |
3954 |
| - private |
3955 |
| - |
3956 |
| - def initialize(user, password) |
3957 |
| - @user = user |
3958 |
| - @password = password |
3959 |
| - end |
3960 |
| - |
3961 |
| - def hmac_md5(text, key) |
3962 |
| - if key.length > 64 |
3963 |
| - key = Digest::MD5.digest(key) |
3964 |
| - end |
3965 |
| - |
3966 |
| - k_ipad = key + "\0" * (64 - key.length) |
3967 |
| - k_opad = key + "\0" * (64 - key.length) |
3968 |
| - for i in 0..63 |
3969 |
| - k_ipad[i] = (k_ipad[i].ord ^ 0x36).chr |
3970 |
| - k_opad[i] = (k_opad[i].ord ^ 0x5c).chr |
3971 |
| - end |
3972 |
| - |
3973 |
| - digest = Digest::MD5.digest(k_ipad + text) |
3974 |
| - |
3975 |
| - return Digest::MD5.hexdigest(k_opad + digest) |
3976 |
| - end |
3977 |
| - end |
3978 |
| - add_authenticator "CRAM-MD5", CramMD5Authenticator |
3979 |
| - |
3980 |
| - # Authenticator for the "DIGEST-MD5" authentication type. See |
3981 |
| - # #authenticate(). |
3982 |
| - class DigestMD5Authenticator |
3983 |
| - def process(challenge) |
3984 |
| - case @stage |
3985 |
| - when STAGE_ONE |
3986 |
| - @stage = STAGE_TWO |
3987 |
| - sparams = {} |
3988 |
| - c = StringScanner.new(challenge) |
3989 |
| - while c.scan(/(?:\s*,)?\s*(\w+)=("(?:[^\\"]+|\\.)*"|[^,]+)\s*/) |
3990 |
| - k, v = c[1], c[2] |
3991 |
| - if v =~ /^"(.*)"$/ |
3992 |
| - v = $1 |
3993 |
| - if v =~ /,/ |
3994 |
| - v = v.split(',') |
3995 |
| - end |
3996 |
| - end |
3997 |
| - sparams[k] = v |
3998 |
| - end |
3999 |
| - |
4000 |
| - raise DataFormatError, "Bad Challenge: '#{challenge}'" unless c.rest.size == 0 |
4001 |
| - raise Error, "Server does not support auth (qop = #{sparams['qop'].join(',')})" unless sparams['qop'].include?("auth") |
4002 |
| - |
4003 |
| - response = { |
4004 |
| - :nonce => sparams['nonce'], |
4005 |
| - :username => @user, |
4006 |
| - :realm => sparams['realm'], |
4007 |
| - :cnonce => Digest::MD5.hexdigest("%.15f:%.15f:%d" % [Time.now.to_f, rand, Process.pid.to_s]), |
4008 |
| - :'digest-uri' => 'imap/' + sparams['realm'], |
4009 |
| - :qop => 'auth', |
4010 |
| - :maxbuf => 65535, |
4011 |
| - :nc => "%08d" % nc(sparams['nonce']), |
4012 |
| - :charset => sparams['charset'], |
4013 |
| - } |
4014 |
| - |
4015 |
| - response[:authzid] = @authname unless @authname.nil? |
4016 |
| - |
4017 |
| - # now, the real thing |
4018 |
| - a0 = Digest::MD5.digest( [ response.values_at(:username, :realm), @password ].join(':') ) |
4019 |
| - |
4020 |
| - a1 = [ a0, response.values_at(:nonce,:cnonce) ].join(':') |
4021 |
| - a1 << ':' + response[:authzid] unless response[:authzid].nil? |
4022 |
| - |
4023 |
| - a2 = "AUTHENTICATE:" + response[:'digest-uri'] |
4024 |
| - a2 << ":00000000000000000000000000000000" if response[:qop] and response[:qop] =~ /^auth-(?:conf|int)$/ |
4025 |
| - |
4026 |
| - response[:response] = Digest::MD5.hexdigest( |
4027 |
| - [ |
4028 |
| - Digest::MD5.hexdigest(a1), |
4029 |
| - response.values_at(:nonce, :nc, :cnonce, :qop), |
4030 |
| - Digest::MD5.hexdigest(a2) |
4031 |
| - ].join(':') |
4032 |
| - ) |
4033 |
| - |
4034 |
| - return response.keys.map {|key| qdval(key.to_s, response[key]) }.join(',') |
4035 |
| - when STAGE_TWO |
4036 |
| - @stage = nil |
4037 |
| - # if at the second stage, return an empty string |
4038 |
| - if challenge =~ /rspauth=/ |
4039 |
| - return '' |
4040 |
| - else |
4041 |
| - raise ResponseParseError, challenge |
4042 |
| - end |
4043 |
| - else |
4044 |
| - raise ResponseParseError, challenge |
4045 |
| - end |
4046 |
| - end |
4047 |
| - |
4048 |
| - def initialize(user, password, authname = nil) |
4049 |
| - @user, @password, @authname = user, password, authname |
4050 |
| - @nc, @stage = {}, STAGE_ONE |
4051 |
| - end |
4052 |
| - |
4053 |
| - private |
4054 |
| - |
4055 |
| - STAGE_ONE = :stage_one |
4056 |
| - STAGE_TWO = :stage_two |
4057 |
| - |
4058 |
| - def nc(nonce) |
4059 |
| - if @nc.has_key? nonce |
4060 |
| - @nc[nonce] = @nc[nonce] + 1 |
4061 |
| - else |
4062 |
| - @nc[nonce] = 1 |
4063 |
| - end |
4064 |
| - return @nc[nonce] |
4065 |
| - end |
4066 |
| - |
4067 |
| - # some responses need quoting |
4068 |
| - def qdval(k, v) |
4069 |
| - return if k.nil? or v.nil? |
4070 |
| - if %w"username authzid realm nonce cnonce digest-uri qop".include? k |
4071 |
| - v.gsub!(/([\\"])/, "\\\1") |
4072 |
| - return '%s="%s"' % [k, v] |
4073 |
| - else |
4074 |
| - return '%s=%s' % [k, v] |
4075 |
| - end |
4076 |
| - end |
4077 |
| - end |
4078 |
| - add_authenticator "DIGEST-MD5", DigestMD5Authenticator |
4079 |
| - |
4080 | 3876 | # Superclass of IMAP errors.
|
4081 | 3877 | class Error < StandardError
|
4082 | 3878 | end
|
@@ -4130,3 +3926,5 @@ class FlagCountError < Error
|
4130 | 3926 | end
|
4131 | 3927 | end
|
4132 | 3928 | end
|
| 3929 | + |
| 3930 | +require_relative "imap/authenticators" |
0 commit comments