help-gsasl
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Server querying of mechanism needed properties


From: Simon Josefsson
Subject: Re: Server querying of mechanism needed properties
Date: Mon, 26 Mar 2012 22:55:20 +0200
User-agent: Gnus/5.130004 (Ma Gnus v0.4) Emacs/24.0.94 (gnu/linux)

Phil Pennock <address@hidden> writes:

> Oops!  I should not have deleted the branch on github after integrating
> it to master.  Sorry.
>
> The core of the code is in gsasl_exim.[ch] found at:
>   http://git.exim.org/exim.git/tree/master:/src/src/auths
>   https://github.com/Exim/exim/tree/master/src/src/auths

Thanks for pointers.

Getting it up and running appeared non-trivial to a non-exim hacker like
me, but eventually I'd like to have a Exim server up and running with
GNU SASL support for interop testing.  Is there an easy way to run exim
with a minimal non-/etc configuration and have it listen to some
non-standard port and accept authentication via GNU SASL?  Preferrably
it should disconnect or at least fail mail delivery after
authentication.

>> Fixed in master now.  I've been thinking of renaming GSASL_AUTHID to
>> GSASL_USERNAME for some time now, and maybe now is a good time.  The
>> risk of confusing these two symbols is non-negligible, and USERNAME is a
>> better word than AUTHID even though it is not as RFC4422-like.
>
> As long as GSASL_AUTHID remains defined, I'm happy; note that
> GSASL_NO_AUTHID would also need to become a compatibility name, for
> consistency.
>
> The issue here is that the pre-processor doesn't know which enum names
> exist, so there's no sane way to check which version is being built
> against.  When a system is acting as a dedicated mail-server, then the
> MTA is a piece of software which the postmasters may often choose to
> maintain locally, instead of relying purely upon package management, so
> Exim gets built from current source against some rather old releases.
>
> It doesn't look as though gcc has an extension to mark an enum symbolic
> name as deprecated, only variables, functions and types.

Sigh.  I'm now leaning towards not changing this.

>> Good idea, I hadn't thought of that, but it makes sense.
>
> *phew*  Suddenly I feel a lot happier about having committed my fellow
> maintainers to ongoing support of a second SASL library API.  :)
>
>> >      Alternatively, given that different callback properties can be
>> >      used, with fallbacks, perhaps a way to query "will this set of
>> >      properties be sufficient for this mechanism; if not what is
>> >      missing?"
>> 
>> Yeah, although that is more complex.  But maybe we need to express that
>> property X, Y Z are _required_ and either property A or B is _required_,
>> and property G, H and I are _optional_.  There could even be situations
>> where property P and Q are both optional, but if P is specified so must
>> Q be.
>
> The key of the proposal is not to ask what is required, but to ask
> "given what I'm already offering you, what am I going to need to prompt
> for"; perhaps a vector of sets of results, which are not guaranteed
> unique?

I'm coming back to this issue, but I'm still not settled on what a good
API would look like.

How about something like:

  gsasl_server_properties (ctx, name, &p);

  #define MAX_PROPS 10
  typedef struct {
         int need[MAX_PROPS];
         int avail[MAX_PROPS];
         int opt[MAX_PROPS];
  } gsasl_props;

The meaning is that there is a list of OR sets of values.  In each
member of the array, the 'need' list the properties that are needed.
The 'avail' list the properties that are available for inspection when
the 'need' properties are called for.  The 'opt' properties are
additional properties the server can specify to influence operation.
(There could be a opt_avail to indicate what properties the 'opt'
properties may use to select its values...)

That would result in something like this:

  gsasl_server_properties (ctx, "EXTERNAL", &p):
  p[0].need = { GSASL_VALIDATE_EXTERNAL, 0 }
  p[0].avail = { GSASL_AUTHZID, 0 }

  gsasl_server_properties (ctx, "ANONYMOUS", &p):
  p[0].need = { GSASL_VALIDATE_ANONYMOUS, 0 }
  p[0].avail = { GSASL_ANONYMOUS_TOKEN, 0 }

  gsasl_server_properties (ctx, "PLAIN", &p):
  p[0].need = { GSASL_VALIDATE_SIMPLE, 0 }
  p[0].avail = { GSASL_AUTHID, GSASL_AUTHZID, GSASL_PASSWORD, 0 }
  p[1].need = { GSASL_PASSWORD, 0 }
  p[1].avail = { GSASL_AUTHID, GSASL_AUTHZID, 0 }

  gsasl_server_properties (ctx, "LOGIN", &p):
  p[0].need = { GSASL_VALIDATE_SIMPLE, 0 }
  p[0].avail = { GSASL_AUTHID, GSASL_PASSWORD, 0 }
  p[1].need = { GSASL_PASSWORD, 0 }
  p[1].avail = { GSASL_AUTHID, 0 }

  gsasl_server_properties (ctx, "CRAM-MD5", &p):
  p[0].need = { GSASL_PASSWORD, 0 }
  p[0].avail = { GSASL_AUTHID, 0 }

  gsasl_server_properties (ctx, "DIGEST-MD5", &p):
  p[0].need = { GSASL_DIGEST_MD5_HASHED_PASSWORD, 0 }
  p[0].avail = { GSASL_AUTHID, GSASL_AUTHZID, 0 }
  p[0].opt = { GSASL_SERVICE, GSASL_HOSTNAME, GSASL_REALM, 0 }
  p[1].need = { GSASL_PASSWORD, 0 }
  p[1].avail = { GSASL_AUTHID, GSASL_AUTHZID, 0 }
  p[1].opt = { GSASL_SERVICE, GSASL_HOSTNAME, GSASL_REALM, 0 }

  gsasl_server_properties (ctx, "SCRAM-SHA-1", &p):
  p[0].need = { GSASL_PASSWORD, 0 }
  p[0].avail = { GSASL_AUTHID, GSASL_AUTHZID, 0 }
  p[0].opt = { GSASL_SCRAM_ITER, GSASL_SCRAM_SALT, GSASL_CB_TLS_UNIQUE, 0 }

Compare the explanations in the manual:

https://www.gnu.org/software/gsasl/manual/gsasl.html#Mechanisms

Is this useful?  It doesn't answer your key question directly, but the
information is in there.

Maybe a better API is a "meta" accessor for each mechanism,
e.g. something like this:

  void *gsasl_mech_meta (ctx, "CRAM-MD5", "server-properties")

that can be cast into a struct with the necessary information.

I think some more brainstorming around this is required.

/Simon



reply via email to

[Prev in Thread] Current Thread [Next in Thread]