[Freeipa-devel] OTP Sync Client Design

Jan Cholasta jcholast at redhat.com
Mon May 26 07:56:40 UTC 2014


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.

>
> 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

-- 
Jan Cholasta




More information about the Freeipa-devel mailing list