@@ -602,46 +602,59 @@ 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:
611
- #
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.
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>
632
620
#
633
- # For example:
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.
634
625
#
635
- # imap.authenticate('PLAIN', user, password)
626
+ # An exception Net::IMAP::NoResponseError is raised if authentication fails.
636
627
#
637
- # A Net::IMAP::NoResponseError is raised if authentication fails.
628
+ # Related: #login, #starttls
638
629
#
639
- # See Net::IMAP::Authenticators for more information on plugging in your
640
- # own authenticator.
630
+ # ==== Supported SASL Mechanisms
641
631
#
642
- # Related: #login, #starttls
632
+ # +PLAIN+:: See PlainAuthenticator.
633
+ # Login using clear-text username and password.
643
634
#
644
- # ==== Capabilities
635
+ # +XOAUTH2+:: See XOauth2Authenticator.
636
+ # Login using a username and OAuth2 access token.
637
+ # Non-standard and obsoleted by +OAUTHBEARER+, but widely
638
+ # supported.
639
+ #
640
+ # >>>
641
+ # *Deprecated:* <em>Obsolete mechanisms are available for backwards
642
+ # compatibility.</em>
643
+ #
644
+ # For +DIGEST-MD5+ see DigestMD5Authenticator.
645
+ #
646
+ # For +LOGIN+, see LoginAuthenticator.
647
+ #
648
+ # For +CRAM-MD5+, see CramMD5Authenticator.
649
+ #
650
+ # <em>Using a deprecated mechanism will print a warning.</em>
651
+ #
652
+ # See Net::IMAP::Authenticators for information on plugging in
653
+ # authenticators for other mechanisms. See the {SASL mechanism
654
+ # registry}[https://www.iana.org/assignments/sasl-mechanisms/sasl-mechanisms.xhtml]
655
+ # for information on these and other SASL mechanisms.
656
+ #
657
+ # ===== Capabilities
645
658
#
646
659
# Clients MUST NOT attempt to #authenticate or #login when +LOGINDISABLED+
647
660
# is listed with the capabilities.
@@ -654,9 +667,36 @@ def starttls(options = {}, verify = true)
654
667
# The TaggedResponse to #authenticate may include updated capabilities in
655
668
# its ResponseCode.
656
669
#
657
- def authenticate ( auth_type , *args )
658
- authenticator = self . class . authenticator ( auth_type , *args )
659
- send_command ( "AUTHENTICATE" , auth_type ) do |resp |
670
+ # ===== Example
671
+ # Most mechanisms ignore unhandled keyword arguments, so the same config can
672
+ # be used for multiple authenticator types:
673
+ # password = nil # saved locally, so we don't ask more than once
674
+ # accesstok = nil
675
+ # creds = {
676
+ # authcid: username,
677
+ # password: proc { password ||= ui.prompt_for_password },
678
+ # oauth2_token: proc { accesstok ||= kms.lookup(username, :access_token).refreshed },
679
+ # }
680
+ # capa = imap.capability
681
+ # if capa.include? "LOGINDISABLED"
682
+ # raise "the server has disabled login"
683
+ # elsif capa.include? "AUTH=OAUTHBEARER"
684
+ # imap.authenticate "OAUTHBEARER", **creds # authcid, oauth2_token
685
+ # elsif capa.include? "AUTH=XOAUTH2"
686
+ # imap.authenticate "XOAUTH2", **creds # authcid, oauth2_token
687
+ # elsif capa.include? "AUTH=SCRAM-SHA-256"
688
+ # imap.authenticate "SCRAM-SHA-256", **creds # authcid, password
689
+ # elsif capa.include? "AUTH=PLAIN"
690
+ # imap.authenticate "PLAIN", **creds # authcid, password
691
+ # elsif capa.include? "AUTH=DIGEST-MD5"
692
+ # imap.authenticate "DIGEST-MD5", **creds # authcid, password
693
+ # else
694
+ # raise "no acceptable authentication mechanism is available"
695
+ # end
696
+ #
697
+ def authenticate ( mechanism , *args , **props , &cb )
698
+ authenticator = self . class . authenticator ( mechanism , *args , **props , &cb )
699
+ send_command ( "AUTHENTICATE" , mechanism ) do |resp |
660
700
if resp . instance_of? ( ContinuationRequest )
661
701
data = authenticator . process ( resp . data . text . unpack ( "m" ) [ 0 ] )
662
702
s = [ data ] . pack ( "m0" )
0 commit comments