@@ -602,46 +602,57 @@ def starttls(options = {}, verify = true)
602
602
end
603
603
end
604
604
605
+ # :call-seq:
606
+ # authenticate(mechanism, ...) -> ok_resp
607
+ # authenticate(mech, *creds, **props) {|prop, auth| val } -> ok_resp
608
+ # authenticate(mechanism, authnid, credentials, authzid=nil) -> ok_resp
609
+ # authenticate(mechanism, **properties) -> ok_resp
610
+ # authenticate(mechanism) {|propname, authctx| prop_value } -> ok_resp
611
+ #
605
612
# Sends an {AUTHENTICATE command [IMAP4rev1 §6.2.2]}[https://www.rfc-editor.org/rfc/rfc3501#section-6.2.2]
606
613
# to authenticate the client.
607
614
#
608
- # The +auth_type+ parameter is a string that
609
- # represents the authentication mechanism to be used. Currently Net::IMAP
610
- # supports the following mechanisms:
615
+ # +mechanism+ is the name of the \SASL authentication mechanism to be used.
616
+ # All other arguments are forwarded to the authenticator for the requested
617
+ # mechanism. The listed call signatures are suggestions. <em>The
618
+ # documentation for each individual mechanism must be consulted for its
619
+ # specific parameters.</em>
611
620
#
612
- # PLAIN:: Login using cleartext user and password. Secure with TLS.
613
- # See PlainAuthenticator.
614
- # CRAM-MD5:: DEPRECATED: Use PLAIN (or DIGEST-MD5) with TLS.
615
- # DIGEST-MD5:: DEPRECATED by RFC6331. Must be secured using TLS.
616
- # See DigestMD5Authenticator.
617
- # LOGIN:: DEPRECATED: Use PLAIN.
618
- #
619
- # Most mechanisms require two args: authentication identity (e.g. username)
620
- # and credentials (e.g. a password). But each mechanism requires and allows
621
- # different arguments; please consult the documentation for the specific
622
- # mechanisms you are using. <em>Several obsolete mechanisms are available
623
- # for backwards compatibility. Using deprecated mechanisms will issue
624
- # warnings.</em>
625
- #
626
- # Servers do not support all mechanisms and clients must not attempt to use
627
- # a mechanism unless "AUTH=#{mechanism}" is listed as a #capability.
628
- # Clients must not attempt to authenticate or #login when +LOGINDISABLED+ is
629
- # listed with the capabilities. Server capabilities, especially auth
630
- # mechanisms, do change after calling #starttls so they need to be checked
631
- # again.
621
+ # <em>In general</em>, all of a mechanism's properties can be set by keyword
622
+ # argument or callback, but mechanisms may allow common properties to be set
623
+ # with positional arguments. See SASL::Authenticator@Properties and
624
+ # SASL::Authenticator@Callbacks for more details.
632
625
#
633
- # For example:
626
+ # An exception Net::IMAP::NoResponseError is raised if authentication fails.
634
627
#
635
- # imap.authenticate('PLAIN', user, password)
628
+ # Related: #login, #starttls
636
629
#
637
- # A Net::IMAP::NoResponseError is raised if authentication fails.
630
+ # ==== Supported SASL Mechanisms
638
631
#
639
- # See Net::IMAP::Authenticators for more information on plugging in your
640
- # own authenticator.
632
+ # Net::IMAP currently supports the following mechanisms:
641
633
#
642
- # Related: #login, #starttls
634
+ # PLAIN:: Login using clear-text user and password. Secure with TLS.
635
+ # See PlainAuthenticator.
636
+ # XOAUTH2:: Login using a username and OAuth2 access token. Non-standard
637
+ # and obsoleted by +OAUTHBEARER+, but still widely supported.
638
+ # See XOauth2Authenticator.
643
639
#
644
- # ==== Capabilities
640
+ # See Net::IMAP::Authenticators for information on plugging in
641
+ # authenticators for other mechanisms. See the {SASL mechanism
642
+ # registry}[https://www.iana.org/assignments/sasl-mechanisms/sasl-mechanisms.xhtml]
643
+ # for information on these and other SASL mechanisms.
644
+ #
645
+ # ===== Deprecated mechanisms
646
+ #
647
+ # <em>Obsolete mechanisms are available for backwards compatibility.
648
+ # Using a deprecated mechanism will print a warning.</em>
649
+ #
650
+ # DIGEST-MD5:: DEPRECATED by RFC6331. Must be secured using TLS.
651
+ # See DigestMD5Authenticator.
652
+ # CRAM-MD5:: DEPRECATED: Use +PLAIN+ (or SCRAM-*)
653
+ # LOGIN:: DEPRECATED: Use +PLAIN+ with TLS.
654
+ #
655
+ # ===== Capabilities
645
656
#
646
657
# Clients MUST NOT attempt to #authenticate or #login when +LOGINDISABLED+
647
658
# is listed with the capabilities.
@@ -654,9 +665,36 @@ def starttls(options = {}, verify = true)
654
665
# The TaggedResponse to #authenticate may include updated capabilities in
655
666
# its ResponseCode.
656
667
#
657
- def authenticate ( auth_type , *args )
658
- authenticator = self . class . authenticator ( auth_type , *args )
659
- send_command ( "AUTHENTICATE" , auth_type ) do |resp |
668
+ # ===== Example
669
+ # Most mechanisms ignore unhandled keyword arguments, so the same config can
670
+ # be used for multiple authenticator types:
671
+ # password = nil # saved locally, so we don't ask more than once
672
+ # accesstok = nil
673
+ # creds = {
674
+ # authcid: username,
675
+ # password: proc { password ||= ui.prompt_for_password },
676
+ # oauth2_token: proc { accesstok ||= kms.lookup(username, :access_token).refreshed },
677
+ # }
678
+ # capa = imap.capability
679
+ # if capa.include? "LOGINDISABLED"
680
+ # raise "the server has disabled login"
681
+ # elsif capa.include? "AUTH=OAUTHBEARER"
682
+ # imap.authenticate "OAUTHBEARER", **creds # authcid, oauth2_token
683
+ # elsif capa.include? "AUTH=XOAUTH2"
684
+ # imap.authenticate "XOAUTH2", **creds # authcid, oauth2_token
685
+ # elsif capa.include? "AUTH=SCRAM-SHA-256"
686
+ # imap.authenticate "SCRAM-SHA-256", **creds # authcid, password
687
+ # elsif capa.include? "AUTH=PLAIN"
688
+ # imap.authenticate "PLAIN", **creds # authcid, password
689
+ # elsif capa.include? "AUTH=DIGEST-MD5"
690
+ # imap.authenticate "DIGEST-MD5", **creds # authcid, password
691
+ # else
692
+ # raise "no acceptable authentication mechanism is available"
693
+ # end
694
+ #
695
+ def authenticate ( mechanism , *args , **props , &cb )
696
+ authenticator = self . class . authenticator ( mechanism , *args , **props , &cb )
697
+ send_command ( "AUTHENTICATE" , mechanism ) do |resp |
660
698
if resp . instance_of? ( ContinuationRequest )
661
699
data = authenticator . process ( resp . data . text . unpack ( "m" ) [ 0 ] )
662
700
s = [ data ] . pack ( "m0" )
0 commit comments