From c15373cde8cf9cd0aefb9eb591401faa32a06166 Mon Sep 17 00:00:00 2001 From: Theodore Tso Date: Wed, 30 Sep 1992 13:24:49 +0000 Subject: [PATCH] *** empty log message *** git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@2449 dc483132-0cff-0310-8789-dd5450dbe970 --- src/admin/edit/util.c | 165 +++++++++++++ src/include/krb5/adm_defs.h | 198 ++++++++++++++++ src/include/krb5/preauth.h | 81 +++++++ src/include/krb5/rsa-md5.h | 64 +++++ src/lib/krb5/krb/preauth.c | 460 ++++++++++++++++++++++++++++++++++++ 5 files changed, 968 insertions(+) create mode 100644 src/admin/edit/util.c create mode 100644 src/include/krb5/adm_defs.h create mode 100644 src/include/krb5/preauth.h create mode 100644 src/include/krb5/rsa-md5.h create mode 100644 src/lib/krb5/krb/preauth.c diff --git a/src/admin/edit/util.c b/src/admin/edit/util.c new file mode 100644 index 000000000..48226234d --- /dev/null +++ b/src/admin/edit/util.c @@ -0,0 +1,165 @@ +/* + * $Source$ + * $Author$ + * + * Copyright 1992 by the Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America is assumed + * to require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * Utilities for kdb5_edit. + * + * Some routines derived from code contributed by the Sandia National + * Laboratories. Sandia National Laboratories also makes no + * representations about the suitability of the modifications, or + * additions to this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + */ + +#if !defined(lint) && !defined(SABER) +static char rcsid_util_c[] = +"$Id$"; +#endif /* !lint & !SABER */ + +#include +#include +#include +#include + +#include "./kdb5_edit.h" + +#if defined(sysvimp) || ( defined(mips) && defined(SYSTYPE_BSD43)) || (defined(vax) && !defined(ultrix)) +char * +strstr(s1, s2) +char *s1; +char *s2; +{ + int s2len; + int i; + char *temp_ptr; + + temp_ptr = s1; + for ( i = 0; i < strlen(s1); i++) { + if (memcmp(temp_ptr, s2, strlen(s2)) == 0) return(temp_ptr); + temp_ptr += 1; + } + return ((char *) 0); +} +#endif /* sysvimp */ + +void +parse_token(token_in, must_be_first_char, num_tokens, tokens_out) +char *token_in; +int *must_be_first_char; +int *num_tokens; +char *tokens_out; +{ + int i, j; + int token_count = 0; + + i = 0; + j = 0; + + /* Eliminate Up Front Asterisks */ + *must_be_first_char = 1; + for (i = 0; token_in[i] == '*'; i++) { + *must_be_first_char = 0; + } + + if (i == strlen(token_in)) { + *num_tokens = 0; + return; + } + + /* Fill first token_out */ + token_count++; + while ((token_in[i] != '*') && (token_in[i] != '\0')) { + tokens_out[j] = token_in[i]; + j++; + i++; + } + + if (i == strlen(token_in)) { + tokens_out[j] = '\0'; + *num_tokens = token_count; + return; + } + + /* Then All Subsequent Tokens */ + while (i < strlen(token_in)) { + if (token_in[i] == '*') { + token_count++; + tokens_out[j] = '\t'; + } else { + tokens_out[j] = token_in[i]; + } + i++; + j++; + } + tokens_out[j] = '\0'; + + if (tokens_out[j - 1] == '\t') { + token_count--; + tokens_out[j - 1] = '\0'; + } + + *num_tokens = token_count; + return; +} + +int +check_for_match(search_field, must_be_first_character, chk_entry, + num_tokens, type) +int must_be_first_character; +char *search_field; +krb5_db_entry *chk_entry; +int num_tokens; +int type; +{ + char token1[256]; + char *found1; + char token2[256]; + char *found2; + char token3[256]; + char *found3; + char *local_entry; + + local_entry = chk_entry->principal->data[type].data; + + token1[0] = token2[0] = token3[0] = '\0'; + + (void) sscanf(search_field, "%s\t%s\t%s", token1, token2, token3); + + found1 = strstr(local_entry, token1); + + if (must_be_first_character && (found1 != local_entry)) return(0); + + if (found1 && (num_tokens == 1)) return(1); + + if (found1 && (num_tokens > 1)) { + found2 = strstr(local_entry, token2); + if (found2 && (found2 > found1) && (num_tokens == 2)) return(1); + } + + if ((found2 > found1) && (num_tokens == 3)) { + found3 = strstr(local_entry, token3); + if (found3 && (found3 > found2) && (found2 > found1)) return(1); + } + return(0); +} + diff --git a/src/include/krb5/adm_defs.h b/src/include/krb5/adm_defs.h new file mode 100644 index 000000000..ae69831e0 --- /dev/null +++ b/src/include/krb5/adm_defs.h @@ -0,0 +1,198 @@ +/* + * $Source$ + * $Author$ + * $Id$ + * + * Copyright 1990 by the Massachusetts Institute of Technology. + * + * Export of this software from the United States of America is assumed + * to require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * + * <<< Description >>> + */ + + +#ifndef __ADM_DEFINES__ +#define __ADM_DEFINES__ + +#define ADM5_VERSTR "ADM5VER1" +#define ADM5_VERSIZE strlen(ADM5_VERSTR) +/* This used to be kerberos_master */ +#define ADM5_PORTNAME "kerberos_adm" +#define DEFAULT_ACL_NAME "/krb5/.admin_acl_file" +#define ADM5_CPW_VERSION "V5CPWS01" +#define ADM5_ADM_VERSION "V5ADMS01" +#define CPWNAME "kadmin" +/* Instance used to be kerberos +#define CPWINSTANCE "kerberos" + Now, instance is realm */ +#define ADMINSTANCE "admin" + +#define ADM_CPW_VERSION "V5CPWS01" +#define ADM_MAX_PW_ITERATIONS 5 +#define ADM_MAX_PW_CHOICES 5 + +#ifdef MACH_PASS +#define ADM_MAX_PW_LENGTH 8 +#define ADM_MAX_PHRASE_LENGTH 101 +#else +#define ADM_MAX_PW_LENGTH 255 +#endif + +#define CPW_SNAME ADM5_PORTNAME + +#define MAXCPWBUFSIZE 4096 + +#ifdef unicos61 +#define SIZEOF_INADDR SIZEOF_in_addr +#else +#define SIZEOF_INADDR sizeof(struct in_addr) +#endif + +/* Server */ +#define KADMIND 0x01 + +/* Applications */ +#define KPASSWD 0x01 +#define KSRVUTIL 0x02 +#define KADMIN 0x03 + +/* Operations */ +#define ADDOPER 0x01 /* Add Principal */ +#define CHGOPER 0x02 /* Change Password */ +#define ADROPER 0x03 /* Add principal with random password */ +#define CHROPER 0x04 /* Change to random password */ +#define DELOPER 0x05 /* Delete Principal */ +#define MODOPER 0x06 /* Modify Principal attributes */ +#define INQOPER 0x07 /* Display Principal info */ +#define AD4OPER 0x08 /* Add Principal using v4 string-to-key */ +#define CH4OPER 0x09 /* Change password using v4 string-to-key */ +#define COMPLETE 0x0f + +/* Extra Message Types */ +#define SENDDATA1 0x00 +#define SENDDATA2 0x01 +#define SENDDATA3 0x02 + +/* Unknowns */ +#define KUNKNOWNAPPL 0xff +#define KUNKNOWNOPER 0xff +#define KUNKNOWNERR 0xff + +typedef struct { + char appl_code; + char oper_code; + char retn_code; + char *message; +} kadmin_requests; + +static char *oper_type[] = { + "complete", /* 0 */ + "addition", /* 1 */ + "deletion", /* 2 */ + "change", /* 3 */ + "modification", /* 4 */ + "inquiry" /* 5 */ +}; + +#define SKYCHANGED 0x00 +#define NSKYRCVD 0x01 + +static char *ksrvutil_message[] = { + "Service Key Changed", /* 0 */ + "New Key and Version Received" /* 1 */ +}; + +#define KADMGOOD 0x00 +#define KADMSAG 0x01 + +static char *kadmind_general_response[] = { + "Success", /* 0 */ + "Service Access Granted" /* 1 */ +}; + + +#define KPASSGOOD 0x00 +#define KPASSBAD 0x01 + +static char *kadmind_kpasswd_response[] = { + "Password Changed", /* 0 */ + "Password NOT Changed!" /* 1 */ +}; + +#define KSRVGOOD 0x00 +#define KSRVBAD 0x01 +#define KSRVCATASTROPHE 0x02 + +static char *kadmind_ksrvutil_response[] = { + "Service Password Change Complete", /* 0 */ + "One or More Service Password Change(s) Failed!", /* 1 */ + "Database Update Failure - Possible Catastrophe!!" /* 2 */ +}; + +#define KADMGOOD 0x00 +#define KADMBAD 0x01 + +static char *kadmind_kadmin_response[] = { + "Administrative Service Completed", /* 0 */ + "Principal Unknown!", /* 1 */ + "Principal Already Exists!", /* 2 */ + "Allocation Failure!", /* 3 */ + "Password Failure!", /* 4 */ + "Protocol Failure!", /* 5 */ + "Security Failure!", /* 6 */ + "Admin Client Not in ACL List!", /* 7 */ + "Database Update Failure - Possible Catastrophe!!" /* 8 */ +}; + +#define KMODVNO 0x00 +#define KMODATTR 0x01 + +#ifdef SANDIA +#define KMODFCNT 0x02 +#endif + +#define ATTRPOST 0x00 +#define ATTRNOPOST 0x01 +#define ATTRFOR 0x02 +#define ATTRNOFOR 0x03 +#define ATTRTGT 0x04 +#define ATTRNOTGT 0x05 +#define ATTRREN 0x06 +#define ATTRNOREN 0x07 +#define ATTRPROXY 0x08 +#define ATTRNOPROXY 0x09 +#define ATTRDSKEY 0x0a +#define ATTRNODSKEY 0x0b +#define ATTRLOCK 0x0c +#define ATTRUNLOCK 0x0d + +#ifdef SANDIA +#define ATTRPRE 0x0e +#define ATTRNOPRE 0x0f +#define ATTRPWOK 0x10 +#define ATTRPWCHG 0x11 +#define ATTRSID 0x12 +#define ATTRNOSID 0x13 +#endif + +#define ATTRNOSVR 0x14 +#define ATTRSVR 0x15 + +#define BADATTR 0x3f + +#endif /* __ADM_DEFINES__ */ diff --git a/src/include/krb5/preauth.h b/src/include/krb5/preauth.h new file mode 100644 index 000000000..e36ece67d --- /dev/null +++ b/src/include/krb5/preauth.h @@ -0,0 +1,81 @@ +/* + * $Author$ + * (Originally written by Glen Machin at Sandia Labs.) + * + * Copyright 1992 by the Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America is assumed + * to require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * Sandia National Laboratories also makes no representations about the + * suitability of the modifications, or additions to this software for + * any purpose. It is provided "as is" without express or implied warranty. + * + */ + +#define MAX_PREAUTH_SIZE 20 /* Maximum size of PreAuthenticator.data */ + +/* + * Note: these typedefs are subject to change.... [tytso:19920903.1609EDT] + */ +typedef krb5_error_code (krb5_preauth_obtain_proc) + PROTOTYPE((krb5_principal client, krb5_address **src_addr, + krb5_pa_data *pa_data)); + +typedef krb5_error_code (krb5_preauth_verify_proc) + PROTOTYPE((krb5_principal client, krb5_address **src_addr, + krb5_data *data)); + +typedef struct _krb5_preauth_ops { + int type; + int flags; + krb5_preauth_obtain_proc *obtain; + krb5_preauth_verify_proc *verify; +} krb5_preauth_ops; + +/* + * Preauthentication property flags + */ +#define KRB5_PREAUTH_FLAGS_ENCRYPT 0x00000001 +#define KRB5_PREAUTH_FLAGS_HARDWARE 0x00000002 + +krb5_error_code find_preauthenticator + PROTOTYPE((int type, krb5_preauth_ops **Preauth_proc)); + +#if 0 +krb5_error_code get_random_padata + PROTOTYPE((krb5_principal client, krb5_address **src_addr, + krb5_pa_data *data)); + +krb5_error_code verify_random_padata + PROTOTYPE((krb5_principal client, krb5_address **src_addr, + krb5_data *data)); +#endif + +krb5_error_code get_timestamp_padata + PROTOTYPE((krb5_principal client, krb5_address **src_addr, + krb5_pa_data *data)); + +krb5_error_code verify_timestamp_padata + PROTOTYPE((krb5_principal client, krb5_address **src_addr, + krb5_data *data)); + +#ifdef KRBCONF_SECUREID +krb5_preauth_obtain_proc get_securid_padata; +krb5_preauth_verify_proc verify_securid_padata; +#endif + diff --git a/src/include/krb5/rsa-md5.h b/src/include/krb5/rsa-md5.h new file mode 100644 index 000000000..727818350 --- /dev/null +++ b/src/include/krb5/rsa-md5.h @@ -0,0 +1,64 @@ +/* + *********************************************************************** + ** md5.h -- header file for implementation of MD5 ** + ** RSA Data Security, Inc. MD5 Message-Digest Algorithm ** + ** Created: 2/17/90 RLR ** + ** Revised: 12/27/90 SRD,AJ,BSK,JT Reference C version ** + ** Revised (for MD5): RLR 4/27/91 ** + ** -- G modified to have y&~z instead of y&z ** + ** -- FF, GG, HH modified to add in last register done ** + ** -- Access pattern: round 2 works mod 5, round 3 works mod 3 ** + ** -- distinct additive constant for each step ** + ** -- round 4 added, working mod 7 ** + *********************************************************************** + */ + +/* + *********************************************************************** + ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. ** + ** ** + ** License to copy and use this software is granted provided that ** + ** it is identified as the "RSA Data Security, Inc. MD5 Message- ** + ** Digest Algorithm" in all material mentioning or referencing this ** + ** software or this function. ** + ** ** + ** License is also granted to make and use derivative works ** + ** provided that such works are identified as "derived from the RSA ** + ** Data Security, Inc. MD5 Message-Digest Algorithm" in all ** + ** material mentioning or referencing the derived work. ** + ** ** + ** RSA Data Security, Inc. makes no representations concerning ** + ** either the merchantability of this software or the suitability ** + ** of this software for any particular purpose. It is provided "as ** + ** is" without express or implied warranty of any kind. ** + ** ** + ** These notices must be retained in any copies of any part of this ** + ** documentation and/or software. ** + *********************************************************************** + */ + +/* Data structure for MD5 (Message-Digest) computation */ +typedef struct { + krb5_ui_4 i[2]; /* number of _bits_ handled mod 2^64 */ + krb5_ui_4 buf[4]; /* scratch buffer */ + unsigned char in[64]; /* input buffer */ + unsigned char digest[16]; /* actual digest after MD5Final call */ +} MD5_CTX; + +#if defined(__STDC__) || defined(KRB5_PROVIDE_PROTOTYPES) +extern void MD5Init(MD5_CTX *); +extern void MD5Update (MD5_CTX *, unsigned char *, unsigned int); +extern void MD5Final (MD5_CTX *); +#else +extern void MD5Init(); +extern void MD5Update (); +extern void MD5Final (); +#endif + +#define RSA_MD5_CKSUM_LENGTH 16 +#define RSA_MD5_DES_CKSUM_LENGTH 16 + +extern krb5_checksum_entry + rsa_md5_cksumtable_entry, + rsa_md5_des_cksumtable_entry; + diff --git a/src/lib/krb5/krb/preauth.c b/src/lib/krb5/krb/preauth.c new file mode 100644 index 000000000..fba6a9d44 --- /dev/null +++ b/src/lib/krb5/krb/preauth.c @@ -0,0 +1,460 @@ +/* + * $Author$ + * + * Copyright 1990,1991 by the Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America is assumed + * to require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * Sandia National Laboratories also makes no representations about the + * suitability of the modifications, or additions to this software for + * any purpose. It is provided "as is" without express or implied warranty. + * + * Note: The internal interfaces to this routine are subject to change + * and/or cleanup. You should only expect the interfaces to + * krb5_obtain_padata and krb5_verify_padata to have some chance of + * staying stable. [tytso:19920903.1544EDT] + */ + +/* + * This file contains routines for establishing, verifying, and any other + * necessary functions, for utilizing the pre-authentication field of the + * kerberos kdc request, with various hardware/software verification devices. + * + * Note: At some point these functions may very well be split apart + * into different files.... [tytso:19920903.1618EDT] + */ + +#include +#include +#include +#include +#include +#include + +#include + +static krb5_preauth_ops preauth_systems[] = { +#if 0 + { + KRB5_PADATA_ENC_RANDOM, + KRB5_PREAUTH_FLAGS_ENCRYPT, + get_random_padata, + verify_random_padata, + }, +#endif + { + KRB5_PADATA_ENC_TIMESTAMP, + KRB5_PREAUTH_FLAGS_ENCRYPT, + get_timestamp_padata, + verify_timestamp_padata, + }, +#ifdef KRBCONF_SECUREID + { + KRB5_PADATA_ENC_SECURID, + KRB5_PREAUTH_FLAGS_ENCRYPT | KRB5_PREAUTH_FLAGS_HARDWARE, + get_securid_padata, + verify_securid_padata, + }, +#endif + { -1,} +}; + +/* + * krb5_obtain_padata is a glue routine which when passed in + * a preauthentication type, client principal, and src_addr, returns + * preauthentication data contained in data to be passed onto the KDC. + * + * If problems occur then a non zero value is returned... + * + * Note: This is a first crack at what any preauthentication will need... + */ +krb5_error_code +krb5_obtain_padata(type, client, src_addr, encrypt_key, ret_data) + int type; /*IN: Preauth type */ + krb5_principal client; /*IN: requestor */ + krb5_address **src_addr; /*IN: array of ptrs to addresses */ + krb5_keyblock *encrypt_key; /*IN: encryption key */ + krb5_pa_data **ret_data; /*OUT: Returned padata */ +{ + krb5_error_code retval; + krb5_preauth_ops *p_system; + krb5_encrypt_block eblock; + krb5_data scratch; + krb5_pa_data *data; + + if (!ret_data) + return EINVAL; + *ret_data = 0; + + if (type == KRB5_PADATA_NONE ) + return(0); + + data = (krb5_pa_data *) malloc(sizeof(krb5_pa_data)); + if (!data) + return ENOMEM; + + data->length = 0; + data->contents = 0; + data->pa_type = type; + + /* Find appropriate preauthenticator */ + retval = find_preauthenticator(type, &p_system); + if (retval) + goto error_out; + + retval = (*p_system->obtain)( client, src_addr, data ); + if (retval) + goto error_out; + + /* Check to see if we need to encrypt padata */ + if (p_system->flags & KRB5_PREAUTH_FLAGS_ENCRYPT) { + /* If we dont have a encryption key we are out of luck */ + if (!encrypt_key) { + retval = KRB5_PREAUTH_NO_KEY; + goto error_out; + } + krb5_use_keytype(&eblock, encrypt_key->keytype); + + /* do any necessay key pre-processing */ + retval = krb5_process_key(&eblock, encrypt_key); + if (retval) + goto error_out; + + /* + * Set up scratch data and length for encryption + * Must allocate more space for checksum and confounder + * We also leave space for an uncrypted size field. + */ + scratch.length = krb5_encrypt_size(data->length, + eblock.crypto_entry) + 4; + + if(!(scratch.data = malloc(scratch.length))){ + (void) krb5_finish_key(&eblock); + retval = ENOMEM; + goto error_out; + } + + scratch.data[0] = data->length >> 24; + scratch.data[1] = data->length >> 16; + scratch.data[2] = data->length >> 8; + scratch.data[3] = data->length; + + /* Encrypt preauth data in encryption key */ + if (retval = krb5_encrypt((krb5_pointer) data->contents, + (char *) scratch.data + 4, + data->length, &eblock, 0)) { + (void) krb5_finish_key(&eblock); + free(scratch.data); + goto error_out; + } + (void) krb5_finish_key(&eblock); + + free(data->contents); + data->length = scratch.length; + data->contents = (unsigned char *) scratch.data; + } + + *ret_data = data; + return 0; + +error_out: + free(data); + return retval; +} + +/* + * krb5_verify_padata is a glue routine which when passed in + * the client, src_addr and padata verifies it with the appropriate + * verify function. + * + * If problems occur then a non zero value is returned... + * else returns zero if padata verifies, and returns a "unique" id. + * + * Note: This is a first crack at what any preauthentication will need... + */ + +krb5_error_code +krb5_verify_padata(data,client,src_addr, decrypt_key, req_id, flags) + krb5_pa_data *data; /*IN: padata */ + krb5_principal client; /*IN: requestor */ + krb5_address **src_addr; /*IN: array of ptrs to addresses */ + krb5_keyblock *decrypt_key; /*IN: decryption key */ + int * req_id; /*OUT: identifier */ + int * flags; /*OUT: flags */ +{ + krb5_preauth_ops *p_system; + krb5_encrypt_block eblock; + krb5_data scratch; + int free_scratch = 0; + krb5_checksum cksum; + krb5_error_code retval; + + if (!data) + return(EINVAL); + + /* Find appropriate preauthenticator */ + retval = find_preauthenticator((int) data->pa_type, &p_system); + if (retval) + return retval; + + /* Check to see if we need to decrypt padata */ + if (p_system->flags & KRB5_PREAUTH_FLAGS_ENCRYPT) { + + /* If we dont have a decryption key we are out of luck */ + if (!decrypt_key) + return(EINVAL); + + krb5_use_keytype(&eblock, decrypt_key->keytype); + + scratch.length = data->length; + if (!(scratch.data = (char *)malloc(scratch.length))) { + return(ENOMEM); + } + + /* do any necessay key pre-processing */ + retval = krb5_process_key(&eblock,decrypt_key); + if (retval) { + free(scratch.data); + return(retval); + } + + /* Decrypt data */ + retval = krb5_decrypt((char *) data->contents + 4, + (krb5_pointer) scratch.data, + scratch.length - 4, &eblock, 0); + if (retval) { + (void) krb5_finish_key(&eblock); + free(scratch.data); + return(retval); + } + + scratch.length = (((int) ((unsigned char *)data->contents)[0] << 24) + + ((int) ((unsigned char *)data->contents)[1] << 16) + + ((int) ((unsigned char *)data->contents)[2] << 8) + + (int) ((unsigned char *)data->contents)[3]); + free_scratch++; + } else { + scratch.data = (char *) data->contents; + scratch.length = data->length; + } + + retval = (*p_system->verify)(client, src_addr, &scratch); + if (free_scratch) + free(scratch.data); + if (retval) + return retval; + if (flags) + *flags = p_system->flags; + + /* Generate a request id by crc32ing the (encrypted) preauth data. */ + /* Note: The idea behind req_id is that it is dependant upon + the information in data. This could then be used for + replay detection. */ + /* MUST malloc cksum.contents */ + cksum.contents = (krb5_octet *)calloc(1, + krb5_checksum_size(CKSUMTYPE_CRC32)); + if (!cksum.contents) return(1); + + if (krb5_calculate_checksum(CKSUMTYPE_CRC32, + data->contents, + data->length, + 0, /* seed is ignored */ + 0, /* seed length is ignored */ + &cksum )) { + *req_id = 0; + } else { + /* Checksum length should be 32 bits, so truncation should never + take place */ + if ( cksum.length > sizeof(*req_id)) cksum.length = sizeof(*req_id); + + /* Offset req_id for 64 bit systems */ + memcpy((char *)req_id + (sizeof(*req_id) - cksum.length), + cksum.contents,cksum.length); + } + free(cksum.contents); + return(0); +} + +static krb5_error_code +find_preauthenticator(type, preauth) + int type; + krb5_preauth_ops **preauth; +{ + krb5_preauth_ops *ap = preauth_systems; + + while ((ap->type != -1) && (ap->type != type)) + ap++; + if (ap->type == -1) + return(KRB5_PREAUTH_BAD_TYPE); + *preauth = ap; + return 0; +} + +/* + * Format is: 8 bytes of random confounder, + * 1 byte version number (currently 0), + * 4 bytes: number of seconds since Jan 1, 1970, in MSB order. + */ +krb5_error_code +get_timestamp_padata(client, src_addr, pa_data) + krb5_principal client; + krb5_address **src_addr; + krb5_pa_data *pa_data; +{ + unsigned char *tmp; + krb5_error_code retval; + krb5_timestamp kdc_time; + int i; + + pa_data->length = 13; + tmp = pa_data->contents = (unsigned char *) malloc(pa_data->length); + if (!tmp) + return(ENOMEM); + + retval = krb5_timeofday(&kdc_time); + if (retval) + return retval; + srand(kdc_time); /* XXX NOT GOOD ENOUGH!!!! */ + + for (i=0; i < 8; i++) + *tmp++ = rand() & 255; + + *tmp++ = 0; + *tmp++ = (kdc_time >> 24) & 255; + *tmp++ = (kdc_time >> 16) & 255; + *tmp++ = (kdc_time >> 8) & 255; + *tmp++ = kdc_time & 255; + + return(0); +} + +krb5_error_code +verify_timestamp_padata(client, src_addr, data) + krb5_principal client; + krb5_address **src_addr; + krb5_data *data; +{ + unsigned char *tmp; + krb5_error_code retval; + krb5_timestamp currenttime, patime; + extern krb5_deltat krb5_clockskew; +#define in_clock_skew(date) (abs((date)-currenttime) < krb5_clockskew) + + tmp = (unsigned char *) data->data; + if (tmp[8] != 0) + return KRB5_PREAUTH_FAILED; + patime = tmp[9] << 24; + patime += tmp[10] << 16; + patime += tmp[11] << 8; + patime += tmp[12]; + + retval = krb5_timeofday(¤ttime); + if (retval) + return retval; + + if (!in_clock_skew(patime)) + return KRB5_PREAUTH_FAILED; + + return 0; +} + +#if 0 +krb5_error_code +get_random_padata(client, src_addr, pa_data) + krb5_principal client; + krb5_address **src_addr; + krb5_pa_data *pa_data; +{ + char temp[MAX_PREAUTH_SIZE]; + + srand(time(0)); + sprintf(temp, "%1u", rand() & 0x7fffffff); + pa_data->length = strlen(temp) + 1; + pa_data->contents = (unsigned char *) malloc(pa_data->length); + if (!pa_data->contents) + return(ENOMEM); + memcpy(pa_data->contents, temp, pa_data->length); + return(0); +} + +krb5_error_code +verify_random_padata(client, src_addr, data) + krb5_principal client; + krb5_address **src_addr; + krb5_data *data; +{ + if (atof(data->data) > 2147483637.0) + return KRB5_PREAUTH_FAILED; + + return 0; +} +#endif + +#ifdef SECUREID +#include "sdcli.h" +#include "sdconf.c" + +int verify_securid_padata(preauth_data) +PreAuthenticator *preauth_data; +{ + char username[255]; + struct SD_CLIENT sd; + + memset((char *)&sd,0, sizeof (sd)); + memset((char *) username, 0, sizeof(username)); + memcpy((char *) username, (char *) preauth_data->client[1]->data, + preauth_data->client[1]->length); + /* If Instance then Append */ + if (preauth_data->client[2] != '\0') { + memcpy((char *) username + preauth_data->client[1]->length, + (char *) "/", 1); + memcpy((char *) username + preauth_data->client[1]->length + 1, + (char *) preauth_data->client[2]->data, + preauth_data->client[2]->length); + } + if (sd_check( preauth_data->data,username,&sd) != ACM_OK) return(1); + return(0); +} + +static char *krb5_SecureId_prompt = "\nEnter Your SecurId Access Code Prepended with Your PIN\n (or a \'#\'if Your PIN is entered on the card keypad)\n or Type return if You Do NOT Use a SecurId Card: "; + +int get_securid_padata(preauth_data) +PreAuthenticator *preauth_data; +{ + + char temp[MAX_PREAUTH_SIZE]; + int tempsize; + int retval = 0; + + tempsize = sizeof(temp) - 1; + if (krb5_read_password(krb5_SecureId_prompt, 0, temp, &tempsize)) + return(1); + temp[tempsize] = '\0'; + + if (temp[0] == '\0') return(1); + preauth_data->datalen = strlen(temp) + 1; + preauth_data->data = (char *) calloc(1,preauth_data->datalen); + if (preauth_data->data) { + memcpy(preauth_data->data,temp,preauth_data->datalen); + retval = 0; + } + else retval = 1; + memset(temp,0,preauth_data->datalen); + return(retval); +} +#endif -- 2.26.2