[OpenAFS-devel] New SetToken and GetToken pioctls

Simon Wilkinson sxw@inf.ed.ac.uk
Tue, 16 Feb 2010 00:02:57 +0000


With the rise of new security mechanisms, the old Get and Set Token =
pioctls are no longer capable of handling all of the various key =
material that we need to shift between userspace and the kernel. A =
proposal to remedy this was originally on the (now defunct) AFSIG wiki, =
and some of what is below is built from the discussions there. Since =
then, a number of different proposed interfaces have been built - the =
content below is based on these, and specifically on Marcus's work on =
rxk5. There is a partial implementation of these token formats in the =
Linux kernel AFS client.

These new pioctls differ significantly from current AFS pioctls. =
Currently, pioctls use an adhoc marshalling format, which until recently =
was constructed simply by throwing binary blobs between client and =
server space. The arguments to these new pioctls are expressed as XDR, =
in the same way as the rest of AFS's marshalled data structures. In =
theory this makes implementation simpler, and it certainly reduces the =
potential for buffer overflows.

The XG is:

const AFSTOKEN_RK_TIX_MAX =3D 12000;      /* Matches entry in rxkad.h */

struct token_rxkad {
    afs_int32 rk_viceid;
    afs_int32 rk_kvno;
    opaque rk_key[8];
    afs_int32 rk_begintime;
    afs_int32 rk_endtime;
    afs_int32 rk_primary_flag;
    opaque rk_ticket<AFSTOKEN_RK_TIX_MAX>;
};

const AFSTOKEN_UNION_NOAUTH =3D 0;
const AFSTOKEN_UNION_KAD =3D 2;
union ktc_tokenUnion switch (afs_int32 at_type) {
    case AFSTOKEN_UNION_KAD:
        token_rxkad at_kad;
};

const AFSTOKEN_LENGTH_MAX =3D 16384;
typedef opaque token_opaque<AFSTOKEN_LENGTH_MAX>;

const AFSTOKEN_EX_SETPAG =3D 0x00000001; /* set tokens in new pag */
const AFSTOKEN_EX_ADD =3D 0x00000002; /* add to existing tokens */
const AFSTOKEN_MAX =3D 8;
const AFSTOKEN_CELL_MAX =3D 64;

struct ktc_setTokenData {
    afs_int32 flags;
    string cell<AFSTOKEN_CELL_MAX>;
    token_opaque tokens<AFSTOKEN_MAX>;
};

We then have two new pioctls...

VIOC_SETTOK2 takes as input the XDR encoded ktc_setTokenData structure. =
This contains the global settings (the cell, cell wide flags), and a =
list of individual tokens to set. These are XDR encoded representations =
of the ktc_tokenUnion discriminated union, one for each token we want to =
add for this cell. Clients may set token types that are not supported by =
the kernel - these should just be returned intact to the client in =
response to a get token call. Token types directly correspond to the =
security index of the associated security class.

The flags control the behaviour of the the settok call. If =
AFSTOKEN_EX_SETPAG is set, then we
perform the old 'change the pag of the parent process' behaviour. If =
AFSTOKEN_EX_ADD is set,
then we we add these tokens to the existing set for this cell. =
Otherwise, we replace them.

It is permitted to set tokens in the kernel that the kernel module does =
not understand - in this case, the kernel should just store those =
tokens, and return them to the user when the GetTokens call is =
performed. These may be tokens for entire classes that are unknown to =
the kernel, or ones which use (for example) encryption algorithms that =
aren't available in kernel.


VICE_GETTOK2 takes as input _either_ an afs_int32 index, or a NULL =
terminated string containing the name of the cell to retrieve (this is =
the same input as the existing GetToken pioctl), and returns an XDR =
encoded ktc_setTokenData structure containing all of the tokens for that =
cell.


Kernel modules and clients which support these new pioctls should =
continue to support the old ones too. Older clients will only be able to =
set, and read, rxkad tokens. When an old-style VIOC_SETTOK is received, =
the kernel module must clear all tokens for the cell.=20

Any comments?

Simon.