Hi all,

I'm working on an implementation of RFC 4422, the SASL authentication
mechanism. The idea is to make using common SASL mechanisms (PLAIN,
SCRAM-whatever) easy, but also to provide a framework for people to
build their own SASL mechanisms that will be compatible with anything
that uses the package. The package currently lives here (clients work,
the server is just an outline of how it would work and none of the
built in mechanisms will work with it yet since there's no way to pass
in a comparison function or anything yet):

https://godoc.org/mellium.im/sasl

The current major issue is that by providing your credentials to the
specific mechanism you have to know them when you first create that
mechanism, which is too early (you shouldn't have to know credentials
until you actually go to do the SASL negotiation). I've gone through
several iterations trying to find a good API that defers accepting
user credentials, but they've all had one problem or another.

The best one I've attempted so far has been to create a new type:

    type Credentials interface{}

and then allow each mechanisms Start and Next functions to take in
credentials (passed to it by the Client or Server). This way different
mechanisms could take different types of credentials, and custom
mechanisms can ship with their own credentials function, eg. a simple
username/password based mechanism might have a:

    func NewIdentityCreds(identity, username, password string) Credentials

function that returns an unexported struct, and that package would
check for that type of credentials when the mechanism was used.

However, this feels brittle too. In application code this would
probably lead to a giant switch checking the name of mechanisms and
deciding what type of credentials to a pass in, and I'm trying to save
the application developers as much work as possible.

Another thing I thought about doing was reflecting over arbitrary
structs and looking for tags, eg. `sasl:"username"`, but this feels
wrong somehow too (I have no good reason for this one though;
reflection just always has a bit of code smell in my book).

Thoughts? What would you generally do in this situation? Is anyone
aware of an API with similar problems or how they solved it?

Thanks,
Sam

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to