/* key_afs.c: AFS filesystem keys * * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved. * Written by David Howells (dhowells@redhat.com) * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ #include #include #include #include #include #include #include #include "cell.h" #include "internal.h" static int afs_key_init(struct key *key, const char *desc, size_t datalen, const char *data); static int afs_key_match(const struct key *key, const void *desc); static void afs_key_clear(struct key *key); static void afs_key_describe(const struct key *keyring, struct seq_file *m); struct afs_key_data { uint16_t session_key_size; uint16_t ticket_size; int32_t kvno; time_t expiry; uint8_t data[0]; }; /* AFS Kerberos ticket * - the description must be the name of the cell to which applicable * - the data is a struct afs_key_data */ struct key_type key_type_afs = { .name = "afs", .link = LIST_HEAD_INIT(key_type_afs.link), .init = afs_key_init, .match = afs_key_match, .clear = afs_key_clear, .describe = afs_key_describe, }; static int afs_key_init(struct key *key, const char *desc, size_t datalen, const char *data) { struct afs_key_data *keydata = (void *) data; size_t dlen; kenter("{%u},%s,%zu,{sk=%hu,tkt=%hu,v=%d,xp=%x}", key->serial, desc, datalen, keydata->session_key_size, keydata->ticket_size, keydata->kvno, (int) keydata->expiry); dlen = strlen(desc) + 1; key->description.data = kmalloc(dlen, GFP_KERNEL); if (!key->description.data) { kleave(" = -ENOMEM"); return -ENOMEM; } memcpy(key->description.data, desc, dlen); key->payload.data = kmalloc(datalen, GFP_KERNEL); if (!key->payload.data) { kleave(" = -ENOMEM"); return -ENOMEM; } key->datalen = datalen; memcpy(key->payload.data, data, datalen); kleave(" = 0"); return 0; } static int afs_key_match(const struct key *key, const void *desc) { if (!key->description.data) return 0; return strcmp(key->description.data, desc) == 0 ? 1 : 0; } static void afs_key_clear(struct key *key) { if (key->description.data) kfree(key->description.data); if (key->payload.data) kfree(key->payload.data); } static void afs_key_describe(const struct key *key, struct seq_file *m) { struct afs_key_data *keydata; if (!key->description.data) { seq_puts(m, "[anon]"); return; } keydata = key->payload.data; seq_printf(m, "%s => { s=%hu t=%hu v=%d x=%lx }", (char *) key->description.data, keydata->session_key_size, keydata->ticket_size, keydata->kvno, (int) keydata->expiry - CURRENT_TIME.tv_sec); } int __init afs_key_register(void) { return register_key_type(&key_type_afs); } void __exit afs_key_unregister(void) { unregister_key_type(&key_type_afs); }