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