convert_creds.c revision 55682
155682Smarkm/* 255682Smarkm * Copyright (c) 1997, 1999 Kungliga Tekniska H�gskolan 355682Smarkm * (Royal Institute of Technology, Stockholm, Sweden). 455682Smarkm * All rights reserved. 555682Smarkm * 655682Smarkm * Redistribution and use in source and binary forms, with or without 755682Smarkm * modification, are permitted provided that the following conditions 855682Smarkm * are met: 955682Smarkm * 1055682Smarkm * 1. Redistributions of source code must retain the above copyright 1155682Smarkm * notice, this list of conditions and the following disclaimer. 1255682Smarkm * 1355682Smarkm * 2. Redistributions in binary form must reproduce the above copyright 1455682Smarkm * notice, this list of conditions and the following disclaimer in the 1555682Smarkm * documentation and/or other materials provided with the distribution. 1655682Smarkm * 1755682Smarkm * 3. Neither the name of the Institute nor the names of its contributors 1855682Smarkm * may be used to endorse or promote products derived from this software 1955682Smarkm * without specific prior written permission. 2055682Smarkm * 2155682Smarkm * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 2255682Smarkm * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2355682Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2455682Smarkm * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 2555682Smarkm * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2655682Smarkm * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2755682Smarkm * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2855682Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2955682Smarkm * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3055682Smarkm * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3155682Smarkm * SUCH DAMAGE. 3255682Smarkm */ 3355682Smarkm 3455682Smarkm#include "krb5_locl.h" 3555682SmarkmRCSID("$Id: convert_creds.c,v 1.13 1999/12/02 17:05:08 joda Exp $"); 3655682Smarkm 3755682Smarkmstatic krb5_error_code 3855682Smarkmcheck_ticket_flags(TicketFlags f) 3955682Smarkm{ 4055682Smarkm return 0; /* maybe add some more tests here? */ 4155682Smarkm} 4255682Smarkm 4355682Smarkm/* include this here, to avoid dependencies on libkrb */ 4455682Smarkm 4555682Smarkm#define MAX_KTXT_LEN 1250 4655682Smarkm 4755682Smarkm#define ANAME_SZ 40 4855682Smarkm#define REALM_SZ 40 4955682Smarkm#define SNAME_SZ 40 5055682Smarkm#define INST_SZ 40 5155682Smarkm 5255682Smarkmstruct ktext { 5355682Smarkm unsigned int length; /* Length of the text */ 5455682Smarkm unsigned char dat[MAX_KTXT_LEN]; /* The data itself */ 5555682Smarkm u_int32_t mbz; /* zero to catch runaway strings */ 5655682Smarkm}; 5755682Smarkm 5855682Smarkmstruct credentials { 5955682Smarkm char service[ANAME_SZ]; /* Service name */ 6055682Smarkm char instance[INST_SZ]; /* Instance */ 6155682Smarkm char realm[REALM_SZ]; /* Auth domain */ 6255682Smarkm des_cblock session; /* Session key */ 6355682Smarkm int lifetime; /* Lifetime */ 6455682Smarkm int kvno; /* Key version number */ 6555682Smarkm struct ktext ticket_st; /* The ticket itself */ 6655682Smarkm int32_t issue_date; /* The issue time */ 6755682Smarkm char pname[ANAME_SZ]; /* Principal's name */ 6855682Smarkm char pinst[INST_SZ]; /* Principal's instance */ 6955682Smarkm}; 7055682Smarkm 7155682Smarkm 7255682Smarkm#define TKTLIFENUMFIXED 64 7355682Smarkm#define TKTLIFEMINFIXED 0x80 7455682Smarkm#define TKTLIFEMAXFIXED 0xBF 7555682Smarkm#define TKTLIFENOEXPIRE 0xFF 7655682Smarkm#define MAXTKTLIFETIME (30*24*3600) /* 30 days */ 7755682Smarkm#ifndef NEVERDATE 7855682Smarkm#define NEVERDATE ((time_t)0x7fffffffL) 7955682Smarkm#endif 8055682Smarkm 8155682Smarkmstatic const int _tkt_lifetimes[TKTLIFENUMFIXED] = { 8255682Smarkm 38400, 41055, 43894, 46929, 50174, 53643, 57352, 61318, 8355682Smarkm 65558, 70091, 74937, 80119, 85658, 91581, 97914, 104684, 8455682Smarkm 111922, 119661, 127935, 136781, 146239, 156350, 167161, 178720, 8555682Smarkm 191077, 204289, 218415, 233517, 249664, 266926, 285383, 305116, 8655682Smarkm 326213, 348769, 372885, 398668, 426234, 455705, 487215, 520904, 8755682Smarkm 556921, 595430, 636601, 680618, 727680, 777995, 831789, 889303, 8855682Smarkm 950794, 1016537, 1086825, 1161973, 1242318, 1328218, 1420057, 1518247, 8955682Smarkm 1623226, 1735464, 1855462, 1983758, 2120925, 2267576, 2424367, 2592000 9055682Smarkm}; 9155682Smarkm 9255682Smarkmstatic int 9355682Smarkm_krb_time_to_life(time_t start, time_t end) 9455682Smarkm{ 9555682Smarkm int i; 9655682Smarkm time_t life = end - start; 9755682Smarkm 9855682Smarkm if (life > MAXTKTLIFETIME || life <= 0) 9955682Smarkm return 0; 10055682Smarkm#if 0 10155682Smarkm if (krb_no_long_lifetimes) 10255682Smarkm return (life + 5*60 - 1)/(5*60); 10355682Smarkm#endif 10455682Smarkm 10555682Smarkm if (end >= NEVERDATE) 10655682Smarkm return TKTLIFENOEXPIRE; 10755682Smarkm if (life < _tkt_lifetimes[0]) 10855682Smarkm return (life + 5*60 - 1)/(5*60); 10955682Smarkm for (i=0; i<TKTLIFENUMFIXED; i++) 11055682Smarkm if (life <= _tkt_lifetimes[i]) 11155682Smarkm return i + TKTLIFEMINFIXED; 11255682Smarkm return 0; 11355682Smarkm 11455682Smarkm} 11555682Smarkm 11655682Smarkm/* Convert the v5 credentials in `in_cred' to v4-dito in `v4creds'. 11755682Smarkm * This is done by sending them to the 524 function in the KDC. If 11855682Smarkm * `in_cred' doesn't contain a DES session key, then a new one is 11955682Smarkm * gotten from the KDC and stored in the cred cache `ccache'. 12055682Smarkm */ 12155682Smarkm 12255682Smarkmkrb5_error_code 12355682Smarkmkrb524_convert_creds_kdc(krb5_context context, 12455682Smarkm krb5_ccache ccache, 12555682Smarkm krb5_creds *in_cred, 12655682Smarkm struct credentials *v4creds) 12755682Smarkm{ 12855682Smarkm krb5_error_code ret; 12955682Smarkm krb5_data reply; 13055682Smarkm krb5_storage *sp; 13155682Smarkm int32_t tmp; 13255682Smarkm krb5_data ticket; 13355682Smarkm char realm[REALM_SZ]; 13455682Smarkm krb5_creds *v5_creds = in_cred; 13555682Smarkm krb5_keytype keytype; 13655682Smarkm 13755682Smarkm ret = krb5_enctype_to_keytype (context, v5_creds->session.keytype, 13855682Smarkm &keytype); 13955682Smarkm if (ret) 14055682Smarkm return ret; 14155682Smarkm 14255682Smarkm if (keytype != KEYTYPE_DES) { 14355682Smarkm krb5_creds template; 14455682Smarkm 14555682Smarkm memset (&template, 0, sizeof(template)); 14655682Smarkm template.session.keytype = KEYTYPE_DES; 14755682Smarkm ret = krb5_copy_principal (context, in_cred->client, &template.client); 14855682Smarkm if (ret) { 14955682Smarkm krb5_free_creds_contents (context, &template); 15055682Smarkm return ret; 15155682Smarkm } 15255682Smarkm ret = krb5_copy_principal (context, in_cred->server, &template.server); 15355682Smarkm if (ret) { 15455682Smarkm krb5_free_creds_contents (context, &template); 15555682Smarkm return ret; 15655682Smarkm } 15755682Smarkm 15855682Smarkm ret = krb5_get_credentials (context, 0, ccache, 15955682Smarkm &template, &v5_creds); 16055682Smarkm krb5_free_creds_contents (context, &template); 16155682Smarkm if (ret) 16255682Smarkm return ret; 16355682Smarkm } 16455682Smarkm 16555682Smarkm ret = check_ticket_flags(v5_creds->flags.b); 16655682Smarkm if(ret) 16755682Smarkm goto out2; 16855682Smarkm 16955682Smarkm ret = krb5_sendto_kdc (context, 17055682Smarkm &v5_creds->ticket, 17155682Smarkm krb5_princ_realm(context, v5_creds->server), 17255682Smarkm &reply); 17355682Smarkm if (ret) 17455682Smarkm goto out2; 17555682Smarkm sp = krb5_storage_from_mem(reply.data, reply.length); 17655682Smarkm if(sp == NULL) { 17755682Smarkm ret = ENOMEM; 17855682Smarkm goto out2; 17955682Smarkm } 18055682Smarkm krb5_ret_int32(sp, &tmp); 18155682Smarkm ret = tmp; 18255682Smarkm if(ret == 0) { 18355682Smarkm memset(v4creds, 0, sizeof(*v4creds)); 18455682Smarkm ret = krb5_ret_int32(sp, &tmp); 18555682Smarkm if(ret) goto out; 18655682Smarkm v4creds->kvno = tmp; 18755682Smarkm ret = krb5_ret_data(sp, &ticket); 18855682Smarkm if(ret) goto out; 18955682Smarkm v4creds->ticket_st.length = ticket.length; 19055682Smarkm memcpy(v4creds->ticket_st.dat, ticket.data, ticket.length); 19155682Smarkm krb5_data_free(&ticket); 19255682Smarkm ret = krb5_524_conv_principal(context, 19355682Smarkm v5_creds->server, 19455682Smarkm v4creds->service, 19555682Smarkm v4creds->instance, 19655682Smarkm v4creds->realm); 19755682Smarkm if(ret) goto out; 19855682Smarkm v4creds->issue_date = v5_creds->times.authtime; 19955682Smarkm v4creds->lifetime = _krb_time_to_life(v4creds->issue_date, 20055682Smarkm v5_creds->times.endtime); 20155682Smarkm ret = krb5_524_conv_principal(context, v5_creds->client, 20255682Smarkm v4creds->pname, 20355682Smarkm v4creds->pinst, 20455682Smarkm realm); 20555682Smarkm if(ret) goto out; 20655682Smarkm memcpy(v4creds->session, v5_creds->session.keyvalue.data, 8); 20755682Smarkm } 20855682Smarkmout: 20955682Smarkm krb5_storage_free(sp); 21055682Smarkm krb5_data_free(&reply); 21155682Smarkmout2: 21255682Smarkm if (v5_creds != in_cred) 21355682Smarkm krb5_free_creds (context, v5_creds); 21455682Smarkm return ret; 21555682Smarkm} 216