[Freeipa-devel] OTP Sync Client Design

Nathaniel McCallum npmccallum at redhat.com
Mon May 26 16:23:43 UTC 2014


On Mon, 2014-05-26 at 09:56 +0200, Jan Cholasta wrote:
> On 23.5.2014 23:19, Nathaniel McCallum wrote:
> > On Wed, 2014-05-14 at 14:08 -0400, Nathaniel McCallum wrote:
> >> Occasionally OTP tokens get out of sync with the server. When this
> >> happens, the user or an admin need to synchronize the token. To this
> >> end, we landed server-side synchronization support, which is a simple
> >> bind with a custom control. This all works with my sample test script.
> >>
> >> Client support is proving a bit more difficult. In the ideal world, the
> >> client would contact LDAP directly and perform the operation. This would
> >> make a man in the middle attack difficult and we can ensure encryption
> >> over the entire operation.
> >>
> >> However, browsers, without server-side assistance, cannot perform this
> >> operation from javascript. This means that, in this case, the first
> >> factor and two second factors must be transmitted to the FreeIPA server
> >> and then proxied to 389. Is this an acceptable compromise?
> >>
> >> This command also needs to be accessible *without* an existing user
> >> login since, if a user's token is out of sync, the user can't login. Is
> >> it possible to expose such an API? If so, how? Both "ipa env" and "ipa
> >> ping" seem to require kinit, so I don't see any obvious examples.
> >
> > Thanks everyone for your feedback. This particular feature is proving
> > difficult to implement, even with our agreed upon design. To reiterate
> > this design: there will be an HTTP method by which to synchronize
> > tokens.
> >
> > There are two assumptions in the code which are making this difficult:
> > 1. All cli commands are Command subclasses.
> > 2. All Command subclasses create authenticated server methods.
> >
> > There are thus two ways to tackle this problem.
> >
> > First, I can create a standard POST method in rpcserver.py. This is not
> > very modular. But the biggest problem is that there is no way to create
> > the cli-side command to call it (assumption #1).
> 
> Well, you could derive the command from ipalib.frontend.Local and 
> manually call the POST method from it.

This still creates a (NoOp) server-side RPC method, right? We can
probably just accept this as a drawback for now and move on. After a
future refactoring of rpcserver.py, we can move the manual POST method
into this server-side RPC method.

> > Second, I can create a Command subclass, similar to the passwd plugin.
> > This will create both the client- and server-side components. However,
> > there is no way to disable the server-side authentication.
> >
> > I think that solving the second of these problems is the most reusable.
> > Just as an example, the ping command currently requires authentication
> > but does not need to do so. The passwd Command too shouldn't need to
> > authenticate before executing the command because the command
> > authenticates itself.
> >
> > I think it very likely that we are going to have need for other Command
> > subclasses in the future which do not require authentication.
> >
> > However, implementing this approach is rather difficult as it will
> > require a refactoring of rpcserver.py. The code in rpcserver.py contains
> > many layering violations and the class structure is rather unclear
> > (look, for instance, at the different orders in which xmlrpc and jsonrpc
> > classes inherit from their parent classes).
> >
> > The current problem forcing this refactoring is that authentication
> > appears to happen across several different layers, but always before the
> > command to be executed is unmarshalled. We need to invert this order:
> > the command needs to be unmarshalled first in order to determine whether
> > or not authentication is necessary. I don't think that switching this
> > order is practical without constraining authentication to a single layer
> > (or two: session and krb5) late in the request process.
> >
> > Git tells me that lots of people have touched this code, so I'm hoping
> > for good feedback! ;)
> >
> > Alternatively, we could create a way to inject cli commands without
> > having Command subclasses. Isolating these concerns is itself probably a
> > good design choice. Ideally we'd have a structure where the Command
> > class itself inherits from a CLICommand class and a ServerMethod class.
> > But this too will be a massive refactoring, perhaps even bigger than the
> > rpcserver.py refactoring.
> >
> > So, which assumption should we break: #1 or #2? And who wants to help me
> > do it? Also, I am all ears for easier solutions for this feature.
> 
> I would go for the refactoring, the rpcserver code does indeed need some 
> love.
> 
> >
> > Nathaniel
> 





More information about the Freeipa-devel mailing list