Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Should we create a shared net-sasl gem? #23

Open
4 of 5 tasks
nevans opened this issue Apr 28, 2021 · 6 comments
Open
4 of 5 tasks

Should we create a shared net-sasl gem? #23

nevans opened this issue Apr 28, 2021 · 6 comments
Assignees
Labels
SASL 🔒 Authentication and authentication mechanisms

Comments

@nevans
Copy link
Collaborator

nevans commented Apr 28, 2021

Currently, the following gems duplicate partial support for a small subset of SASL mechanisms:

  • net-imap
  • net-smtp
  • net-pop (it's actually missing, but it should be in there)
  • net-ldap
  • blather (XMPP)
  • memcached
  • dalli (another memcached client)
  • ...and probably many others.

This duplication and incomplete support basically defeats the purpose of SASL. It seems to me that SASL is used in a wide enough number of internet protocols that some level of SASL support should be in stdlib. See e.g. it's in java standard edition

We could start with a very simple API, which only handles client-side authentication and doesn't do much more than Net::IMAP already does. Simply providing a standard for pluggable support is useful. E.g here's a starter proposal:

  • class Net::SASL::Registry to allow non-global config, so e.g. a mechanism could be added to Net::IMAP without affecting other libraries.
    • #add_authenticator(name, mechanism_class)
    • #authenticator(name, *args)
    • both of these methods would also be available from a global registry on Net::SASL
  • Net::SASL::Authenticator interface (can provide a super-class with NotImplementedError on perform):
    • #initialize(*credentials, uri: nil)
      • some mechanisms require the host and port, and supporting that in the generic interface simplifies making clients work properly regardless of which mechanism is selected.
    • #supports_initial_response?
    • #process(challenge) - just as with Net::IMAP. IR sends a nil challenge
    • #done? - for mechanisms implementing a state machine, users of the library can know it is done without needing to call #perform and catch an exception.
    • respond_to?(...)could be used for backwards compatibility with Net::IMAP authenticators which haven't yet been updated to add supports_initial_response? or #done?.
  • utility methods:
    • Net::SASL.saslprep(string) - implements RFC4013, which is required by some mechanisms and recommended for others

And, of course, we could start by adding the existing Net::IMAP mechanisms. But it would be simple and very useful to add OAUTHBEARER and some others as well.

I've marked #22 as a draft, pending some discussion about this. Is this the correct place to discuss this? Should I create a ticket in the ruby issue tracker?

@nevans
Copy link
Collaborator Author

nevans commented Apr 29, 2021

FYI: I pushed a proof of concept here: master...nevans:net-sasl

@shugo
Copy link
Member

shugo commented Apr 30, 2021

net-* are not bundled gems, but default gems now, so such a structural change may affect maintenance cost of Ruby releases.

@hsbt What do you think?

@nevans
Copy link
Collaborator Author

nevans commented May 3, 2021

I definitely don't want to increase maintenance costs. But this functionality is already in default gems twice (net-imap and net-smtp) and it's noticeably missing from net-pop. It probably would've been added net-pop too... if a simple shared SASL library had existed. 😄 My hope is that this could maybe decrease overall maintenance cost across all three projects?

I've just released https://rubygems.org/gems/net-sasl v0.1.0, and I'll happily transfer ownership of the gem if the proposal is accepted. I've created a new branch which uses it (master...nevans:net-sasl-gem) and I can submit draft PRs to net-smtp and net-pop later in the week.

I was planning to add support for ANONYMOUS, EXTERNAL, XOAUTH, and OAUTHBEARER. And I noticed that the ruby-kafka gem has support for GSSAPI, SCRAM-SHA-256, and SCRAM-SHA-512, so those should be relatively simple to copy over as well. Of course these can just as easily be added to net-imap as to net-sasl, but with net-sasl we can make them automatically available to any library that uses it: IMAP, POP, SMTP, LDAP, XMPP, Kafka, etc.

What do you think?

@shugo
Copy link
Member

shugo commented May 6, 2021

I'm for your proposal, but I'm not a maintainer of net-smtp and net-pop, so I'll wait for replies to PRs to them.

@nevans
Copy link
Collaborator Author

nevans commented May 6, 2021

Great, thanks. I'll put those PRs together when I have time (next week probably).

@Neustradamus
Copy link

To follow :)

@nevans nevans added the SASL 🔒 Authentication and authentication mechanisms label Feb 12, 2023
nevans added a commit to nevans/net-smtp that referenced this issue Oct 9, 2023
This commit converts `#authenticate` to use `net-imap` as a generic
fallback for mechanisms that haven't otherwise been added (as subclasses
of `Authenticator`).  In this commit, the original implementation is
still used by `#authenticate` for the `PLAIN`, `LOGIN`, and `CRAM-MD5`
mechanisms.  Every other mechanism supported by `net-imap` v0.4.0 is
added here:
* `ANONYMOUS`
* `DIGEST-MD5` _(deprecated)_
* `EXTERNAL`
* `OAUTHBEARER`
* `SCRAM-SHA-1` and `SCRAM-SHA-256`
* `XOAUTH`

**TODO:** Ideally, `net-smtp` and `net-imap` should both depend on a
shared `sasl` or `net-sasl` gem, rather than keep the SASL
implementation inside one or the other.  See
ruby/net-imap#23.

**TODO:** since we already know the authenticator arguments up-front, we
can validate authenticator arguments by simply creating the
authenticator object and rely on the its initializer to raise
ArgumentError for missing args.
nevans added a commit to nevans/net-smtp that referenced this issue Oct 9, 2023
This commit converts `#authenticate` to use `net-imap` as a generic
fallback for mechanisms that haven't otherwise been added (as subclasses
of `Authenticator`).  In this commit, the original implementation is
still used by `#authenticate` for the `PLAIN`, `LOGIN`, and `CRAM-MD5`
mechanisms.  Every other mechanism supported by `net-imap` v0.4.0 is
added here:
* `ANONYMOUS`
* `DIGEST-MD5` _(deprecated)_
* `EXTERNAL`
* `OAUTHBEARER`
* `SCRAM-SHA-1` and `SCRAM-SHA-256`
* `XOAUTH`

**TODO:** Ideally, `net-smtp` and `net-imap` should both depend on a
shared `sasl` or `net-sasl` gem, rather than keep the SASL
implementation inside one or the other.  See
ruby/net-imap#23.

**TODO:** since we already know the authenticator arguments up-front, we
can validate authenticator arguments by simply creating the
authenticator object and rely on the its initializer to raise
ArgumentError for missing args.
nevans added a commit to nevans/net-smtp that referenced this issue Oct 9, 2023
This commit converts `#authenticate` to use `net-imap` as a generic
fallback for mechanisms that haven't otherwise been added (as subclasses
of `Authenticator`).  In this commit, the original implementation is
still used by `#authenticate` for the `PLAIN`, `LOGIN`, and `CRAM-MD5`
mechanisms.  Every other mechanism supported by `net-imap` v0.4.0 is
added here:
* `ANONYMOUS`
* `DIGEST-MD5` _(deprecated)_
* `EXTERNAL`
* `OAUTHBEARER`
* `SCRAM-SHA-1` and `SCRAM-SHA-256`
* `XOAUTH`

**TODO:** Ideally, `net-smtp` and `net-imap` should both depend on a
shared `sasl` or `net-sasl` gem, rather than keep the SASL
implementation inside one or the other.  See
ruby/net-imap#23.

**TODO:** since we already know the authenticator arguments up-front, we
can validate authenticator arguments by simply creating the
authenticator object and rely on the its initializer to raise
ArgumentError for missing args.
nevans added a commit to nevans/net-smtp that referenced this issue Oct 10, 2023
This commit converts `#authenticate` to use `net-imap` as a generic
fallback for mechanisms that haven't otherwise been added (as subclasses
of `Authenticator`).  In this commit, the original implementation is
still used by `#authenticate` for the `PLAIN`, `LOGIN`, and `CRAM-MD5`
mechanisms.  Every other mechanism supported by `net-imap` v0.4.0 is
added here:
* `ANONYMOUS`
* `DIGEST-MD5` _(deprecated)_
* `EXTERNAL`
* `OAUTHBEARER`
* `SCRAM-SHA-1` and `SCRAM-SHA-256`
* `XOAUTH`

**TODO:** Ideally, `net-smtp` and `net-imap` should both depend on a
shared `sasl` or `net-sasl` gem, rather than keep the SASL
implementation inside one or the other.  See
ruby/net-imap#23.

**TODO:** since we already know the authenticator arguments up-front, we
can validate authenticator arguments by simply creating the
authenticator object and rely on the its initializer to raise
ArgumentError for missing args.
nevans added a commit to nevans/net-smtp that referenced this issue Oct 11, 2023
This commit converts `#authenticate` to use `net-imap` as a generic
fallback for mechanisms that haven't otherwise been added (as subclasses
of `Authenticator`).  In this commit, the original implementation is
still used by `#authenticate` for the `PLAIN`, `LOGIN`, and `CRAM-MD5`
mechanisms.  Every other mechanism supported by `net-imap` v0.4.0 is
added here:
* `ANONYMOUS`
* `DIGEST-MD5` _(deprecated)_
* `EXTERNAL`
* `OAUTHBEARER`
* `SCRAM-SHA-1` and `SCRAM-SHA-256`
* `XOAUTH`

**TODO:** Ideally, `net-smtp` and `net-imap` should both depend on a
shared `sasl` or `net-sasl` gem, rather than keep the SASL
implementation inside one or the other.  See
ruby/net-imap#23.

**TODO:** since we already know the authenticator arguments up-front, we
can validate authenticator arguments by simply creating the
authenticator object and rely on the its initializer to raise
ArgumentError for missing args.
nevans added a commit to nevans/net-smtp that referenced this issue Oct 11, 2023
This commit converts `#authenticate` to use `net-imap` as a generic
fallback for mechanisms that haven't otherwise been added (as subclasses
of `Authenticator`).  In this commit, the original implementation is
still used by `#authenticate` for the `PLAIN`, `LOGIN`, and `CRAM-MD5`
mechanisms.  Every other mechanism supported by `net-imap` v0.4.0 is
added here:
* `ANONYMOUS`
* `DIGEST-MD5` _(deprecated)_
* `EXTERNAL`
* `OAUTHBEARER`
* `SCRAM-SHA-1` and `SCRAM-SHA-256`
* `XOAUTH`

**TODO:** Ideally, `net-smtp` and `net-imap` should both depend on a
shared `sasl` or `net-sasl` gem, rather than keep the SASL
implementation inside one or the other.  See
ruby/net-imap#23.

**TODO:** since we already know the authenticator arguments up-front, we
can validate authenticator arguments by simply creating the
authenticator object and rely on the its initializer to raise
ArgumentError for missing args.
nevans added a commit to nevans/net-smtp that referenced this issue Oct 11, 2023
This commit converts `#authenticate` to use `net-imap` as a generic
fallback for mechanisms that haven't otherwise been added (as subclasses
of `Authenticator`).  In this commit, the original implementation is
still used by `#authenticate` for the `PLAIN`, `LOGIN`, and `CRAM-MD5`
mechanisms.  Every other mechanism supported by `net-imap` v0.4.0 is
added here:
* `ANONYMOUS`
* `DIGEST-MD5` _(deprecated)_
* `EXTERNAL`
* `OAUTHBEARER`
* `SCRAM-SHA-1` and `SCRAM-SHA-256`
* `XOAUTH`

**TODO:** Ideally, `net-smtp` and `net-imap` should both depend on a
shared `sasl` or `net-sasl` gem, rather than keep the SASL
implementation inside one or the other.  See
ruby/net-imap#23.

**TODO:** since we already know the authenticator arguments up-front, we
can validate authenticator arguments by simply creating the
authenticator object and rely on the its initializer to raise
ArgumentError for missing args.
nevans added a commit to nevans/net-smtp that referenced this issue Oct 14, 2023
This commit adds the `net-imap` as a default fallback for mechanisms
that haven't otherwise been added.  In this commit, the original
implementation is still used by `#authenticate` for the `PLAIN`,
`LOGIN`, and `CRAM-MD5` mechanisms.  Every other mechanism supported by
`net-imap` v0.4.0 is added here:
* `ANONYMOUS`
* `DIGEST-MD5` _(deprecated)_
* `EXTERNAL`
* `OAUTHBEARER`
* `SCRAM-SHA-1` and `SCRAM-SHA-256`
* `XOAUTH`

**TODO:** Ideally, `net-smtp` and `net-imap` should both depend on a
shared `sasl` or `net-sasl` gem, rather than keep the SASL
implementation inside one or the other.  See
ruby/net-imap#23.
nevans added a commit to nevans/net-smtp that referenced this issue Oct 14, 2023
This commit adds the `net-imap` as a default fallback for mechanisms
that haven't otherwise been added.  In this commit, the original
implementation is still used by `#authenticate` for the `PLAIN`,
`LOGIN`, and `CRAM-MD5` mechanisms.  Every other mechanism supported by
`net-imap` v0.4.0 is added here:
* `ANONYMOUS`
* `DIGEST-MD5` _(deprecated)_
* `EXTERNAL`
* `OAUTHBEARER`
* `SCRAM-SHA-1` and `SCRAM-SHA-256`
* `XOAUTH`

**TODO:** Ideally, `net-smtp` and `net-imap` should both depend on a
shared `sasl` or `net-sasl` gem, rather than keep the SASL
implementation inside one or the other.  See
ruby/net-imap#23.
nevans added a commit to nevans/net-smtp that referenced this issue Oct 14, 2023
This commit adds the `net-imap` as a default fallback for mechanisms
that haven't otherwise been added.  In this commit, the original
implementation is still used by `#authenticate` for the `PLAIN`,
`LOGIN`, and `CRAM-MD5` mechanisms.  Every other mechanism supported by
`net-imap` v0.4.0 is added here:
* `ANONYMOUS`
* `DIGEST-MD5` _(deprecated)_
* `EXTERNAL`
* `OAUTHBEARER`
* `SCRAM-SHA-1` and `SCRAM-SHA-256`
* `XOAUTH`

**TODO:** Ideally, `net-smtp` and `net-imap` should both depend on a
shared `sasl` or `net-sasl` gem, rather than keep the SASL
implementation inside one or the other.  See
ruby/net-imap#23.
nevans added a commit to nevans/net-smtp that referenced this issue Oct 14, 2023
This commit adds the `net-imap` as a default fallback for mechanisms
that haven't otherwise been added.  In this commit, the original
implementation is still used by `#authenticate` for the `PLAIN`,
`LOGIN`, and `CRAM-MD5` mechanisms.  Every other mechanism supported by
`net-imap` v0.4.0 is added here:
* `ANONYMOUS`
* `DIGEST-MD5` _(deprecated)_
* `EXTERNAL`
* `OAUTHBEARER`
* `SCRAM-SHA-1` and `SCRAM-SHA-256`
* `XOAUTH`

**TODO:** Ideally, `net-smtp` and `net-imap` should both depend on a
shared `sasl` or `net-sasl` gem, rather than keep the SASL
implementation inside one or the other.  See
ruby/net-imap#23.
nevans added a commit to nevans/net-smtp that referenced this issue Oct 15, 2023
This commit adds the `net-imap` as a default fallback for mechanisms
that haven't otherwise been added.  In this commit, the original
implementation is still used by `#authenticate` for the `PLAIN`,
`LOGIN`, and `CRAM-MD5` mechanisms.  Every other mechanism supported by
`net-imap` v0.4.0 is added here:
* `ANONYMOUS`
* `DIGEST-MD5` _(deprecated)_
* `EXTERNAL`
* `OAUTHBEARER`
* `SCRAM-SHA-1` and `SCRAM-SHA-256`
* `XOAUTH`

**TODO:** Ideally, `net-smtp` and `net-imap` should both depend on a
shared `sasl` or `net-sasl` gem, rather than keep the SASL
implementation inside one or the other.  See
ruby/net-imap#23.
nevans added a commit to nevans/net-smtp that referenced this issue Oct 15, 2023
This commit adds the `net-imap` as a default fallback for mechanisms
that haven't otherwise been added.  In this commit, the original
implementation is still used by `#authenticate` for the `PLAIN`,
`LOGIN`, and `CRAM-MD5` mechanisms.  Every other mechanism supported by
`net-imap` v0.4.0 is added here:
* `ANONYMOUS`
* `DIGEST-MD5` _(deprecated)_
* `EXTERNAL`
* `OAUTHBEARER`
* `SCRAM-SHA-1` and `SCRAM-SHA-256`
* `XOAUTH`

**TODO:** Ideally, `net-smtp` and `net-imap` should both depend on a
shared `sasl` or `net-sasl` gem, rather than keep the SASL
implementation inside one or the other.  See
ruby/net-imap#23.
nevans added a commit to nevans/net-smtp that referenced this issue Oct 15, 2023
This commit adds the `net-imap` as a default fallback for mechanisms
that haven't otherwise been added.  In this commit, the original
implementation is still used by `#authenticate` for the `PLAIN`,
`LOGIN`, and `CRAM-MD5` mechanisms.  Every other mechanism supported by
`net-imap` v0.4.0 is added here:
* `ANONYMOUS`
* `DIGEST-MD5` _(deprecated)_
* `EXTERNAL`
* `OAUTHBEARER`
* `SCRAM-SHA-1` and `SCRAM-SHA-256`
* `XOAUTH`

**TODO:** Ideally, `net-smtp` and `net-imap` should both depend on a
shared `sasl` or `net-sasl` gem, rather than keep the SASL
implementation inside one or the other.  See
ruby/net-imap#23.
nevans added a commit to nevans/net-smtp that referenced this issue Oct 15, 2023
This commit adds the `net-imap` as a default fallback for mechanisms
that haven't otherwise been added.  In this commit, the original
implementation is still used by `#authenticate` for the `PLAIN`,
`LOGIN`, and `CRAM-MD5` mechanisms.  Every other mechanism supported by
`net-imap` v0.4.0 is added here:
* `ANONYMOUS`
* `DIGEST-MD5` _(deprecated)_
* `EXTERNAL`
* `OAUTHBEARER`
* `SCRAM-SHA-1` and `SCRAM-SHA-256`
* `XOAUTH`

**TODO:** Ideally, `net-smtp` and `net-imap` should both depend on a
shared `sasl` or `net-sasl` gem, rather than keep the SASL
implementation inside one or the other.  See
ruby/net-imap#23.
nevans added a commit to nevans/net-smtp that referenced this issue Oct 20, 2023
This commit adds the `net-imap` as a default fallback for mechanisms
that haven't otherwise been added.  In this commit, the original
implementation is still used by `#authenticate` for the `PLAIN`,
`LOGIN`, and `CRAM-MD5` mechanisms.  Every other mechanism supported by
`net-imap` v0.4.0 is added here:
* `ANONYMOUS`
* `DIGEST-MD5` _(deprecated)_
* `EXTERNAL`
* `OAUTHBEARER`
* `SCRAM-SHA-1` and `SCRAM-SHA-256`
* `XOAUTH`

**TODO:** Ideally, `net-smtp` and `net-imap` should both depend on a
shared `sasl` or `net-sasl` gem, rather than keep the SASL
implementation inside one or the other.  See
ruby/net-imap#23.
nevans added a commit to nevans/net-smtp that referenced this issue Oct 21, 2023
This commit adds the `net-imap` as a default fallback for mechanisms
that haven't otherwise been added.  In this commit, the original
implementation is still used by `#authenticate` for the `PLAIN`,
`LOGIN`, and `CRAM-MD5` mechanisms.  Every other mechanism supported by
`net-imap` v0.4.0 is added here:
* `ANONYMOUS`
* `DIGEST-MD5` _(deprecated)_
* `EXTERNAL`
* `OAUTHBEARER`
* `SCRAM-SHA-1` and `SCRAM-SHA-256`
* `XOAUTH`

**TODO:** Ideally, `net-smtp` and `net-imap` should both depend on a
shared `sasl` or `net-sasl` gem, rather than keep the SASL
implementation inside one or the other.  See
ruby/net-imap#23.
nevans added a commit to nevans/net-smtp that referenced this issue Oct 21, 2023
This commit adds the `net-imap` as a default fallback for mechanisms
that haven't otherwise been added.  In this commit, the original
implementation is still used by `#authenticate` for the `PLAIN`,
`LOGIN`, and `CRAM-MD5` mechanisms.  Every other mechanism supported by
`net-imap` v0.4.0 is added here:
* `ANONYMOUS`
* `DIGEST-MD5` _(deprecated)_
* `EXTERNAL`
* `OAUTHBEARER`
* `SCRAM-SHA-1` and `SCRAM-SHA-256`
* `XOAUTH`

**TODO:** Ideally, `net-smtp` and `net-imap` should both depend on a
shared `sasl` or `net-sasl` gem, rather than keep the SASL
implementation inside one or the other.  See
ruby/net-imap#23.
@nevans nevans pinned this issue Oct 23, 2023
nevans added a commit to nevans/net-smtp that referenced this issue Nov 7, 2023
This commit adds the `net-imap` as a default fallback for mechanisms
that haven't otherwise been added.  In this commit, the original
implementation is still used by `#authenticate` for the `PLAIN`,
`LOGIN`, and `CRAM-MD5` mechanisms.  Every other mechanism supported by
`net-imap` v0.4.0 is added here:
* `ANONYMOUS`
* `DIGEST-MD5` _(deprecated)_
* `EXTERNAL`
* `OAUTHBEARER`
* `SCRAM-SHA-1` and `SCRAM-SHA-256`
* `XOAUTH`

**TODO:** Ideally, `net-smtp` and `net-imap` should both depend on a
shared `sasl` or `net-sasl` gem, rather than keep the SASL
implementation inside one or the other.  See
ruby/net-imap#23.
nevans added a commit to nevans/net-smtp that referenced this issue Nov 9, 2023
This commit adds the `net-imap` as a default fallback for mechanisms
that haven't otherwise been added.  In this commit, the original
implementation is still used by `#authenticate` for the `PLAIN`,
`LOGIN`, and `CRAM-MD5` mechanisms.  Every other mechanism supported by
`net-imap` v0.4.0 is added here:
* `ANONYMOUS`
* `DIGEST-MD5` _(deprecated)_
* `EXTERNAL`
* `OAUTHBEARER`
* `SCRAM-SHA-1` and `SCRAM-SHA-256`
* `XOAUTH`

**TODO:** Ideally, `net-smtp` and `net-imap` should both depend on a
shared `sasl` or `net-sasl` gem, rather than keep the SASL
implementation inside one or the other.  See
ruby/net-imap#23.
nevans added a commit to nevans/net-smtp that referenced this issue May 5, 2024
This commit adds the `net-imap` as a default fallback for mechanisms
that haven't otherwise been added.  In this commit, the original
implementation is still used by `#authenticate` for the `PLAIN`,
`XOAUTH2`, `LOGIN`, and `CRAM-MD5` mechanisms.  Every other mechanism
supported by `net-imap` v0.4.0 is added here:
* `ANONYMOUS`
* `DIGEST-MD5` _(deprecated)_
* `EXTERNAL`
* `OAUTHBEARER`
* `SCRAM-SHA-1` and `SCRAM-SHA-256`

**TODO:** Ideally, `net-smtp` and `net-imap` should both depend on a
shared `sasl` or `net-sasl` gem, rather than keep the SASL
implementation inside one or the other.  See
ruby/net-imap#23.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
SASL 🔒 Authentication and authentication mechanisms
Development

No branches or pull requests

4 participants