diff options
Diffstat (limited to 'crypto/kerberosIV/lib/krb/ticket_memory.c')
-rw-r--r-- | crypto/kerberosIV/lib/krb/ticket_memory.c | 435 |
1 files changed, 435 insertions, 0 deletions
diff --git a/crypto/kerberosIV/lib/krb/ticket_memory.c b/crypto/kerberosIV/lib/krb/ticket_memory.c new file mode 100644 index 0000000..f694190 --- /dev/null +++ b/crypto/kerberosIV/lib/krb/ticket_memory.c @@ -0,0 +1,435 @@ +/* + * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* ticket_memory.c - Storage for tickets in memory + * Author: d93-jka@nada.kth.se - June 1996 + */ + +#define WIN32_LEAN_AND_MEAN +#include <Windows.h> +#include "krb_locl.h" +#include "ticket_memory.h" + +RCSID("$Id: ticket_memory.c,v 1.15 1999/12/02 16:58:44 joda Exp $"); + +void msg(char *text, int error); + +/* Global variables for memory mapping. */ +HANDLE SharedMemoryHandle; +tktmem *SharedMemory; + +static int CredIndex = -1; + +void PostUpdateMessage(void); + +int +newTktMem(const char *tf_name) +{ + if(!SharedMemory){ + SharedMemoryHandle = CreateFileMapping((HANDLE)-1, 0, + PAGE_READWRITE, + sizeof(tktmem) >> 16, + sizeof(tktmem) & 0xffff, + "krb_memory"); + + if(!SharedMemoryHandle){ + msg("Could not create shared memory.", GetLastError()); + return KFAILURE; + } + + SharedMemory = MapViewOfFile(SharedMemoryHandle, + FILE_MAP_WRITE, 0, 0, 0); + if(!SharedMemory){ + msg("Unable to alloc shared memory.", GetLastError()); + return KFAILURE; + } + if(GetLastError() != ERROR_ALREADY_EXISTS) { + memset(SharedMemory, 0, sizeof(*SharedMemory)); + if(tf_name) + strlcpy(SharedMemory->tmname, + tf_name, sizeof(SharedMemory->tmname)); + } + } + CredIndex = 0; + return KSUCCESS; +} + +int +freeTktMem(const char *tf_name) +{ + if(SharedMemory) { + UnmapViewOfFile(SharedMemory); + CloseHandle(SharedMemoryHandle); + } + return KSUCCESS; +} + + + +tktmem * +getTktMem(const char *tf_name) +{ + return SharedMemory; +} + +void +firstCred(void) +{ + if(getTktMem(0)->last_cred_no > 0) + CredIndex = 0; + else + CredIndex = -1; +} + +int +nextCredIndex(void) +{ + const tktmem *mem; + int last; + mem = getTktMem(0); + last = mem->last_cred_no; + if(CredIndex >= 0 && CredIndex < last ) + return CredIndex++; + else + return CredIndex = -1; +} + +int +currCredIndex(void) +{ + const tktmem *mem; + int last; + mem = getTktMem(0); + last = mem->last_cred_no; + if(CredIndex >= 0 && CredIndex < last) + return CredIndex; + else + return CredIndex = -1; +} + +int +nextFreeIndex(void) +{ + tktmem *mem = getTktMem(0); + if(mem->last_cred_no > CRED_VEC_SZ) + return -1; + else + return mem->last_cred_no++; +} + +/* + * in_tkt() is used to initialize the ticket store. It creates the + * file to contain the tickets and writes the given user's name "pname" + * and instance "pinst" in the file. in_tkt() returns KSUCCESS on + * success, or KFAILURE if something goes wrong. + */ + +int +in_tkt(char *pname, char *pinst) +{ + /* Here goes code to initialize shared memory, to store tickets in. */ + /* Implemented somewhere else. */ + return KFAILURE; +} + +/* + * dest_tkt() is used to destroy the ticket store upon logout. + * If the ticket file does not exist, dest_tkt() returns RET_TKFIL. + * Otherwise the function returns RET_OK on success, KFAILURE on + * failure. + * + * The ticket file (TKT_FILE) is defined in "krb.h". + */ + +int +dest_tkt(void) +{ + memset(getTktMem(0), 0, sizeof(tktmem)); + return 0; +} + +/* Short description of routines: + * + * tf_init() opens the ticket file and locks it. + * + * tf_get_pname() returns the principal's name. + * + * tf_put_pname() writes the principal's name to the ticket file. + * + * tf_get_pinst() returns the principal's instance (may be null). + * + * tf_put_pinst() writes the instance. + * + * tf_get_cred() returns the next CREDENTIALS record. + * + * tf_save_cred() appends a new CREDENTIAL record to the ticket file. + * + * tf_close() closes the ticket file and releases the lock. + * + * tf_gets() returns the next null-terminated string. It's an internal + * routine used by tf_get_pname(), tf_get_pinst(), and tf_get_cred(). + * + * tf_read() reads a given number of bytes. It's an internal routine + * used by tf_get_cred(). + */ + +/* + * tf_init() should be called before the other ticket file routines. + * It takes the name of the ticket file to use, "tf_name", and a + * read/write flag "rw" as arguments. + * + * Returns KSUCCESS if all went well, otherwise one of the following: + * + * NO_TKT_FIL - file wasn't there + * TKT_FIL_ACC - file was in wrong mode, etc. + * TKT_FIL_LCK - couldn't lock the file, even after a retry + */ + +int +tf_init(char *tf_name, int rw) +{ + if(!getTktMem(tf_name)) + return NO_TKT_FIL; + firstCred(); + return KSUCCESS; +} + +/* + * tf_create() should be called when creating a new ticket file. + * The only argument is the name of the ticket file. + * After calling this, it should be possible to use other tf_* functions. + */ + +int +tf_create(char *tf_name) +{ + if(newTktMem(tf_name) != KSUCCESS) + return NO_TKT_FIL; + return KSUCCESS; +} + +/* + * tf_get_pname() reads the principal's name from the ticket file. It + * should only be called after tf_init() has been called. The + * principal's name is filled into the "p" parameter. If all goes well, + * KSUCCESS is returned. If tf_init() wasn't called, TKT_FIL_INI is + * returned. If the name was null, or EOF was encountered, or the name + * was longer than ANAME_SZ, TKT_FIL_FMT is returned. + */ + +int +tf_get_pname(char *p) +{ + tktmem *TktStore; + + if(!(TktStore = getTktMem(0))) + return KFAILURE; + if(!TktStore->pname[0]) + return KFAILURE; + strlcpy(p, TktStore->pname, ANAME_SZ); + return KSUCCESS; +} + +/* + * tf_put_pname() sets the principal's name in the ticket file. Call + * after tf_create(). + */ + +int +tf_put_pname(char *p) +{ + tktmem *TktStore; + + if(!(TktStore = getTktMem(0))) + return KFAILURE; + strlcpy(TktStore->pname, p, sizeof(TktStore->pname)); + return KSUCCESS; +} + +/* + * tf_get_pinst() reads the principal's instance from a ticket file. + * It should only be called after tf_init() and tf_get_pname() have been + * called. The instance is filled into the "inst" parameter. If all + * goes well, KSUCCESS is returned. If tf_init() wasn't called, + * TKT_FIL_INI is returned. If EOF was encountered, or the instance + * was longer than ANAME_SZ, TKT_FIL_FMT is returned. Note that the + * instance may be null. + */ + +int +tf_get_pinst(char *inst) +{ + tktmem *TktStore; + + if(!(TktStore = getTktMem(0))) + return KFAILURE; + strlcpy(inst, TktStore->pinst, INST_SZ); + return KSUCCESS; +} + +/* + * tf_put_pinst writes the principal's instance to the ticket file. + * Call after tf_create. + */ + +int +tf_put_pinst(char *inst) +{ + tktmem *TktStore; + + if(!(TktStore = getTktMem(0))) + return KFAILURE; + strlcpy(TktStore->pinst, inst, sizeof(TktStore->pinst)); + return KSUCCESS; +} + +/* + * tf_get_cred() reads a CREDENTIALS record from a ticket file and fills + * in the given structure "c". It should only be called after tf_init(), + * tf_get_pname(), and tf_get_pinst() have been called. If all goes well, + * KSUCCESS is returned. Possible error codes are: + * + * TKT_FIL_INI - tf_init wasn't called first + * TKT_FIL_FMT - bad format + * EOF - end of file encountered + */ + +int +tf_get_cred(CREDENTIALS *c) +{ + int index; + CREDENTIALS *cred; + tktmem *TktStore; + + if(!(TktStore = getTktMem(0))) + return KFAILURE; + krb_set_kdc_time_diff(TktStore->kdc_diff); + if((index = nextCredIndex()) == -1) + return EOF; + if(!(cred = TktStore->cred_vec+index)) + return KFAILURE; + if(!c) + return KFAILURE; + memcpy(c, cred, sizeof(*c)); + return KSUCCESS; +} + +/* + * tf_close() closes the ticket file and sets "fd" to -1. If "fd" is + * not a valid file descriptor, it just returns. It also clears the + * buffer used to read tickets. + */ + +void +tf_close(void) +{ +} + +/* + * tf_save_cred() appends an incoming ticket to the end of the ticket + * file. You must call tf_init() before calling tf_save_cred(). + * + * The "service", "instance", and "realm" arguments specify the + * server's name; "session" contains the session key to be used with + * the ticket; "kvno" is the server key version number in which the + * ticket is encrypted, "ticket" contains the actual ticket, and + * "issue_date" is the time the ticket was requested (local host's time). + * + * Returns KSUCCESS if all goes well, TKT_FIL_INI if tf_init() wasn't + * called previously, and KFAILURE for anything else that went wrong. + */ + +int +tf_save_cred(char *service, /* Service name */ + char *instance, /* Instance */ + char *realm, /* Auth domain */ + unsigned char *session, /* Session key */ + int lifetime, /* Lifetime */ + int kvno, /* Key version number */ + KTEXT ticket, /* The ticket itself */ + u_int32_t issue_date) /* The issue time */ +{ + CREDENTIALS *cred; + tktmem *mem = getTktMem(0); + int last = nextFreeIndex(); + + if(last == -1) + return KFAILURE; + cred = mem->cred_vec+last; + strlcpy(cred->service, service, sizeof(cred->service)); + strlcpy(cred->instance, instance, sizeof(cred->instance)); + strlcpy(cred->realm, realm, sizeof(cred->realm)); + memcpy(cred->session, session, sizeof(cred->session)); + cred->lifetime = lifetime; + cred->kvno = kvno; + memcpy(&(cred->ticket_st), ticket, sizeof(*ticket)); + cred->issue_date = issue_date; + strlcpy(cred->pname, mem->pname, sizeof(cred->pname)); + strlcpy(cred->pinst, mem->pinst, sizeof(cred->pinst)); + PostUpdateMessage(); + return KSUCCESS; +} + + +static void +set_time_diff(time_t diff) +{ + tktmem *TktStore = getTktMem(0); + if(TktStore == NULL) + return; + TktStore->kdc_diff = diff; +} + + +int +tf_setup(CREDENTIALS *cred, char *pname, char *pinst) +{ + int ret; + ret = tf_create(tkt_string()); + if (ret != KSUCCESS) + return ret; + + if (tf_put_pname(pname) != KSUCCESS || + tf_put_pinst(pinst) != KSUCCESS) { + tf_close(); + return INTK_ERR; + } + + set_time_diff(krb_get_kdc_time_diff()); + + ret = tf_save_cred(cred->service, cred->instance, cred->realm, + cred->session, cred->lifetime, cred->kvno, + &cred->ticket_st, cred->issue_date); + tf_close(); + return ret; +} |