-
Notifications
You must be signed in to change notification settings - Fork 28
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Move each authenticator to its own file
Also updates rdoc with SASL specifications and deprecations. Of these four, only `PLAIN` isn't deprecated! +@@Authenticators+ was changed to a class instance var +@Authenticators+. No one should have been using the class variable directly, so that should be fine.
- Loading branch information
Showing
6 changed files
with
257 additions
and
204 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
# frozen_string_literal: true | ||
|
||
# Registry for SASL authenticators used by Net::IMAP. | ||
module Net::IMAP::Authenticators | ||
|
||
# Adds an authenticator for Net::IMAP#authenticate. +auth_type+ is the | ||
# {SASL mechanism}[https://www.iana.org/assignments/sasl-mechanisms/sasl-mechanisms.xhtml] | ||
# supported by +authenticator+ (for instance, "+LOGIN+"). The +authenticator+ | ||
# is an object which defines a +#process+ method to handle authentication with | ||
# the server. See Net::IMAP::LoginAuthenticator, | ||
# Net::IMAP::CramMD5Authenticator, and Net::IMAP::DigestMD5Authenticator for | ||
# examples. | ||
# | ||
# If +auth_type+ refers to an existing authenticator, it will be | ||
# replaced by the new one. | ||
def add_authenticator(auth_type, authenticator) | ||
authenticators[auth_type] = authenticator | ||
end | ||
|
||
# Builds an authenticator for Net::IMAP#authenticate. +args+ will be passed | ||
# directly to the chosen authenticator's +#initialize+. | ||
def authenticator(auth_type, *args) | ||
auth_type = auth_type.upcase | ||
unless authenticators.has_key?(auth_type) | ||
raise ArgumentError, | ||
format('unknown auth type - "%s"', auth_type) | ||
end | ||
authenticators[auth_type].new(*args) | ||
end | ||
|
||
private | ||
|
||
def authenticators | ||
@authenticators ||= {} | ||
end | ||
|
||
end | ||
|
||
Net::IMAP.extend Net::IMAP::Authenticators | ||
|
||
require_relative "authenticators/login" | ||
require_relative "authenticators/plain" | ||
require_relative "authenticators/cram_md5" | ||
require_relative "authenticators/digest_md5" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
# frozen_string_literal: true | ||
|
||
require "digest/md5" | ||
|
||
# Authenticator for the "+CRAM-MD5+" SASL mechanism. See | ||
# Net::IMAP#authenticate. | ||
# | ||
# == Deprecated | ||
# | ||
# +CRAM-MD5+ should be considered obsolete and insecure. It is included for | ||
# backward compatibility with historic servers. | ||
# {draft-ietf-sasl-crammd5-to-historic}[https://tools.ietf.org/html/draft-ietf-sasl-crammd5-to-historic-00.html] | ||
# recommends using +SCRAM-*+ or +PLAIN+ protected by TLS instead. Additionally, | ||
# RFC8314[https://tools.ietf.org/html/rfc8314] discourage the use of cleartext | ||
# and recommends TLS version 1.2 or greater be used for all traffic. | ||
class Net::IMAP::CramMD5Authenticator | ||
def process(challenge) | ||
digest = hmac_md5(challenge, @password) | ||
return @user + " " + digest | ||
end | ||
|
||
private | ||
|
||
def initialize(user, password) | ||
@user = user | ||
@password = password | ||
end | ||
|
||
def hmac_md5(text, key) | ||
if key.length > 64 | ||
key = Digest::MD5.digest(key) | ||
end | ||
|
||
k_ipad = key + "\0" * (64 - key.length) | ||
k_opad = key + "\0" * (64 - key.length) | ||
for i in 0..63 | ||
k_ipad[i] = (k_ipad[i].ord ^ 0x36).chr | ||
k_opad[i] = (k_opad[i].ord ^ 0x5c).chr | ||
end | ||
|
||
digest = Digest::MD5.digest(k_ipad + text) | ||
|
||
return Digest::MD5.hexdigest(k_opad + digest) | ||
end | ||
|
||
Net::IMAP.add_authenticator "PLAIN", self | ||
end |
Oops, something went wrong.