1*0Sstevel@tonic-gate /* ssl/kssl.c -*- mode: C; c-file-style: "eay" -*- */ 2*0Sstevel@tonic-gate /* Written by Vern Staats <staatsvr@asc.hpc.mil> for the OpenSSL project 2000. 3*0Sstevel@tonic-gate */ 4*0Sstevel@tonic-gate /* ==================================================================== 5*0Sstevel@tonic-gate * Copyright (c) 2000 The OpenSSL Project. All rights reserved. 6*0Sstevel@tonic-gate * 7*0Sstevel@tonic-gate * Redistribution and use in source and binary forms, with or without 8*0Sstevel@tonic-gate * modification, are permitted provided that the following conditions 9*0Sstevel@tonic-gate * are met: 10*0Sstevel@tonic-gate * 11*0Sstevel@tonic-gate * 1. Redistributions of source code must retain the above copyright 12*0Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer. 13*0Sstevel@tonic-gate * 14*0Sstevel@tonic-gate * 2. Redistributions in binary form must reproduce the above copyright 15*0Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer in 16*0Sstevel@tonic-gate * the documentation and/or other materials provided with the 17*0Sstevel@tonic-gate * distribution. 18*0Sstevel@tonic-gate * 19*0Sstevel@tonic-gate * 3. All advertising materials mentioning features or use of this 20*0Sstevel@tonic-gate * software must display the following acknowledgment: 21*0Sstevel@tonic-gate * "This product includes software developed by the OpenSSL Project 22*0Sstevel@tonic-gate * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 23*0Sstevel@tonic-gate * 24*0Sstevel@tonic-gate * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 25*0Sstevel@tonic-gate * endorse or promote products derived from this software without 26*0Sstevel@tonic-gate * prior written permission. For written permission, please contact 27*0Sstevel@tonic-gate * licensing@OpenSSL.org. 28*0Sstevel@tonic-gate * 29*0Sstevel@tonic-gate * 5. Products derived from this software may not be called "OpenSSL" 30*0Sstevel@tonic-gate * nor may "OpenSSL" appear in their names without prior written 31*0Sstevel@tonic-gate * permission of the OpenSSL Project. 32*0Sstevel@tonic-gate * 33*0Sstevel@tonic-gate * 6. Redistributions of any form whatsoever must retain the following 34*0Sstevel@tonic-gate * acknowledgment: 35*0Sstevel@tonic-gate * "This product includes software developed by the OpenSSL Project 36*0Sstevel@tonic-gate * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 37*0Sstevel@tonic-gate * 38*0Sstevel@tonic-gate * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 39*0Sstevel@tonic-gate * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 40*0Sstevel@tonic-gate * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 41*0Sstevel@tonic-gate * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 42*0Sstevel@tonic-gate * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 43*0Sstevel@tonic-gate * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 44*0Sstevel@tonic-gate * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 45*0Sstevel@tonic-gate * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 46*0Sstevel@tonic-gate * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 47*0Sstevel@tonic-gate * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 48*0Sstevel@tonic-gate * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 49*0Sstevel@tonic-gate * OF THE POSSIBILITY OF SUCH DAMAGE. 50*0Sstevel@tonic-gate * ==================================================================== 51*0Sstevel@tonic-gate * 52*0Sstevel@tonic-gate * This product includes cryptographic software written by Eric Young 53*0Sstevel@tonic-gate * (eay@cryptsoft.com). This product includes software written by Tim 54*0Sstevel@tonic-gate * Hudson (tjh@cryptsoft.com). 55*0Sstevel@tonic-gate * 56*0Sstevel@tonic-gate */ 57*0Sstevel@tonic-gate 58*0Sstevel@tonic-gate 59*0Sstevel@tonic-gate /* ssl/kssl.c -- Routines to support (& debug) Kerberos5 auth for openssl 60*0Sstevel@tonic-gate ** 61*0Sstevel@tonic-gate ** 19990701 VRS Started. 62*0Sstevel@tonic-gate ** 200011?? Jeffrey Altman, Richard Levitte 63*0Sstevel@tonic-gate ** Generalized for Heimdal, Newer MIT, & Win32. 64*0Sstevel@tonic-gate ** Integrated into main OpenSSL 0.9.7 snapshots. 65*0Sstevel@tonic-gate ** 20010413 Simon Wilkinson, VRS 66*0Sstevel@tonic-gate ** Real RFC2712 KerberosWrapper replaces AP_REQ. 67*0Sstevel@tonic-gate */ 68*0Sstevel@tonic-gate 69*0Sstevel@tonic-gate #include <openssl/opensslconf.h> 70*0Sstevel@tonic-gate 71*0Sstevel@tonic-gate #define _XOPEN_SOURCE /* glibc2 needs this to declare strptime() */ 72*0Sstevel@tonic-gate #include <time.h> 73*0Sstevel@tonic-gate #undef _XOPEN_SOURCE /* To avoid clashes with anything else... */ 74*0Sstevel@tonic-gate #include <string.h> 75*0Sstevel@tonic-gate 76*0Sstevel@tonic-gate #include <openssl/ssl.h> 77*0Sstevel@tonic-gate #include <openssl/evp.h> 78*0Sstevel@tonic-gate #include <openssl/objects.h> 79*0Sstevel@tonic-gate #include <openssl/krb5_asn.h> 80*0Sstevel@tonic-gate 81*0Sstevel@tonic-gate #ifndef OPENSSL_NO_KRB5 82*0Sstevel@tonic-gate 83*0Sstevel@tonic-gate /* 84*0Sstevel@tonic-gate * When OpenSSL is built on Windows, we do not want to require that 85*0Sstevel@tonic-gate * the Kerberos DLLs be available in order for the OpenSSL DLLs to 86*0Sstevel@tonic-gate * work. Therefore, all Kerberos routines are loaded at run time 87*0Sstevel@tonic-gate * and we do not link to a .LIB file. 88*0Sstevel@tonic-gate */ 89*0Sstevel@tonic-gate 90*0Sstevel@tonic-gate #if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) 91*0Sstevel@tonic-gate /* 92*0Sstevel@tonic-gate * The purpose of the following pre-processor statements is to provide 93*0Sstevel@tonic-gate * compatibility with different releases of MIT Kerberos for Windows. 94*0Sstevel@tonic-gate * All versions up to 1.2 used macros. But macros do not allow for 95*0Sstevel@tonic-gate * a binary compatible interface for DLLs. Therefore, all macros are 96*0Sstevel@tonic-gate * being replaced by function calls. The following code will allow 97*0Sstevel@tonic-gate * an OpenSSL DLL built on Windows to work whether or not the macro 98*0Sstevel@tonic-gate * or function form of the routines are utilized. 99*0Sstevel@tonic-gate */ 100*0Sstevel@tonic-gate #ifdef krb5_cc_get_principal 101*0Sstevel@tonic-gate #define NO_DEF_KRB5_CCACHE 102*0Sstevel@tonic-gate #undef krb5_cc_get_principal 103*0Sstevel@tonic-gate #endif 104*0Sstevel@tonic-gate #define krb5_cc_get_principal kssl_krb5_cc_get_principal 105*0Sstevel@tonic-gate 106*0Sstevel@tonic-gate #define krb5_free_data_contents kssl_krb5_free_data_contents 107*0Sstevel@tonic-gate #define krb5_free_context kssl_krb5_free_context 108*0Sstevel@tonic-gate #define krb5_auth_con_free kssl_krb5_auth_con_free 109*0Sstevel@tonic-gate #define krb5_free_principal kssl_krb5_free_principal 110*0Sstevel@tonic-gate #define krb5_mk_req_extended kssl_krb5_mk_req_extended 111*0Sstevel@tonic-gate #define krb5_get_credentials kssl_krb5_get_credentials 112*0Sstevel@tonic-gate #define krb5_cc_default kssl_krb5_cc_default 113*0Sstevel@tonic-gate #define krb5_sname_to_principal kssl_krb5_sname_to_principal 114*0Sstevel@tonic-gate #define krb5_init_context kssl_krb5_init_context 115*0Sstevel@tonic-gate #define krb5_free_ticket kssl_krb5_free_ticket 116*0Sstevel@tonic-gate #define krb5_rd_req kssl_krb5_rd_req 117*0Sstevel@tonic-gate #define krb5_kt_default kssl_krb5_kt_default 118*0Sstevel@tonic-gate #define krb5_kt_resolve kssl_krb5_kt_resolve 119*0Sstevel@tonic-gate /* macros in mit 1.2.2 and earlier; functions in mit 1.2.3 and greater */ 120*0Sstevel@tonic-gate #ifndef krb5_kt_close 121*0Sstevel@tonic-gate #define krb5_kt_close kssl_krb5_kt_close 122*0Sstevel@tonic-gate #endif /* krb5_kt_close */ 123*0Sstevel@tonic-gate #ifndef krb5_kt_get_entry 124*0Sstevel@tonic-gate #define krb5_kt_get_entry kssl_krb5_kt_get_entry 125*0Sstevel@tonic-gate #endif /* krb5_kt_get_entry */ 126*0Sstevel@tonic-gate #define krb5_auth_con_init kssl_krb5_auth_con_init 127*0Sstevel@tonic-gate 128*0Sstevel@tonic-gate #define krb5_principal_compare kssl_krb5_principal_compare 129*0Sstevel@tonic-gate #define krb5_decrypt_tkt_part kssl_krb5_decrypt_tkt_part 130*0Sstevel@tonic-gate #define krb5_timeofday kssl_krb5_timeofday 131*0Sstevel@tonic-gate #define krb5_rc_default kssl_krb5_rc_default 132*0Sstevel@tonic-gate 133*0Sstevel@tonic-gate #ifdef krb5_rc_initialize 134*0Sstevel@tonic-gate #undef krb5_rc_initialize 135*0Sstevel@tonic-gate #endif 136*0Sstevel@tonic-gate #define krb5_rc_initialize kssl_krb5_rc_initialize 137*0Sstevel@tonic-gate 138*0Sstevel@tonic-gate #ifdef krb5_rc_get_lifespan 139*0Sstevel@tonic-gate #undef krb5_rc_get_lifespan 140*0Sstevel@tonic-gate #endif 141*0Sstevel@tonic-gate #define krb5_rc_get_lifespan kssl_krb5_rc_get_lifespan 142*0Sstevel@tonic-gate 143*0Sstevel@tonic-gate #ifdef krb5_rc_destroy 144*0Sstevel@tonic-gate #undef krb5_rc_destroy 145*0Sstevel@tonic-gate #endif 146*0Sstevel@tonic-gate #define krb5_rc_destroy kssl_krb5_rc_destroy 147*0Sstevel@tonic-gate 148*0Sstevel@tonic-gate #define valid_cksumtype kssl_valid_cksumtype 149*0Sstevel@tonic-gate #define krb5_checksum_size kssl_krb5_checksum_size 150*0Sstevel@tonic-gate #define krb5_kt_free_entry kssl_krb5_kt_free_entry 151*0Sstevel@tonic-gate #define krb5_auth_con_setrcache kssl_krb5_auth_con_setrcache 152*0Sstevel@tonic-gate #define krb5_auth_con_getrcache kssl_krb5_auth_con_getrcache 153*0Sstevel@tonic-gate #define krb5_get_server_rcache kssl_krb5_get_server_rcache 154*0Sstevel@tonic-gate 155*0Sstevel@tonic-gate /* Prototypes for built in stubs */ 156*0Sstevel@tonic-gate void kssl_krb5_free_data_contents(krb5_context, krb5_data *); 157*0Sstevel@tonic-gate void kssl_krb5_free_principal(krb5_context, krb5_principal ); 158*0Sstevel@tonic-gate krb5_error_code kssl_krb5_kt_resolve(krb5_context, 159*0Sstevel@tonic-gate krb5_const char *, 160*0Sstevel@tonic-gate krb5_keytab *); 161*0Sstevel@tonic-gate krb5_error_code kssl_krb5_kt_default(krb5_context, 162*0Sstevel@tonic-gate krb5_keytab *); 163*0Sstevel@tonic-gate krb5_error_code kssl_krb5_free_ticket(krb5_context, krb5_ticket *); 164*0Sstevel@tonic-gate krb5_error_code kssl_krb5_rd_req(krb5_context, krb5_auth_context *, 165*0Sstevel@tonic-gate krb5_const krb5_data *, 166*0Sstevel@tonic-gate krb5_const_principal, krb5_keytab, 167*0Sstevel@tonic-gate krb5_flags *,krb5_ticket **); 168*0Sstevel@tonic-gate 169*0Sstevel@tonic-gate krb5_boolean kssl_krb5_principal_compare(krb5_context, krb5_const_principal, 170*0Sstevel@tonic-gate krb5_const_principal); 171*0Sstevel@tonic-gate krb5_error_code kssl_krb5_mk_req_extended(krb5_context, 172*0Sstevel@tonic-gate krb5_auth_context *, 173*0Sstevel@tonic-gate krb5_const krb5_flags, 174*0Sstevel@tonic-gate krb5_data *, 175*0Sstevel@tonic-gate krb5_creds *, 176*0Sstevel@tonic-gate krb5_data * ); 177*0Sstevel@tonic-gate krb5_error_code kssl_krb5_init_context(krb5_context *); 178*0Sstevel@tonic-gate void kssl_krb5_free_context(krb5_context); 179*0Sstevel@tonic-gate krb5_error_code kssl_krb5_cc_default(krb5_context,krb5_ccache *); 180*0Sstevel@tonic-gate krb5_error_code kssl_krb5_sname_to_principal(krb5_context, 181*0Sstevel@tonic-gate krb5_const char *, 182*0Sstevel@tonic-gate krb5_const char *, 183*0Sstevel@tonic-gate krb5_int32, 184*0Sstevel@tonic-gate krb5_principal *); 185*0Sstevel@tonic-gate krb5_error_code kssl_krb5_get_credentials(krb5_context, 186*0Sstevel@tonic-gate krb5_const krb5_flags, 187*0Sstevel@tonic-gate krb5_ccache, 188*0Sstevel@tonic-gate krb5_creds *, 189*0Sstevel@tonic-gate krb5_creds * *); 190*0Sstevel@tonic-gate krb5_error_code kssl_krb5_auth_con_init(krb5_context, 191*0Sstevel@tonic-gate krb5_auth_context *); 192*0Sstevel@tonic-gate krb5_error_code kssl_krb5_cc_get_principal(krb5_context context, 193*0Sstevel@tonic-gate krb5_ccache cache, 194*0Sstevel@tonic-gate krb5_principal *principal); 195*0Sstevel@tonic-gate krb5_error_code kssl_krb5_auth_con_free(krb5_context,krb5_auth_context); 196*0Sstevel@tonic-gate size_t kssl_krb5_checksum_size(krb5_context context,krb5_cksumtype ctype); 197*0Sstevel@tonic-gate krb5_boolean kssl_valid_cksumtype(krb5_cksumtype ctype); 198*0Sstevel@tonic-gate krb5_error_code krb5_kt_free_entry(krb5_context,krb5_keytab_entry FAR * ); 199*0Sstevel@tonic-gate krb5_error_code kssl_krb5_auth_con_setrcache(krb5_context, 200*0Sstevel@tonic-gate krb5_auth_context, 201*0Sstevel@tonic-gate krb5_rcache); 202*0Sstevel@tonic-gate krb5_error_code kssl_krb5_get_server_rcache(krb5_context, 203*0Sstevel@tonic-gate krb5_const krb5_data *, 204*0Sstevel@tonic-gate krb5_rcache *); 205*0Sstevel@tonic-gate krb5_error_code kssl_krb5_auth_con_getrcache(krb5_context, 206*0Sstevel@tonic-gate krb5_auth_context, 207*0Sstevel@tonic-gate krb5_rcache *); 208*0Sstevel@tonic-gate 209*0Sstevel@tonic-gate /* Function pointers (almost all Kerberos functions are _stdcall) */ 210*0Sstevel@tonic-gate static void (_stdcall *p_krb5_free_data_contents)(krb5_context, krb5_data *) 211*0Sstevel@tonic-gate =NULL; 212*0Sstevel@tonic-gate static void (_stdcall *p_krb5_free_principal)(krb5_context, krb5_principal ) 213*0Sstevel@tonic-gate =NULL; 214*0Sstevel@tonic-gate static krb5_error_code(_stdcall *p_krb5_kt_resolve) 215*0Sstevel@tonic-gate (krb5_context, krb5_const char *, krb5_keytab *)=NULL; 216*0Sstevel@tonic-gate static krb5_error_code (_stdcall *p_krb5_kt_default)(krb5_context, 217*0Sstevel@tonic-gate krb5_keytab *)=NULL; 218*0Sstevel@tonic-gate static krb5_error_code (_stdcall *p_krb5_free_ticket)(krb5_context, 219*0Sstevel@tonic-gate krb5_ticket *)=NULL; 220*0Sstevel@tonic-gate static krb5_error_code (_stdcall *p_krb5_rd_req)(krb5_context, 221*0Sstevel@tonic-gate krb5_auth_context *, 222*0Sstevel@tonic-gate krb5_const krb5_data *, 223*0Sstevel@tonic-gate krb5_const_principal, 224*0Sstevel@tonic-gate krb5_keytab, krb5_flags *, 225*0Sstevel@tonic-gate krb5_ticket **)=NULL; 226*0Sstevel@tonic-gate static krb5_error_code (_stdcall *p_krb5_mk_req_extended) 227*0Sstevel@tonic-gate (krb5_context, krb5_auth_context *, 228*0Sstevel@tonic-gate krb5_const krb5_flags, krb5_data *, krb5_creds *, 229*0Sstevel@tonic-gate krb5_data * )=NULL; 230*0Sstevel@tonic-gate static krb5_error_code (_stdcall *p_krb5_init_context)(krb5_context *)=NULL; 231*0Sstevel@tonic-gate static void (_stdcall *p_krb5_free_context)(krb5_context)=NULL; 232*0Sstevel@tonic-gate static krb5_error_code (_stdcall *p_krb5_cc_default)(krb5_context, 233*0Sstevel@tonic-gate krb5_ccache *)=NULL; 234*0Sstevel@tonic-gate static krb5_error_code (_stdcall *p_krb5_sname_to_principal) 235*0Sstevel@tonic-gate (krb5_context, krb5_const char *, krb5_const char *, 236*0Sstevel@tonic-gate krb5_int32, krb5_principal *)=NULL; 237*0Sstevel@tonic-gate static krb5_error_code (_stdcall *p_krb5_get_credentials) 238*0Sstevel@tonic-gate (krb5_context, krb5_const krb5_flags, krb5_ccache, 239*0Sstevel@tonic-gate krb5_creds *, krb5_creds **)=NULL; 240*0Sstevel@tonic-gate static krb5_error_code (_stdcall *p_krb5_auth_con_init) 241*0Sstevel@tonic-gate (krb5_context, krb5_auth_context *)=NULL; 242*0Sstevel@tonic-gate static krb5_error_code (_stdcall *p_krb5_cc_get_principal) 243*0Sstevel@tonic-gate (krb5_context context, krb5_ccache cache, 244*0Sstevel@tonic-gate krb5_principal *principal)=NULL; 245*0Sstevel@tonic-gate static krb5_error_code (_stdcall *p_krb5_auth_con_free) 246*0Sstevel@tonic-gate (krb5_context, krb5_auth_context)=NULL; 247*0Sstevel@tonic-gate static krb5_error_code (_stdcall *p_krb5_decrypt_tkt_part) 248*0Sstevel@tonic-gate (krb5_context, krb5_const krb5_keyblock *, 249*0Sstevel@tonic-gate krb5_ticket *)=NULL; 250*0Sstevel@tonic-gate static krb5_error_code (_stdcall *p_krb5_timeofday) 251*0Sstevel@tonic-gate (krb5_context context, krb5_int32 *timeret)=NULL; 252*0Sstevel@tonic-gate static krb5_error_code (_stdcall *p_krb5_rc_default) 253*0Sstevel@tonic-gate (krb5_context context, krb5_rcache *rc)=NULL; 254*0Sstevel@tonic-gate static krb5_error_code (_stdcall *p_krb5_rc_initialize) 255*0Sstevel@tonic-gate (krb5_context context, krb5_rcache rc, 256*0Sstevel@tonic-gate krb5_deltat lifespan)=NULL; 257*0Sstevel@tonic-gate static krb5_error_code (_stdcall *p_krb5_rc_get_lifespan) 258*0Sstevel@tonic-gate (krb5_context context, krb5_rcache rc, 259*0Sstevel@tonic-gate krb5_deltat *lifespan)=NULL; 260*0Sstevel@tonic-gate static krb5_error_code (_stdcall *p_krb5_rc_destroy) 261*0Sstevel@tonic-gate (krb5_context context, krb5_rcache rc)=NULL; 262*0Sstevel@tonic-gate static krb5_boolean (_stdcall *p_krb5_principal_compare) 263*0Sstevel@tonic-gate (krb5_context, krb5_const_principal, krb5_const_principal)=NULL; 264*0Sstevel@tonic-gate static size_t (_stdcall *p_krb5_checksum_size)(krb5_context context,krb5_cksumtype ctype)=NULL; 265*0Sstevel@tonic-gate static krb5_boolean (_stdcall *p_valid_cksumtype)(krb5_cksumtype ctype)=NULL; 266*0Sstevel@tonic-gate static krb5_error_code (_stdcall *p_krb5_kt_free_entry) 267*0Sstevel@tonic-gate (krb5_context,krb5_keytab_entry * )=NULL; 268*0Sstevel@tonic-gate static krb5_error_code (_stdcall * p_krb5_auth_con_setrcache)(krb5_context, 269*0Sstevel@tonic-gate krb5_auth_context, 270*0Sstevel@tonic-gate krb5_rcache)=NULL; 271*0Sstevel@tonic-gate static krb5_error_code (_stdcall * p_krb5_get_server_rcache)(krb5_context, 272*0Sstevel@tonic-gate krb5_const krb5_data *, 273*0Sstevel@tonic-gate krb5_rcache *)=NULL; 274*0Sstevel@tonic-gate static krb5_error_code (* p_krb5_auth_con_getrcache)(krb5_context, 275*0Sstevel@tonic-gate krb5_auth_context, 276*0Sstevel@tonic-gate krb5_rcache *)=NULL; 277*0Sstevel@tonic-gate static krb5_error_code (_stdcall * p_krb5_kt_close)(krb5_context context, 278*0Sstevel@tonic-gate krb5_keytab keytab)=NULL; 279*0Sstevel@tonic-gate static krb5_error_code (_stdcall * p_krb5_kt_get_entry)(krb5_context context, 280*0Sstevel@tonic-gate krb5_keytab keytab, 281*0Sstevel@tonic-gate krb5_const_principal principal, krb5_kvno vno, 282*0Sstevel@tonic-gate krb5_enctype enctype, krb5_keytab_entry *entry)=NULL; 283*0Sstevel@tonic-gate static int krb5_loaded = 0; /* only attempt to initialize func ptrs once */ 284*0Sstevel@tonic-gate 285*0Sstevel@tonic-gate /* Function to Load the Kerberos 5 DLL and initialize function pointers */ 286*0Sstevel@tonic-gate void 287*0Sstevel@tonic-gate load_krb5_dll(void) 288*0Sstevel@tonic-gate { 289*0Sstevel@tonic-gate HANDLE hKRB5_32; 290*0Sstevel@tonic-gate 291*0Sstevel@tonic-gate krb5_loaded++; 292*0Sstevel@tonic-gate hKRB5_32 = LoadLibrary("KRB5_32"); 293*0Sstevel@tonic-gate if (!hKRB5_32) 294*0Sstevel@tonic-gate return; 295*0Sstevel@tonic-gate 296*0Sstevel@tonic-gate (FARPROC) p_krb5_free_data_contents = 297*0Sstevel@tonic-gate GetProcAddress( hKRB5_32, "krb5_free_data_contents" ); 298*0Sstevel@tonic-gate (FARPROC) p_krb5_free_context = 299*0Sstevel@tonic-gate GetProcAddress( hKRB5_32, "krb5_free_context" ); 300*0Sstevel@tonic-gate (FARPROC) p_krb5_auth_con_free = 301*0Sstevel@tonic-gate GetProcAddress( hKRB5_32, "krb5_auth_con_free" ); 302*0Sstevel@tonic-gate (FARPROC) p_krb5_free_principal = 303*0Sstevel@tonic-gate GetProcAddress( hKRB5_32, "krb5_free_principal" ); 304*0Sstevel@tonic-gate (FARPROC) p_krb5_mk_req_extended = 305*0Sstevel@tonic-gate GetProcAddress( hKRB5_32, "krb5_mk_req_extended" ); 306*0Sstevel@tonic-gate (FARPROC) p_krb5_get_credentials = 307*0Sstevel@tonic-gate GetProcAddress( hKRB5_32, "krb5_get_credentials" ); 308*0Sstevel@tonic-gate (FARPROC) p_krb5_cc_get_principal = 309*0Sstevel@tonic-gate GetProcAddress( hKRB5_32, "krb5_cc_get_principal" ); 310*0Sstevel@tonic-gate (FARPROC) p_krb5_cc_default = 311*0Sstevel@tonic-gate GetProcAddress( hKRB5_32, "krb5_cc_default" ); 312*0Sstevel@tonic-gate (FARPROC) p_krb5_sname_to_principal = 313*0Sstevel@tonic-gate GetProcAddress( hKRB5_32, "krb5_sname_to_principal" ); 314*0Sstevel@tonic-gate (FARPROC) p_krb5_init_context = 315*0Sstevel@tonic-gate GetProcAddress( hKRB5_32, "krb5_init_context" ); 316*0Sstevel@tonic-gate (FARPROC) p_krb5_free_ticket = 317*0Sstevel@tonic-gate GetProcAddress( hKRB5_32, "krb5_free_ticket" ); 318*0Sstevel@tonic-gate (FARPROC) p_krb5_rd_req = 319*0Sstevel@tonic-gate GetProcAddress( hKRB5_32, "krb5_rd_req" ); 320*0Sstevel@tonic-gate (FARPROC) p_krb5_principal_compare = 321*0Sstevel@tonic-gate GetProcAddress( hKRB5_32, "krb5_principal_compare" ); 322*0Sstevel@tonic-gate (FARPROC) p_krb5_decrypt_tkt_part = 323*0Sstevel@tonic-gate GetProcAddress( hKRB5_32, "krb5_decrypt_tkt_part" ); 324*0Sstevel@tonic-gate (FARPROC) p_krb5_timeofday = 325*0Sstevel@tonic-gate GetProcAddress( hKRB5_32, "krb5_timeofday" ); 326*0Sstevel@tonic-gate (FARPROC) p_krb5_rc_default = 327*0Sstevel@tonic-gate GetProcAddress( hKRB5_32, "krb5_rc_default" ); 328*0Sstevel@tonic-gate (FARPROC) p_krb5_rc_initialize = 329*0Sstevel@tonic-gate GetProcAddress( hKRB5_32, "krb5_rc_initialize" ); 330*0Sstevel@tonic-gate (FARPROC) p_krb5_rc_get_lifespan = 331*0Sstevel@tonic-gate GetProcAddress( hKRB5_32, "krb5_rc_get_lifespan" ); 332*0Sstevel@tonic-gate (FARPROC) p_krb5_rc_destroy = 333*0Sstevel@tonic-gate GetProcAddress( hKRB5_32, "krb5_rc_destroy" ); 334*0Sstevel@tonic-gate (FARPROC) p_krb5_kt_default = 335*0Sstevel@tonic-gate GetProcAddress( hKRB5_32, "krb5_kt_default" ); 336*0Sstevel@tonic-gate (FARPROC) p_krb5_kt_resolve = 337*0Sstevel@tonic-gate GetProcAddress( hKRB5_32, "krb5_kt_resolve" ); 338*0Sstevel@tonic-gate (FARPROC) p_krb5_auth_con_init = 339*0Sstevel@tonic-gate GetProcAddress( hKRB5_32, "krb5_auth_con_init" ); 340*0Sstevel@tonic-gate (FARPROC) p_valid_cksumtype = 341*0Sstevel@tonic-gate GetProcAddress( hKRB5_32, "valid_cksumtype" ); 342*0Sstevel@tonic-gate (FARPROC) p_krb5_checksum_size = 343*0Sstevel@tonic-gate GetProcAddress( hKRB5_32, "krb5_checksum_size" ); 344*0Sstevel@tonic-gate (FARPROC) p_krb5_kt_free_entry = 345*0Sstevel@tonic-gate GetProcAddress( hKRB5_32, "krb5_kt_free_entry" ); 346*0Sstevel@tonic-gate (FARPROC) p_krb5_auth_con_setrcache = 347*0Sstevel@tonic-gate GetProcAddress( hKRB5_32, "krb5_auth_con_setrcache" ); 348*0Sstevel@tonic-gate (FARPROC) p_krb5_get_server_rcache = 349*0Sstevel@tonic-gate GetProcAddress( hKRB5_32, "krb5_get_server_rcache" ); 350*0Sstevel@tonic-gate (FARPROC) p_krb5_auth_con_getrcache = 351*0Sstevel@tonic-gate GetProcAddress( hKRB5_32, "krb5_auth_con_getrcache" ); 352*0Sstevel@tonic-gate (FARPROC) p_krb5_kt_close = 353*0Sstevel@tonic-gate GetProcAddress( hKRB5_32, "krb5_kt_close" ); 354*0Sstevel@tonic-gate (FARPROC) p_krb5_kt_get_entry = 355*0Sstevel@tonic-gate GetProcAddress( hKRB5_32, "krb5_kt_get_entry" ); 356*0Sstevel@tonic-gate } 357*0Sstevel@tonic-gate 358*0Sstevel@tonic-gate /* Stubs for each function to be dynamicly loaded */ 359*0Sstevel@tonic-gate void 360*0Sstevel@tonic-gate kssl_krb5_free_data_contents(krb5_context CO, krb5_data * data) 361*0Sstevel@tonic-gate { 362*0Sstevel@tonic-gate if (!krb5_loaded) 363*0Sstevel@tonic-gate load_krb5_dll(); 364*0Sstevel@tonic-gate 365*0Sstevel@tonic-gate if ( p_krb5_free_data_contents ) 366*0Sstevel@tonic-gate p_krb5_free_data_contents(CO,data); 367*0Sstevel@tonic-gate } 368*0Sstevel@tonic-gate 369*0Sstevel@tonic-gate krb5_error_code 370*0Sstevel@tonic-gate kssl_krb5_mk_req_extended (krb5_context CO, 371*0Sstevel@tonic-gate krb5_auth_context * pACO, 372*0Sstevel@tonic-gate krb5_const krb5_flags F, 373*0Sstevel@tonic-gate krb5_data * pD1, 374*0Sstevel@tonic-gate krb5_creds * pC, 375*0Sstevel@tonic-gate krb5_data * pD2) 376*0Sstevel@tonic-gate { 377*0Sstevel@tonic-gate if (!krb5_loaded) 378*0Sstevel@tonic-gate load_krb5_dll(); 379*0Sstevel@tonic-gate 380*0Sstevel@tonic-gate if ( p_krb5_mk_req_extended ) 381*0Sstevel@tonic-gate return(p_krb5_mk_req_extended(CO,pACO,F,pD1,pC,pD2)); 382*0Sstevel@tonic-gate else 383*0Sstevel@tonic-gate return KRB5KRB_ERR_GENERIC; 384*0Sstevel@tonic-gate } 385*0Sstevel@tonic-gate krb5_error_code 386*0Sstevel@tonic-gate kssl_krb5_auth_con_init(krb5_context CO, 387*0Sstevel@tonic-gate krb5_auth_context * pACO) 388*0Sstevel@tonic-gate { 389*0Sstevel@tonic-gate if (!krb5_loaded) 390*0Sstevel@tonic-gate load_krb5_dll(); 391*0Sstevel@tonic-gate 392*0Sstevel@tonic-gate if ( p_krb5_auth_con_init ) 393*0Sstevel@tonic-gate return(p_krb5_auth_con_init(CO,pACO)); 394*0Sstevel@tonic-gate else 395*0Sstevel@tonic-gate return KRB5KRB_ERR_GENERIC; 396*0Sstevel@tonic-gate } 397*0Sstevel@tonic-gate krb5_error_code 398*0Sstevel@tonic-gate kssl_krb5_auth_con_free (krb5_context CO, 399*0Sstevel@tonic-gate krb5_auth_context ACO) 400*0Sstevel@tonic-gate { 401*0Sstevel@tonic-gate if (!krb5_loaded) 402*0Sstevel@tonic-gate load_krb5_dll(); 403*0Sstevel@tonic-gate 404*0Sstevel@tonic-gate if ( p_krb5_auth_con_free ) 405*0Sstevel@tonic-gate return(p_krb5_auth_con_free(CO,ACO)); 406*0Sstevel@tonic-gate else 407*0Sstevel@tonic-gate return KRB5KRB_ERR_GENERIC; 408*0Sstevel@tonic-gate } 409*0Sstevel@tonic-gate krb5_error_code 410*0Sstevel@tonic-gate kssl_krb5_get_credentials(krb5_context CO, 411*0Sstevel@tonic-gate krb5_const krb5_flags F, 412*0Sstevel@tonic-gate krb5_ccache CC, 413*0Sstevel@tonic-gate krb5_creds * pCR, 414*0Sstevel@tonic-gate krb5_creds ** ppCR) 415*0Sstevel@tonic-gate { 416*0Sstevel@tonic-gate if (!krb5_loaded) 417*0Sstevel@tonic-gate load_krb5_dll(); 418*0Sstevel@tonic-gate 419*0Sstevel@tonic-gate if ( p_krb5_get_credentials ) 420*0Sstevel@tonic-gate return(p_krb5_get_credentials(CO,F,CC,pCR,ppCR)); 421*0Sstevel@tonic-gate else 422*0Sstevel@tonic-gate return KRB5KRB_ERR_GENERIC; 423*0Sstevel@tonic-gate } 424*0Sstevel@tonic-gate krb5_error_code 425*0Sstevel@tonic-gate kssl_krb5_sname_to_principal(krb5_context CO, 426*0Sstevel@tonic-gate krb5_const char * pC1, 427*0Sstevel@tonic-gate krb5_const char * pC2, 428*0Sstevel@tonic-gate krb5_int32 I, 429*0Sstevel@tonic-gate krb5_principal * pPR) 430*0Sstevel@tonic-gate { 431*0Sstevel@tonic-gate if (!krb5_loaded) 432*0Sstevel@tonic-gate load_krb5_dll(); 433*0Sstevel@tonic-gate 434*0Sstevel@tonic-gate if ( p_krb5_sname_to_principal ) 435*0Sstevel@tonic-gate return(p_krb5_sname_to_principal(CO,pC1,pC2,I,pPR)); 436*0Sstevel@tonic-gate else 437*0Sstevel@tonic-gate return KRB5KRB_ERR_GENERIC; 438*0Sstevel@tonic-gate } 439*0Sstevel@tonic-gate 440*0Sstevel@tonic-gate krb5_error_code 441*0Sstevel@tonic-gate kssl_krb5_cc_default(krb5_context CO, 442*0Sstevel@tonic-gate krb5_ccache * pCC) 443*0Sstevel@tonic-gate { 444*0Sstevel@tonic-gate if (!krb5_loaded) 445*0Sstevel@tonic-gate load_krb5_dll(); 446*0Sstevel@tonic-gate 447*0Sstevel@tonic-gate if ( p_krb5_cc_default ) 448*0Sstevel@tonic-gate return(p_krb5_cc_default(CO,pCC)); 449*0Sstevel@tonic-gate else 450*0Sstevel@tonic-gate return KRB5KRB_ERR_GENERIC; 451*0Sstevel@tonic-gate } 452*0Sstevel@tonic-gate 453*0Sstevel@tonic-gate krb5_error_code 454*0Sstevel@tonic-gate kssl_krb5_init_context(krb5_context * pCO) 455*0Sstevel@tonic-gate { 456*0Sstevel@tonic-gate if (!krb5_loaded) 457*0Sstevel@tonic-gate load_krb5_dll(); 458*0Sstevel@tonic-gate 459*0Sstevel@tonic-gate if ( p_krb5_init_context ) 460*0Sstevel@tonic-gate return(p_krb5_init_context(pCO)); 461*0Sstevel@tonic-gate else 462*0Sstevel@tonic-gate return KRB5KRB_ERR_GENERIC; 463*0Sstevel@tonic-gate } 464*0Sstevel@tonic-gate 465*0Sstevel@tonic-gate void 466*0Sstevel@tonic-gate kssl_krb5_free_context(krb5_context CO) 467*0Sstevel@tonic-gate { 468*0Sstevel@tonic-gate if (!krb5_loaded) 469*0Sstevel@tonic-gate load_krb5_dll(); 470*0Sstevel@tonic-gate 471*0Sstevel@tonic-gate if ( p_krb5_free_context ) 472*0Sstevel@tonic-gate p_krb5_free_context(CO); 473*0Sstevel@tonic-gate } 474*0Sstevel@tonic-gate 475*0Sstevel@tonic-gate void 476*0Sstevel@tonic-gate kssl_krb5_free_principal(krb5_context c, krb5_principal p) 477*0Sstevel@tonic-gate { 478*0Sstevel@tonic-gate if (!krb5_loaded) 479*0Sstevel@tonic-gate load_krb5_dll(); 480*0Sstevel@tonic-gate 481*0Sstevel@tonic-gate if ( p_krb5_free_principal ) 482*0Sstevel@tonic-gate p_krb5_free_principal(c,p); 483*0Sstevel@tonic-gate } 484*0Sstevel@tonic-gate 485*0Sstevel@tonic-gate krb5_error_code 486*0Sstevel@tonic-gate kssl_krb5_kt_resolve(krb5_context con, 487*0Sstevel@tonic-gate krb5_const char * sz, 488*0Sstevel@tonic-gate krb5_keytab * kt) 489*0Sstevel@tonic-gate { 490*0Sstevel@tonic-gate if (!krb5_loaded) 491*0Sstevel@tonic-gate load_krb5_dll(); 492*0Sstevel@tonic-gate 493*0Sstevel@tonic-gate if ( p_krb5_kt_resolve ) 494*0Sstevel@tonic-gate return(p_krb5_kt_resolve(con,sz,kt)); 495*0Sstevel@tonic-gate else 496*0Sstevel@tonic-gate return KRB5KRB_ERR_GENERIC; 497*0Sstevel@tonic-gate } 498*0Sstevel@tonic-gate 499*0Sstevel@tonic-gate krb5_error_code 500*0Sstevel@tonic-gate kssl_krb5_kt_default(krb5_context con, 501*0Sstevel@tonic-gate krb5_keytab * kt) 502*0Sstevel@tonic-gate { 503*0Sstevel@tonic-gate if (!krb5_loaded) 504*0Sstevel@tonic-gate load_krb5_dll(); 505*0Sstevel@tonic-gate 506*0Sstevel@tonic-gate if ( p_krb5_kt_default ) 507*0Sstevel@tonic-gate return(p_krb5_kt_default(con,kt)); 508*0Sstevel@tonic-gate else 509*0Sstevel@tonic-gate return KRB5KRB_ERR_GENERIC; 510*0Sstevel@tonic-gate } 511*0Sstevel@tonic-gate 512*0Sstevel@tonic-gate krb5_error_code 513*0Sstevel@tonic-gate kssl_krb5_free_ticket(krb5_context con, 514*0Sstevel@tonic-gate krb5_ticket * kt) 515*0Sstevel@tonic-gate { 516*0Sstevel@tonic-gate if (!krb5_loaded) 517*0Sstevel@tonic-gate load_krb5_dll(); 518*0Sstevel@tonic-gate 519*0Sstevel@tonic-gate if ( p_krb5_free_ticket ) 520*0Sstevel@tonic-gate return(p_krb5_free_ticket(con,kt)); 521*0Sstevel@tonic-gate else 522*0Sstevel@tonic-gate return KRB5KRB_ERR_GENERIC; 523*0Sstevel@tonic-gate } 524*0Sstevel@tonic-gate 525*0Sstevel@tonic-gate krb5_error_code 526*0Sstevel@tonic-gate kssl_krb5_rd_req(krb5_context con, krb5_auth_context * pacon, 527*0Sstevel@tonic-gate krb5_const krb5_data * data, 528*0Sstevel@tonic-gate krb5_const_principal princ, krb5_keytab keytab, 529*0Sstevel@tonic-gate krb5_flags * flags, krb5_ticket ** pptkt) 530*0Sstevel@tonic-gate { 531*0Sstevel@tonic-gate if (!krb5_loaded) 532*0Sstevel@tonic-gate load_krb5_dll(); 533*0Sstevel@tonic-gate 534*0Sstevel@tonic-gate if ( p_krb5_rd_req ) 535*0Sstevel@tonic-gate return(p_krb5_rd_req(con,pacon,data,princ,keytab,flags,pptkt)); 536*0Sstevel@tonic-gate else 537*0Sstevel@tonic-gate return KRB5KRB_ERR_GENERIC; 538*0Sstevel@tonic-gate } 539*0Sstevel@tonic-gate 540*0Sstevel@tonic-gate krb5_boolean 541*0Sstevel@tonic-gate krb5_principal_compare(krb5_context con, krb5_const_principal princ1, 542*0Sstevel@tonic-gate krb5_const_principal princ2) 543*0Sstevel@tonic-gate { 544*0Sstevel@tonic-gate if (!krb5_loaded) 545*0Sstevel@tonic-gate load_krb5_dll(); 546*0Sstevel@tonic-gate 547*0Sstevel@tonic-gate if ( p_krb5_principal_compare ) 548*0Sstevel@tonic-gate return(p_krb5_principal_compare(con,princ1,princ2)); 549*0Sstevel@tonic-gate else 550*0Sstevel@tonic-gate return KRB5KRB_ERR_GENERIC; 551*0Sstevel@tonic-gate } 552*0Sstevel@tonic-gate 553*0Sstevel@tonic-gate krb5_error_code 554*0Sstevel@tonic-gate krb5_decrypt_tkt_part(krb5_context con, krb5_const krb5_keyblock *keys, 555*0Sstevel@tonic-gate krb5_ticket *ticket) 556*0Sstevel@tonic-gate { 557*0Sstevel@tonic-gate if (!krb5_loaded) 558*0Sstevel@tonic-gate load_krb5_dll(); 559*0Sstevel@tonic-gate 560*0Sstevel@tonic-gate if ( p_krb5_decrypt_tkt_part ) 561*0Sstevel@tonic-gate return(p_krb5_decrypt_tkt_part(con,keys,ticket)); 562*0Sstevel@tonic-gate else 563*0Sstevel@tonic-gate return KRB5KRB_ERR_GENERIC; 564*0Sstevel@tonic-gate } 565*0Sstevel@tonic-gate 566*0Sstevel@tonic-gate krb5_error_code 567*0Sstevel@tonic-gate krb5_timeofday(krb5_context con, krb5_int32 *timeret) 568*0Sstevel@tonic-gate { 569*0Sstevel@tonic-gate if (!krb5_loaded) 570*0Sstevel@tonic-gate load_krb5_dll(); 571*0Sstevel@tonic-gate 572*0Sstevel@tonic-gate if ( p_krb5_timeofday ) 573*0Sstevel@tonic-gate return(p_krb5_timeofday(con,timeret)); 574*0Sstevel@tonic-gate else 575*0Sstevel@tonic-gate return KRB5KRB_ERR_GENERIC; 576*0Sstevel@tonic-gate } 577*0Sstevel@tonic-gate 578*0Sstevel@tonic-gate krb5_error_code 579*0Sstevel@tonic-gate krb5_rc_default(krb5_context con, krb5_rcache *rc) 580*0Sstevel@tonic-gate { 581*0Sstevel@tonic-gate if (!krb5_loaded) 582*0Sstevel@tonic-gate load_krb5_dll(); 583*0Sstevel@tonic-gate 584*0Sstevel@tonic-gate if ( p_krb5_rc_default ) 585*0Sstevel@tonic-gate return(p_krb5_rc_default(con,rc)); 586*0Sstevel@tonic-gate else 587*0Sstevel@tonic-gate return KRB5KRB_ERR_GENERIC; 588*0Sstevel@tonic-gate } 589*0Sstevel@tonic-gate 590*0Sstevel@tonic-gate krb5_error_code 591*0Sstevel@tonic-gate krb5_rc_initialize(krb5_context con, krb5_rcache rc, krb5_deltat lifespan) 592*0Sstevel@tonic-gate { 593*0Sstevel@tonic-gate if (!krb5_loaded) 594*0Sstevel@tonic-gate load_krb5_dll(); 595*0Sstevel@tonic-gate 596*0Sstevel@tonic-gate if ( p_krb5_rc_initialize ) 597*0Sstevel@tonic-gate return(p_krb5_rc_initialize(con, rc, lifespan)); 598*0Sstevel@tonic-gate else 599*0Sstevel@tonic-gate return KRB5KRB_ERR_GENERIC; 600*0Sstevel@tonic-gate } 601*0Sstevel@tonic-gate 602*0Sstevel@tonic-gate krb5_error_code 603*0Sstevel@tonic-gate krb5_rc_get_lifespan(krb5_context con, krb5_rcache rc, krb5_deltat *lifespanp) 604*0Sstevel@tonic-gate { 605*0Sstevel@tonic-gate if (!krb5_loaded) 606*0Sstevel@tonic-gate load_krb5_dll(); 607*0Sstevel@tonic-gate 608*0Sstevel@tonic-gate if ( p_krb5_rc_get_lifespan ) 609*0Sstevel@tonic-gate return(p_krb5_rc_get_lifespan(con, rc, lifespanp)); 610*0Sstevel@tonic-gate else 611*0Sstevel@tonic-gate return KRB5KRB_ERR_GENERIC; 612*0Sstevel@tonic-gate } 613*0Sstevel@tonic-gate 614*0Sstevel@tonic-gate krb5_error_code 615*0Sstevel@tonic-gate krb5_rc_destroy(krb5_context con, krb5_rcache rc) 616*0Sstevel@tonic-gate { 617*0Sstevel@tonic-gate if (!krb5_loaded) 618*0Sstevel@tonic-gate load_krb5_dll(); 619*0Sstevel@tonic-gate 620*0Sstevel@tonic-gate if ( p_krb5_rc_destroy ) 621*0Sstevel@tonic-gate return(p_krb5_rc_destroy(con, rc)); 622*0Sstevel@tonic-gate else 623*0Sstevel@tonic-gate return KRB5KRB_ERR_GENERIC; 624*0Sstevel@tonic-gate } 625*0Sstevel@tonic-gate 626*0Sstevel@tonic-gate size_t 627*0Sstevel@tonic-gate krb5_checksum_size(krb5_context context,krb5_cksumtype ctype) 628*0Sstevel@tonic-gate { 629*0Sstevel@tonic-gate if (!krb5_loaded) 630*0Sstevel@tonic-gate load_krb5_dll(); 631*0Sstevel@tonic-gate 632*0Sstevel@tonic-gate if ( p_krb5_checksum_size ) 633*0Sstevel@tonic-gate return(p_krb5_checksum_size(context, ctype)); 634*0Sstevel@tonic-gate else 635*0Sstevel@tonic-gate return KRB5KRB_ERR_GENERIC; 636*0Sstevel@tonic-gate } 637*0Sstevel@tonic-gate 638*0Sstevel@tonic-gate krb5_boolean 639*0Sstevel@tonic-gate valid_cksumtype(krb5_cksumtype ctype) 640*0Sstevel@tonic-gate { 641*0Sstevel@tonic-gate if (!krb5_loaded) 642*0Sstevel@tonic-gate load_krb5_dll(); 643*0Sstevel@tonic-gate 644*0Sstevel@tonic-gate if ( p_valid_cksumtype ) 645*0Sstevel@tonic-gate return(p_valid_cksumtype(ctype)); 646*0Sstevel@tonic-gate else 647*0Sstevel@tonic-gate return KRB5KRB_ERR_GENERIC; 648*0Sstevel@tonic-gate } 649*0Sstevel@tonic-gate 650*0Sstevel@tonic-gate krb5_error_code 651*0Sstevel@tonic-gate krb5_kt_free_entry(krb5_context con,krb5_keytab_entry * entry) 652*0Sstevel@tonic-gate { 653*0Sstevel@tonic-gate if (!krb5_loaded) 654*0Sstevel@tonic-gate load_krb5_dll(); 655*0Sstevel@tonic-gate 656*0Sstevel@tonic-gate if ( p_krb5_kt_free_entry ) 657*0Sstevel@tonic-gate return(p_krb5_kt_free_entry(con,entry)); 658*0Sstevel@tonic-gate else 659*0Sstevel@tonic-gate return KRB5KRB_ERR_GENERIC; 660*0Sstevel@tonic-gate } 661*0Sstevel@tonic-gate 662*0Sstevel@tonic-gate /* Structure definitions */ 663*0Sstevel@tonic-gate #ifndef NO_DEF_KRB5_CCACHE 664*0Sstevel@tonic-gate #ifndef krb5_x 665*0Sstevel@tonic-gate #define krb5_x(ptr,args) ((ptr)?((*(ptr)) args):(abort(),1)) 666*0Sstevel@tonic-gate #define krb5_xc(ptr,args) ((ptr)?((*(ptr)) args):(abort(),(char*)0)) 667*0Sstevel@tonic-gate #endif 668*0Sstevel@tonic-gate 669*0Sstevel@tonic-gate typedef krb5_pointer krb5_cc_cursor; /* cursor for sequential lookup */ 670*0Sstevel@tonic-gate 671*0Sstevel@tonic-gate typedef struct _krb5_ccache 672*0Sstevel@tonic-gate { 673*0Sstevel@tonic-gate krb5_magic magic; 674*0Sstevel@tonic-gate struct _krb5_cc_ops FAR *ops; 675*0Sstevel@tonic-gate krb5_pointer data; 676*0Sstevel@tonic-gate } *krb5_ccache; 677*0Sstevel@tonic-gate 678*0Sstevel@tonic-gate typedef struct _krb5_cc_ops 679*0Sstevel@tonic-gate { 680*0Sstevel@tonic-gate krb5_magic magic; 681*0Sstevel@tonic-gate char *prefix; 682*0Sstevel@tonic-gate char * (KRB5_CALLCONV *get_name) 683*0Sstevel@tonic-gate (krb5_context, krb5_ccache); 684*0Sstevel@tonic-gate krb5_error_code (KRB5_CALLCONV *resolve) 685*0Sstevel@tonic-gate (krb5_context, krb5_ccache *, const char *); 686*0Sstevel@tonic-gate krb5_error_code (KRB5_CALLCONV *gen_new) 687*0Sstevel@tonic-gate (krb5_context, krb5_ccache *); 688*0Sstevel@tonic-gate krb5_error_code (KRB5_CALLCONV *init) 689*0Sstevel@tonic-gate (krb5_context, krb5_ccache, krb5_principal); 690*0Sstevel@tonic-gate krb5_error_code (KRB5_CALLCONV *destroy) 691*0Sstevel@tonic-gate (krb5_context, krb5_ccache); 692*0Sstevel@tonic-gate krb5_error_code (KRB5_CALLCONV *close) 693*0Sstevel@tonic-gate (krb5_context, krb5_ccache); 694*0Sstevel@tonic-gate krb5_error_code (KRB5_CALLCONV *store) 695*0Sstevel@tonic-gate (krb5_context, krb5_ccache, krb5_creds *); 696*0Sstevel@tonic-gate krb5_error_code (KRB5_CALLCONV *retrieve) 697*0Sstevel@tonic-gate (krb5_context, krb5_ccache, 698*0Sstevel@tonic-gate krb5_flags, krb5_creds *, krb5_creds *); 699*0Sstevel@tonic-gate krb5_error_code (KRB5_CALLCONV *get_princ) 700*0Sstevel@tonic-gate (krb5_context, krb5_ccache, krb5_principal *); 701*0Sstevel@tonic-gate krb5_error_code (KRB5_CALLCONV *get_first) 702*0Sstevel@tonic-gate (krb5_context, krb5_ccache, krb5_cc_cursor *); 703*0Sstevel@tonic-gate krb5_error_code (KRB5_CALLCONV *get_next) 704*0Sstevel@tonic-gate (krb5_context, krb5_ccache, 705*0Sstevel@tonic-gate krb5_cc_cursor *, krb5_creds *); 706*0Sstevel@tonic-gate krb5_error_code (KRB5_CALLCONV *end_get) 707*0Sstevel@tonic-gate (krb5_context, krb5_ccache, krb5_cc_cursor *); 708*0Sstevel@tonic-gate krb5_error_code (KRB5_CALLCONV *remove_cred) 709*0Sstevel@tonic-gate (krb5_context, krb5_ccache, 710*0Sstevel@tonic-gate krb5_flags, krb5_creds *); 711*0Sstevel@tonic-gate krb5_error_code (KRB5_CALLCONV *set_flags) 712*0Sstevel@tonic-gate (krb5_context, krb5_ccache, krb5_flags); 713*0Sstevel@tonic-gate } krb5_cc_ops; 714*0Sstevel@tonic-gate #endif /* NO_DEF_KRB5_CCACHE */ 715*0Sstevel@tonic-gate 716*0Sstevel@tonic-gate krb5_error_code 717*0Sstevel@tonic-gate kssl_krb5_cc_get_principal 718*0Sstevel@tonic-gate (krb5_context context, krb5_ccache cache, 719*0Sstevel@tonic-gate krb5_principal *principal) 720*0Sstevel@tonic-gate { 721*0Sstevel@tonic-gate if ( p_krb5_cc_get_principal ) 722*0Sstevel@tonic-gate return(p_krb5_cc_get_principal(context,cache,principal)); 723*0Sstevel@tonic-gate else 724*0Sstevel@tonic-gate return(krb5_x 725*0Sstevel@tonic-gate ((cache)->ops->get_princ,(context, cache, principal))); 726*0Sstevel@tonic-gate } 727*0Sstevel@tonic-gate 728*0Sstevel@tonic-gate krb5_error_code 729*0Sstevel@tonic-gate kssl_krb5_auth_con_setrcache(krb5_context con, krb5_auth_context acon, 730*0Sstevel@tonic-gate krb5_rcache rcache) 731*0Sstevel@tonic-gate { 732*0Sstevel@tonic-gate if ( p_krb5_auth_con_setrcache ) 733*0Sstevel@tonic-gate return(p_krb5_auth_con_setrcache(con,acon,rcache)); 734*0Sstevel@tonic-gate else 735*0Sstevel@tonic-gate return KRB5KRB_ERR_GENERIC; 736*0Sstevel@tonic-gate } 737*0Sstevel@tonic-gate 738*0Sstevel@tonic-gate krb5_error_code 739*0Sstevel@tonic-gate kssl_krb5_get_server_rcache(krb5_context con, krb5_const krb5_data * data, 740*0Sstevel@tonic-gate krb5_rcache * rcache) 741*0Sstevel@tonic-gate { 742*0Sstevel@tonic-gate if ( p_krb5_get_server_rcache ) 743*0Sstevel@tonic-gate return(p_krb5_get_server_rcache(con,data,rcache)); 744*0Sstevel@tonic-gate else 745*0Sstevel@tonic-gate return KRB5KRB_ERR_GENERIC; 746*0Sstevel@tonic-gate } 747*0Sstevel@tonic-gate 748*0Sstevel@tonic-gate krb5_error_code 749*0Sstevel@tonic-gate kssl_krb5_auth_con_getrcache(krb5_context con, krb5_auth_context acon, 750*0Sstevel@tonic-gate krb5_rcache * prcache) 751*0Sstevel@tonic-gate { 752*0Sstevel@tonic-gate if ( p_krb5_auth_con_getrcache ) 753*0Sstevel@tonic-gate return(p_krb5_auth_con_getrcache(con,acon, prcache)); 754*0Sstevel@tonic-gate else 755*0Sstevel@tonic-gate return KRB5KRB_ERR_GENERIC; 756*0Sstevel@tonic-gate } 757*0Sstevel@tonic-gate 758*0Sstevel@tonic-gate krb5_error_code 759*0Sstevel@tonic-gate kssl_krb5_kt_close(krb5_context context, krb5_keytab keytab) 760*0Sstevel@tonic-gate { 761*0Sstevel@tonic-gate if ( p_krb5_kt_close ) 762*0Sstevel@tonic-gate return(p_krb5_kt_close(context,keytab)); 763*0Sstevel@tonic-gate else 764*0Sstevel@tonic-gate return KRB5KRB_ERR_GENERIC; 765*0Sstevel@tonic-gate } 766*0Sstevel@tonic-gate 767*0Sstevel@tonic-gate krb5_error_code 768*0Sstevel@tonic-gate kssl_krb5_kt_get_entry(krb5_context context, krb5_keytab keytab, 769*0Sstevel@tonic-gate krb5_const_principal principal, krb5_kvno vno, 770*0Sstevel@tonic-gate krb5_enctype enctype, krb5_keytab_entry *entry) 771*0Sstevel@tonic-gate { 772*0Sstevel@tonic-gate if ( p_krb5_kt_get_entry ) 773*0Sstevel@tonic-gate return(p_krb5_kt_get_entry(context,keytab,principal,vno,enctype,entry)); 774*0Sstevel@tonic-gate else 775*0Sstevel@tonic-gate return KRB5KRB_ERR_GENERIC; 776*0Sstevel@tonic-gate } 777*0Sstevel@tonic-gate #endif /* OPENSSL_SYS_WINDOWS || OPENSSL_SYS_WIN32 */ 778*0Sstevel@tonic-gate 779*0Sstevel@tonic-gate char 780*0Sstevel@tonic-gate *kstring(char *string) 781*0Sstevel@tonic-gate { 782*0Sstevel@tonic-gate static char *null = "[NULL]"; 783*0Sstevel@tonic-gate 784*0Sstevel@tonic-gate return ((string == NULL)? null: string); 785*0Sstevel@tonic-gate } 786*0Sstevel@tonic-gate 787*0Sstevel@tonic-gate /* Given KRB5 enctype (basically DES or 3DES), 788*0Sstevel@tonic-gate ** return closest match openssl EVP_ encryption algorithm. 789*0Sstevel@tonic-gate ** Return NULL for unknown or problematic (krb5_dk_encrypt) enctypes. 790*0Sstevel@tonic-gate ** Assume ENCTYPE_*_RAW (krb5_raw_encrypt) are OK. 791*0Sstevel@tonic-gate */ 792*0Sstevel@tonic-gate const EVP_CIPHER * 793*0Sstevel@tonic-gate kssl_map_enc(krb5_enctype enctype) 794*0Sstevel@tonic-gate { 795*0Sstevel@tonic-gate switch (enctype) 796*0Sstevel@tonic-gate { 797*0Sstevel@tonic-gate case ENCTYPE_DES_HMAC_SHA1: /* EVP_des_cbc(); */ 798*0Sstevel@tonic-gate case ENCTYPE_DES_CBC_CRC: 799*0Sstevel@tonic-gate case ENCTYPE_DES_CBC_MD4: 800*0Sstevel@tonic-gate case ENCTYPE_DES_CBC_MD5: 801*0Sstevel@tonic-gate case ENCTYPE_DES_CBC_RAW: 802*0Sstevel@tonic-gate return EVP_des_cbc(); 803*0Sstevel@tonic-gate break; 804*0Sstevel@tonic-gate case ENCTYPE_DES3_CBC_SHA1: /* EVP_des_ede3_cbc(); */ 805*0Sstevel@tonic-gate case ENCTYPE_DES3_CBC_SHA: 806*0Sstevel@tonic-gate case ENCTYPE_DES3_CBC_RAW: 807*0Sstevel@tonic-gate return EVP_des_ede3_cbc(); 808*0Sstevel@tonic-gate break; 809*0Sstevel@tonic-gate default: return NULL; 810*0Sstevel@tonic-gate break; 811*0Sstevel@tonic-gate } 812*0Sstevel@tonic-gate } 813*0Sstevel@tonic-gate 814*0Sstevel@tonic-gate 815*0Sstevel@tonic-gate /* Return true:1 if p "looks like" the start of the real authenticator 816*0Sstevel@tonic-gate ** described in kssl_skip_confound() below. The ASN.1 pattern is 817*0Sstevel@tonic-gate ** "62 xx 30 yy" (APPLICATION-2, SEQUENCE), where xx-yy =~ 2, and 818*0Sstevel@tonic-gate ** xx and yy are possibly multi-byte length fields. 819*0Sstevel@tonic-gate */ 820*0Sstevel@tonic-gate int kssl_test_confound(unsigned char *p) 821*0Sstevel@tonic-gate { 822*0Sstevel@tonic-gate int len = 2; 823*0Sstevel@tonic-gate int xx = 0, yy = 0; 824*0Sstevel@tonic-gate 825*0Sstevel@tonic-gate if (*p++ != 0x62) return 0; 826*0Sstevel@tonic-gate if (*p > 0x82) return 0; 827*0Sstevel@tonic-gate switch(*p) { 828*0Sstevel@tonic-gate case 0x82: p++; xx = (*p++ << 8); xx += *p++; break; 829*0Sstevel@tonic-gate case 0x81: p++; xx = *p++; break; 830*0Sstevel@tonic-gate case 0x80: return 0; 831*0Sstevel@tonic-gate default: xx = *p++; break; 832*0Sstevel@tonic-gate } 833*0Sstevel@tonic-gate if (*p++ != 0x30) return 0; 834*0Sstevel@tonic-gate if (*p > 0x82) return 0; 835*0Sstevel@tonic-gate switch(*p) { 836*0Sstevel@tonic-gate case 0x82: p++; len+=2; yy = (*p++ << 8); yy += *p++; break; 837*0Sstevel@tonic-gate case 0x81: p++; len++; yy = *p++; break; 838*0Sstevel@tonic-gate case 0x80: return 0; 839*0Sstevel@tonic-gate default: yy = *p++; break; 840*0Sstevel@tonic-gate } 841*0Sstevel@tonic-gate 842*0Sstevel@tonic-gate return (xx - len == yy)? 1: 0; 843*0Sstevel@tonic-gate } 844*0Sstevel@tonic-gate 845*0Sstevel@tonic-gate /* Allocate, fill, and return cksumlens array of checksum lengths. 846*0Sstevel@tonic-gate ** This array holds just the unique elements from the krb5_cksumarray[]. 847*0Sstevel@tonic-gate ** array[n] == 0 signals end of data. 848*0Sstevel@tonic-gate ** 849*0Sstevel@tonic-gate ** The krb5_cksumarray[] was an internal variable that has since been 850*0Sstevel@tonic-gate ** replaced by a more general method for storing the data. It should 851*0Sstevel@tonic-gate ** not be used. Instead we use real API calls and make a guess for 852*0Sstevel@tonic-gate ** what the highest assigned CKSUMTYPE_ constant is. As of 1.2.2 853*0Sstevel@tonic-gate ** it is 0x000c (CKSUMTYPE_HMAC_SHA1_DES3). So we will use 0x0010. 854*0Sstevel@tonic-gate */ 855*0Sstevel@tonic-gate size_t *populate_cksumlens(void) 856*0Sstevel@tonic-gate { 857*0Sstevel@tonic-gate int i, j, n; 858*0Sstevel@tonic-gate static size_t *cklens = NULL; 859*0Sstevel@tonic-gate 860*0Sstevel@tonic-gate #ifdef KRB5_MIT_OLD11 861*0Sstevel@tonic-gate n = krb5_max_cksum; 862*0Sstevel@tonic-gate #else 863*0Sstevel@tonic-gate n = 0x0010; 864*0Sstevel@tonic-gate #endif /* KRB5_MIT_OLD11 */ 865*0Sstevel@tonic-gate 866*0Sstevel@tonic-gate #ifdef KRB5CHECKAUTH 867*0Sstevel@tonic-gate if (!cklens && !(cklens = (size_t *) calloc(sizeof(int),n+1))) return NULL; 868*0Sstevel@tonic-gate 869*0Sstevel@tonic-gate for (i=0; i < n; i++) { 870*0Sstevel@tonic-gate if (!valid_cksumtype(i)) continue; /* array has holes */ 871*0Sstevel@tonic-gate for (j=0; j < n; j++) { 872*0Sstevel@tonic-gate if (cklens[j] == 0) { 873*0Sstevel@tonic-gate cklens[j] = krb5_checksum_size(NULL,i); 874*0Sstevel@tonic-gate break; /* krb5 elem was new: add */ 875*0Sstevel@tonic-gate } 876*0Sstevel@tonic-gate if (cklens[j] == krb5_checksum_size(NULL,i)) { 877*0Sstevel@tonic-gate break; /* ignore duplicate elements */ 878*0Sstevel@tonic-gate } 879*0Sstevel@tonic-gate } 880*0Sstevel@tonic-gate } 881*0Sstevel@tonic-gate #endif /* KRB5CHECKAUTH */ 882*0Sstevel@tonic-gate 883*0Sstevel@tonic-gate return cklens; 884*0Sstevel@tonic-gate } 885*0Sstevel@tonic-gate 886*0Sstevel@tonic-gate /* Return pointer to start of real authenticator within authenticator, or 887*0Sstevel@tonic-gate ** return NULL on error. 888*0Sstevel@tonic-gate ** Decrypted authenticator looks like this: 889*0Sstevel@tonic-gate ** [0 or 8 byte confounder] [4-24 byte checksum] [real authent'r] 890*0Sstevel@tonic-gate ** This hackery wouldn't be necessary if MIT KRB5 1.0.6 had the 891*0Sstevel@tonic-gate ** krb5_auth_con_getcksumtype() function advertised in its krb5.h. 892*0Sstevel@tonic-gate */ 893*0Sstevel@tonic-gate unsigned char *kssl_skip_confound(krb5_enctype etype, unsigned char *a) 894*0Sstevel@tonic-gate { 895*0Sstevel@tonic-gate int i, conlen; 896*0Sstevel@tonic-gate size_t cklen; 897*0Sstevel@tonic-gate static size_t *cksumlens = NULL; 898*0Sstevel@tonic-gate unsigned char *test_auth; 899*0Sstevel@tonic-gate 900*0Sstevel@tonic-gate conlen = (etype)? 8: 0; 901*0Sstevel@tonic-gate 902*0Sstevel@tonic-gate if (!cksumlens && !(cksumlens = populate_cksumlens())) return NULL; 903*0Sstevel@tonic-gate for (i=0; (cklen = cksumlens[i]) != 0; i++) 904*0Sstevel@tonic-gate { 905*0Sstevel@tonic-gate test_auth = a + conlen + cklen; 906*0Sstevel@tonic-gate if (kssl_test_confound(test_auth)) return test_auth; 907*0Sstevel@tonic-gate } 908*0Sstevel@tonic-gate 909*0Sstevel@tonic-gate return NULL; 910*0Sstevel@tonic-gate } 911*0Sstevel@tonic-gate 912*0Sstevel@tonic-gate 913*0Sstevel@tonic-gate /* Set kssl_err error info when reason text is a simple string 914*0Sstevel@tonic-gate ** kssl_err = struct { int reason; char text[KSSL_ERR_MAX+1]; } 915*0Sstevel@tonic-gate */ 916*0Sstevel@tonic-gate void 917*0Sstevel@tonic-gate kssl_err_set(KSSL_ERR *kssl_err, int reason, char *text) 918*0Sstevel@tonic-gate { 919*0Sstevel@tonic-gate if (kssl_err == NULL) return; 920*0Sstevel@tonic-gate 921*0Sstevel@tonic-gate kssl_err->reason = reason; 922*0Sstevel@tonic-gate BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, text); 923*0Sstevel@tonic-gate return; 924*0Sstevel@tonic-gate } 925*0Sstevel@tonic-gate 926*0Sstevel@tonic-gate 927*0Sstevel@tonic-gate /* Display contents of krb5_data struct, for debugging 928*0Sstevel@tonic-gate */ 929*0Sstevel@tonic-gate void 930*0Sstevel@tonic-gate print_krb5_data(char *label, krb5_data *kdata) 931*0Sstevel@tonic-gate { 932*0Sstevel@tonic-gate int i; 933*0Sstevel@tonic-gate 934*0Sstevel@tonic-gate printf("%s[%d] ", label, kdata->length); 935*0Sstevel@tonic-gate for (i=0; i < kdata->length; i++) 936*0Sstevel@tonic-gate { 937*0Sstevel@tonic-gate if (0 && isprint((int) kdata->data[i])) 938*0Sstevel@tonic-gate printf( "%c ", kdata->data[i]); 939*0Sstevel@tonic-gate else 940*0Sstevel@tonic-gate printf( "%02x ", (unsigned char) kdata->data[i]); 941*0Sstevel@tonic-gate } 942*0Sstevel@tonic-gate printf("\n"); 943*0Sstevel@tonic-gate } 944*0Sstevel@tonic-gate 945*0Sstevel@tonic-gate 946*0Sstevel@tonic-gate /* Display contents of krb5_authdata struct, for debugging 947*0Sstevel@tonic-gate */ 948*0Sstevel@tonic-gate void 949*0Sstevel@tonic-gate print_krb5_authdata(char *label, krb5_authdata **adata) 950*0Sstevel@tonic-gate { 951*0Sstevel@tonic-gate if (adata == NULL) 952*0Sstevel@tonic-gate { 953*0Sstevel@tonic-gate printf("%s, authdata==0\n", label); 954*0Sstevel@tonic-gate return; 955*0Sstevel@tonic-gate } 956*0Sstevel@tonic-gate printf("%s [%p]\n", label, (void *)adata); 957*0Sstevel@tonic-gate #if 0 958*0Sstevel@tonic-gate { 959*0Sstevel@tonic-gate int i; 960*0Sstevel@tonic-gate printf("%s[at%d:%d] ", label, adata->ad_type, adata->length); 961*0Sstevel@tonic-gate for (i=0; i < adata->length; i++) 962*0Sstevel@tonic-gate { 963*0Sstevel@tonic-gate printf((isprint(adata->contents[i]))? "%c ": "%02x", 964*0Sstevel@tonic-gate adata->contents[i]); 965*0Sstevel@tonic-gate } 966*0Sstevel@tonic-gate printf("\n"); 967*0Sstevel@tonic-gate } 968*0Sstevel@tonic-gate #endif 969*0Sstevel@tonic-gate } 970*0Sstevel@tonic-gate 971*0Sstevel@tonic-gate 972*0Sstevel@tonic-gate /* Display contents of krb5_keyblock struct, for debugging 973*0Sstevel@tonic-gate */ 974*0Sstevel@tonic-gate void 975*0Sstevel@tonic-gate print_krb5_keyblock(char *label, krb5_keyblock *keyblk) 976*0Sstevel@tonic-gate { 977*0Sstevel@tonic-gate int i; 978*0Sstevel@tonic-gate 979*0Sstevel@tonic-gate if (keyblk == NULL) 980*0Sstevel@tonic-gate { 981*0Sstevel@tonic-gate printf("%s, keyblk==0\n", label); 982*0Sstevel@tonic-gate return; 983*0Sstevel@tonic-gate } 984*0Sstevel@tonic-gate #ifdef KRB5_HEIMDAL 985*0Sstevel@tonic-gate printf("%s\n\t[et%d:%d]: ", label, keyblk->keytype, 986*0Sstevel@tonic-gate keyblk->keyvalue->length); 987*0Sstevel@tonic-gate for (i=0; i < keyblk->keyvalue->length; i++) 988*0Sstevel@tonic-gate { 989*0Sstevel@tonic-gate printf("%02x",(unsigned char *)(keyblk->keyvalue->contents)[i]); 990*0Sstevel@tonic-gate } 991*0Sstevel@tonic-gate printf("\n"); 992*0Sstevel@tonic-gate #else 993*0Sstevel@tonic-gate printf("%s\n\t[et%d:%d]: ", label, keyblk->enctype, keyblk->length); 994*0Sstevel@tonic-gate for (i=0; i < keyblk->length; i++) 995*0Sstevel@tonic-gate { 996*0Sstevel@tonic-gate printf("%02x",keyblk->contents[i]); 997*0Sstevel@tonic-gate } 998*0Sstevel@tonic-gate printf("\n"); 999*0Sstevel@tonic-gate #endif 1000*0Sstevel@tonic-gate } 1001*0Sstevel@tonic-gate 1002*0Sstevel@tonic-gate 1003*0Sstevel@tonic-gate /* Display contents of krb5_principal_data struct, for debugging 1004*0Sstevel@tonic-gate ** (krb5_principal is typedef'd == krb5_principal_data *) 1005*0Sstevel@tonic-gate */ 1006*0Sstevel@tonic-gate void 1007*0Sstevel@tonic-gate print_krb5_princ(char *label, krb5_principal_data *princ) 1008*0Sstevel@tonic-gate { 1009*0Sstevel@tonic-gate int i, ui, uj; 1010*0Sstevel@tonic-gate 1011*0Sstevel@tonic-gate printf("%s principal Realm: ", label); 1012*0Sstevel@tonic-gate if (princ == NULL) return; 1013*0Sstevel@tonic-gate for (ui=0; ui < princ->realm.length; ui++) putchar(princ->realm.data[ui]); 1014*0Sstevel@tonic-gate printf(" (nametype %d) has %d strings:\n", princ->type,princ->length); 1015*0Sstevel@tonic-gate for (i=0; i < princ->length; i++) 1016*0Sstevel@tonic-gate { 1017*0Sstevel@tonic-gate printf("\t%d [%d]: ", i, princ->data[i].length); 1018*0Sstevel@tonic-gate for (uj=0; uj < princ->data[i].length; uj++) { 1019*0Sstevel@tonic-gate putchar(princ->data[i].data[uj]); 1020*0Sstevel@tonic-gate } 1021*0Sstevel@tonic-gate printf("\n"); 1022*0Sstevel@tonic-gate } 1023*0Sstevel@tonic-gate return; 1024*0Sstevel@tonic-gate } 1025*0Sstevel@tonic-gate 1026*0Sstevel@tonic-gate 1027*0Sstevel@tonic-gate /* Given krb5 service (typically "kssl") and hostname in kssl_ctx, 1028*0Sstevel@tonic-gate ** Return encrypted Kerberos ticket for service @ hostname. 1029*0Sstevel@tonic-gate ** If authenp is non-NULL, also return encrypted authenticator, 1030*0Sstevel@tonic-gate ** whose data should be freed by caller. 1031*0Sstevel@tonic-gate ** (Originally was: Create Kerberos AP_REQ message for SSL Client.) 1032*0Sstevel@tonic-gate ** 1033*0Sstevel@tonic-gate ** 19990628 VRS Started; Returns Kerberos AP_REQ message. 1034*0Sstevel@tonic-gate ** 20010409 VRS Modified for RFC2712; Returns enc tkt. 1035*0Sstevel@tonic-gate ** 20010606 VRS May also return optional authenticator. 1036*0Sstevel@tonic-gate */ 1037*0Sstevel@tonic-gate krb5_error_code 1038*0Sstevel@tonic-gate kssl_cget_tkt( /* UPDATE */ KSSL_CTX *kssl_ctx, 1039*0Sstevel@tonic-gate /* OUT */ krb5_data **enc_ticketp, 1040*0Sstevel@tonic-gate /* UPDATE */ krb5_data *authenp, 1041*0Sstevel@tonic-gate /* OUT */ KSSL_ERR *kssl_err) 1042*0Sstevel@tonic-gate { 1043*0Sstevel@tonic-gate krb5_error_code krb5rc = KRB5KRB_ERR_GENERIC; 1044*0Sstevel@tonic-gate krb5_context krb5context = NULL; 1045*0Sstevel@tonic-gate krb5_auth_context krb5auth_context = NULL; 1046*0Sstevel@tonic-gate krb5_ccache krb5ccdef = NULL; 1047*0Sstevel@tonic-gate krb5_creds krb5creds, *krb5credsp = NULL; 1048*0Sstevel@tonic-gate krb5_data krb5_app_req; 1049*0Sstevel@tonic-gate 1050*0Sstevel@tonic-gate kssl_err_set(kssl_err, 0, ""); 1051*0Sstevel@tonic-gate memset((char *)&krb5creds, 0, sizeof(krb5creds)); 1052*0Sstevel@tonic-gate 1053*0Sstevel@tonic-gate if (!kssl_ctx) 1054*0Sstevel@tonic-gate { 1055*0Sstevel@tonic-gate kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, 1056*0Sstevel@tonic-gate "No kssl_ctx defined.\n"); 1057*0Sstevel@tonic-gate goto err; 1058*0Sstevel@tonic-gate } 1059*0Sstevel@tonic-gate else if (!kssl_ctx->service_host) 1060*0Sstevel@tonic-gate { 1061*0Sstevel@tonic-gate kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, 1062*0Sstevel@tonic-gate "kssl_ctx service_host undefined.\n"); 1063*0Sstevel@tonic-gate goto err; 1064*0Sstevel@tonic-gate } 1065*0Sstevel@tonic-gate 1066*0Sstevel@tonic-gate if ((krb5rc = krb5_init_context(&krb5context)) != 0) 1067*0Sstevel@tonic-gate { 1068*0Sstevel@tonic-gate BIO_snprintf(kssl_err->text,KSSL_ERR_MAX, 1069*0Sstevel@tonic-gate "krb5_init_context() fails: %d\n", krb5rc); 1070*0Sstevel@tonic-gate kssl_err->reason = SSL_R_KRB5_C_INIT; 1071*0Sstevel@tonic-gate goto err; 1072*0Sstevel@tonic-gate } 1073*0Sstevel@tonic-gate 1074*0Sstevel@tonic-gate if ((krb5rc = krb5_sname_to_principal(krb5context, 1075*0Sstevel@tonic-gate kssl_ctx->service_host, 1076*0Sstevel@tonic-gate (kssl_ctx->service_name)? kssl_ctx->service_name: KRB5SVC, 1077*0Sstevel@tonic-gate KRB5_NT_SRV_HST, &krb5creds.server)) != 0) 1078*0Sstevel@tonic-gate { 1079*0Sstevel@tonic-gate BIO_snprintf(kssl_err->text,KSSL_ERR_MAX, 1080*0Sstevel@tonic-gate "krb5_sname_to_principal() fails for %s/%s\n", 1081*0Sstevel@tonic-gate kssl_ctx->service_host, 1082*0Sstevel@tonic-gate (kssl_ctx->service_name)? kssl_ctx->service_name: 1083*0Sstevel@tonic-gate KRB5SVC); 1084*0Sstevel@tonic-gate kssl_err->reason = SSL_R_KRB5_C_INIT; 1085*0Sstevel@tonic-gate goto err; 1086*0Sstevel@tonic-gate } 1087*0Sstevel@tonic-gate 1088*0Sstevel@tonic-gate if ((krb5rc = krb5_cc_default(krb5context, &krb5ccdef)) != 0) 1089*0Sstevel@tonic-gate { 1090*0Sstevel@tonic-gate kssl_err_set(kssl_err, SSL_R_KRB5_C_CC_PRINC, 1091*0Sstevel@tonic-gate "krb5_cc_default fails.\n"); 1092*0Sstevel@tonic-gate goto err; 1093*0Sstevel@tonic-gate } 1094*0Sstevel@tonic-gate 1095*0Sstevel@tonic-gate if ((krb5rc = krb5_cc_get_principal(krb5context, krb5ccdef, 1096*0Sstevel@tonic-gate &krb5creds.client)) != 0) 1097*0Sstevel@tonic-gate { 1098*0Sstevel@tonic-gate kssl_err_set(kssl_err, SSL_R_KRB5_C_CC_PRINC, 1099*0Sstevel@tonic-gate "krb5_cc_get_principal() fails.\n"); 1100*0Sstevel@tonic-gate goto err; 1101*0Sstevel@tonic-gate } 1102*0Sstevel@tonic-gate 1103*0Sstevel@tonic-gate if ((krb5rc = krb5_get_credentials(krb5context, 0, krb5ccdef, 1104*0Sstevel@tonic-gate &krb5creds, &krb5credsp)) != 0) 1105*0Sstevel@tonic-gate { 1106*0Sstevel@tonic-gate kssl_err_set(kssl_err, SSL_R_KRB5_C_GET_CRED, 1107*0Sstevel@tonic-gate "krb5_get_credentials() fails.\n"); 1108*0Sstevel@tonic-gate goto err; 1109*0Sstevel@tonic-gate } 1110*0Sstevel@tonic-gate 1111*0Sstevel@tonic-gate *enc_ticketp = &krb5credsp->ticket; 1112*0Sstevel@tonic-gate #ifdef KRB5_HEIMDAL 1113*0Sstevel@tonic-gate kssl_ctx->enctype = krb5credsp->session.keytype; 1114*0Sstevel@tonic-gate #else 1115*0Sstevel@tonic-gate kssl_ctx->enctype = krb5credsp->keyblock.enctype; 1116*0Sstevel@tonic-gate #endif 1117*0Sstevel@tonic-gate 1118*0Sstevel@tonic-gate krb5rc = KRB5KRB_ERR_GENERIC; 1119*0Sstevel@tonic-gate /* caller should free data of krb5_app_req */ 1120*0Sstevel@tonic-gate /* 20010406 VRS deleted for real KerberosWrapper 1121*0Sstevel@tonic-gate ** 20010605 VRS reinstated to offer Authenticator to KerberosWrapper 1122*0Sstevel@tonic-gate */ 1123*0Sstevel@tonic-gate krb5_app_req.length = 0; 1124*0Sstevel@tonic-gate if (authenp) 1125*0Sstevel@tonic-gate { 1126*0Sstevel@tonic-gate krb5_data krb5in_data; 1127*0Sstevel@tonic-gate unsigned char *p; 1128*0Sstevel@tonic-gate long arlen; 1129*0Sstevel@tonic-gate KRB5_APREQBODY *ap_req; 1130*0Sstevel@tonic-gate 1131*0Sstevel@tonic-gate authenp->length = 0; 1132*0Sstevel@tonic-gate krb5in_data.data = NULL; 1133*0Sstevel@tonic-gate krb5in_data.length = 0; 1134*0Sstevel@tonic-gate if ((krb5rc = krb5_mk_req_extended(krb5context, 1135*0Sstevel@tonic-gate &krb5auth_context, 0, &krb5in_data, krb5credsp, 1136*0Sstevel@tonic-gate &krb5_app_req)) != 0) 1137*0Sstevel@tonic-gate { 1138*0Sstevel@tonic-gate kssl_err_set(kssl_err, SSL_R_KRB5_C_MK_REQ, 1139*0Sstevel@tonic-gate "krb5_mk_req_extended() fails.\n"); 1140*0Sstevel@tonic-gate goto err; 1141*0Sstevel@tonic-gate } 1142*0Sstevel@tonic-gate 1143*0Sstevel@tonic-gate arlen = krb5_app_req.length; 1144*0Sstevel@tonic-gate p = (unsigned char *)krb5_app_req.data; 1145*0Sstevel@tonic-gate ap_req = (KRB5_APREQBODY *) d2i_KRB5_APREQ(NULL, &p, arlen); 1146*0Sstevel@tonic-gate if (ap_req) 1147*0Sstevel@tonic-gate { 1148*0Sstevel@tonic-gate authenp->length = i2d_KRB5_ENCDATA( 1149*0Sstevel@tonic-gate ap_req->authenticator, NULL); 1150*0Sstevel@tonic-gate if (authenp->length && 1151*0Sstevel@tonic-gate (authenp->data = malloc(authenp->length))) 1152*0Sstevel@tonic-gate { 1153*0Sstevel@tonic-gate unsigned char *adp = (unsigned char *)authenp->data; 1154*0Sstevel@tonic-gate authenp->length = i2d_KRB5_ENCDATA( 1155*0Sstevel@tonic-gate ap_req->authenticator, &adp); 1156*0Sstevel@tonic-gate } 1157*0Sstevel@tonic-gate } 1158*0Sstevel@tonic-gate 1159*0Sstevel@tonic-gate if (ap_req) KRB5_APREQ_free((KRB5_APREQ *) ap_req); 1160*0Sstevel@tonic-gate if (krb5_app_req.length) 1161*0Sstevel@tonic-gate kssl_krb5_free_data_contents(krb5context,&krb5_app_req); 1162*0Sstevel@tonic-gate } 1163*0Sstevel@tonic-gate #ifdef KRB5_HEIMDAL 1164*0Sstevel@tonic-gate if (kssl_ctx_setkey(kssl_ctx, &krb5credsp->session)) 1165*0Sstevel@tonic-gate { 1166*0Sstevel@tonic-gate kssl_err_set(kssl_err, SSL_R_KRB5_C_INIT, 1167*0Sstevel@tonic-gate "kssl_ctx_setkey() fails.\n"); 1168*0Sstevel@tonic-gate } 1169*0Sstevel@tonic-gate #else 1170*0Sstevel@tonic-gate if (kssl_ctx_setkey(kssl_ctx, &krb5credsp->keyblock)) 1171*0Sstevel@tonic-gate { 1172*0Sstevel@tonic-gate kssl_err_set(kssl_err, SSL_R_KRB5_C_INIT, 1173*0Sstevel@tonic-gate "kssl_ctx_setkey() fails.\n"); 1174*0Sstevel@tonic-gate } 1175*0Sstevel@tonic-gate #endif 1176*0Sstevel@tonic-gate else krb5rc = 0; 1177*0Sstevel@tonic-gate 1178*0Sstevel@tonic-gate err: 1179*0Sstevel@tonic-gate #ifdef KSSL_DEBUG 1180*0Sstevel@tonic-gate kssl_ctx_show(kssl_ctx); 1181*0Sstevel@tonic-gate #endif /* KSSL_DEBUG */ 1182*0Sstevel@tonic-gate 1183*0Sstevel@tonic-gate if (krb5creds.client) krb5_free_principal(krb5context, 1184*0Sstevel@tonic-gate krb5creds.client); 1185*0Sstevel@tonic-gate if (krb5creds.server) krb5_free_principal(krb5context, 1186*0Sstevel@tonic-gate krb5creds.server); 1187*0Sstevel@tonic-gate if (krb5auth_context) krb5_auth_con_free(krb5context, 1188*0Sstevel@tonic-gate krb5auth_context); 1189*0Sstevel@tonic-gate if (krb5context) krb5_free_context(krb5context); 1190*0Sstevel@tonic-gate return (krb5rc); 1191*0Sstevel@tonic-gate } 1192*0Sstevel@tonic-gate 1193*0Sstevel@tonic-gate 1194*0Sstevel@tonic-gate /* Given d2i_-decoded asn1ticket, allocate and return a new krb5_ticket. 1195*0Sstevel@tonic-gate ** Return Kerberos error code and kssl_err struct on error. 1196*0Sstevel@tonic-gate ** Allocates krb5_ticket and krb5_principal; caller should free these. 1197*0Sstevel@tonic-gate ** 1198*0Sstevel@tonic-gate ** 20010410 VRS Implemented krb5_decode_ticket() as 1199*0Sstevel@tonic-gate ** old_krb5_decode_ticket(). Missing from MIT1.0.6. 1200*0Sstevel@tonic-gate ** 20010615 VRS Re-cast as openssl/asn1 d2i_*() functions. 1201*0Sstevel@tonic-gate ** Re-used some of the old krb5_decode_ticket() 1202*0Sstevel@tonic-gate ** code here. This tkt should alloc/free just 1203*0Sstevel@tonic-gate ** like the real thing. 1204*0Sstevel@tonic-gate */ 1205*0Sstevel@tonic-gate krb5_error_code 1206*0Sstevel@tonic-gate kssl_TKT2tkt( /* IN */ krb5_context krb5context, 1207*0Sstevel@tonic-gate /* IN */ KRB5_TKTBODY *asn1ticket, 1208*0Sstevel@tonic-gate /* OUT */ krb5_ticket **krb5ticket, 1209*0Sstevel@tonic-gate /* OUT */ KSSL_ERR *kssl_err ) 1210*0Sstevel@tonic-gate { 1211*0Sstevel@tonic-gate krb5_error_code krb5rc = KRB5KRB_ERR_GENERIC; 1212*0Sstevel@tonic-gate krb5_ticket *new5ticket = NULL; 1213*0Sstevel@tonic-gate ASN1_GENERALSTRING *gstr_svc, *gstr_host; 1214*0Sstevel@tonic-gate 1215*0Sstevel@tonic-gate *krb5ticket = NULL; 1216*0Sstevel@tonic-gate 1217*0Sstevel@tonic-gate if (asn1ticket == NULL || asn1ticket->realm == NULL || 1218*0Sstevel@tonic-gate asn1ticket->sname == NULL || 1219*0Sstevel@tonic-gate sk_ASN1_GENERALSTRING_num(asn1ticket->sname->namestring) < 2) 1220*0Sstevel@tonic-gate { 1221*0Sstevel@tonic-gate BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, 1222*0Sstevel@tonic-gate "Null field in asn1ticket.\n"); 1223*0Sstevel@tonic-gate kssl_err->reason = SSL_R_KRB5_S_RD_REQ; 1224*0Sstevel@tonic-gate return KRB5KRB_ERR_GENERIC; 1225*0Sstevel@tonic-gate } 1226*0Sstevel@tonic-gate 1227*0Sstevel@tonic-gate if ((new5ticket = (krb5_ticket *) calloc(1, sizeof(krb5_ticket)))==NULL) 1228*0Sstevel@tonic-gate { 1229*0Sstevel@tonic-gate BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, 1230*0Sstevel@tonic-gate "Unable to allocate new krb5_ticket.\n"); 1231*0Sstevel@tonic-gate kssl_err->reason = SSL_R_KRB5_S_RD_REQ; 1232*0Sstevel@tonic-gate return ENOMEM; /* or KRB5KRB_ERR_GENERIC; */ 1233*0Sstevel@tonic-gate } 1234*0Sstevel@tonic-gate 1235*0Sstevel@tonic-gate gstr_svc = sk_ASN1_GENERALSTRING_value(asn1ticket->sname->namestring, 0); 1236*0Sstevel@tonic-gate gstr_host = sk_ASN1_GENERALSTRING_value(asn1ticket->sname->namestring, 1); 1237*0Sstevel@tonic-gate 1238*0Sstevel@tonic-gate if ((krb5rc = kssl_build_principal_2(krb5context, 1239*0Sstevel@tonic-gate &new5ticket->server, 1240*0Sstevel@tonic-gate asn1ticket->realm->length, (char *)asn1ticket->realm->data, 1241*0Sstevel@tonic-gate gstr_svc->length, (char *)gstr_svc->data, 1242*0Sstevel@tonic-gate gstr_host->length, (char *)gstr_host->data)) != 0) 1243*0Sstevel@tonic-gate { 1244*0Sstevel@tonic-gate free(new5ticket); 1245*0Sstevel@tonic-gate BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, 1246*0Sstevel@tonic-gate "Error building ticket server principal.\n"); 1247*0Sstevel@tonic-gate kssl_err->reason = SSL_R_KRB5_S_RD_REQ; 1248*0Sstevel@tonic-gate return krb5rc; /* or KRB5KRB_ERR_GENERIC; */ 1249*0Sstevel@tonic-gate } 1250*0Sstevel@tonic-gate 1251*0Sstevel@tonic-gate krb5_princ_type(krb5context, new5ticket->server) = 1252*0Sstevel@tonic-gate asn1ticket->sname->nametype->data[0]; 1253*0Sstevel@tonic-gate new5ticket->enc_part.enctype = asn1ticket->encdata->etype->data[0]; 1254*0Sstevel@tonic-gate new5ticket->enc_part.kvno = asn1ticket->encdata->kvno->data[0]; 1255*0Sstevel@tonic-gate new5ticket->enc_part.ciphertext.length = 1256*0Sstevel@tonic-gate asn1ticket->encdata->cipher->length; 1257*0Sstevel@tonic-gate if ((new5ticket->enc_part.ciphertext.data = 1258*0Sstevel@tonic-gate calloc(1, asn1ticket->encdata->cipher->length)) == NULL) 1259*0Sstevel@tonic-gate { 1260*0Sstevel@tonic-gate free(new5ticket); 1261*0Sstevel@tonic-gate BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, 1262*0Sstevel@tonic-gate "Error allocating cipher in krb5ticket.\n"); 1263*0Sstevel@tonic-gate kssl_err->reason = SSL_R_KRB5_S_RD_REQ; 1264*0Sstevel@tonic-gate return KRB5KRB_ERR_GENERIC; 1265*0Sstevel@tonic-gate } 1266*0Sstevel@tonic-gate else 1267*0Sstevel@tonic-gate { 1268*0Sstevel@tonic-gate memcpy(new5ticket->enc_part.ciphertext.data, 1269*0Sstevel@tonic-gate asn1ticket->encdata->cipher->data, 1270*0Sstevel@tonic-gate asn1ticket->encdata->cipher->length); 1271*0Sstevel@tonic-gate } 1272*0Sstevel@tonic-gate 1273*0Sstevel@tonic-gate *krb5ticket = new5ticket; 1274*0Sstevel@tonic-gate return 0; 1275*0Sstevel@tonic-gate } 1276*0Sstevel@tonic-gate 1277*0Sstevel@tonic-gate 1278*0Sstevel@tonic-gate /* Given krb5 service name in KSSL_CTX *kssl_ctx (typically "kssl"), 1279*0Sstevel@tonic-gate ** and krb5 AP_REQ message & message length, 1280*0Sstevel@tonic-gate ** Return Kerberos session key and client principle 1281*0Sstevel@tonic-gate ** to SSL Server in KSSL_CTX *kssl_ctx. 1282*0Sstevel@tonic-gate ** 1283*0Sstevel@tonic-gate ** 19990702 VRS Started. 1284*0Sstevel@tonic-gate */ 1285*0Sstevel@tonic-gate krb5_error_code 1286*0Sstevel@tonic-gate kssl_sget_tkt( /* UPDATE */ KSSL_CTX *kssl_ctx, 1287*0Sstevel@tonic-gate /* IN */ krb5_data *indata, 1288*0Sstevel@tonic-gate /* OUT */ krb5_ticket_times *ttimes, 1289*0Sstevel@tonic-gate /* OUT */ KSSL_ERR *kssl_err ) 1290*0Sstevel@tonic-gate { 1291*0Sstevel@tonic-gate krb5_error_code krb5rc = KRB5KRB_ERR_GENERIC; 1292*0Sstevel@tonic-gate static krb5_context krb5context = NULL; 1293*0Sstevel@tonic-gate static krb5_auth_context krb5auth_context = NULL; 1294*0Sstevel@tonic-gate krb5_ticket *krb5ticket = NULL; 1295*0Sstevel@tonic-gate KRB5_TKTBODY *asn1ticket = NULL; 1296*0Sstevel@tonic-gate unsigned char *p; 1297*0Sstevel@tonic-gate krb5_keytab krb5keytab = NULL; 1298*0Sstevel@tonic-gate krb5_keytab_entry kt_entry; 1299*0Sstevel@tonic-gate krb5_principal krb5server; 1300*0Sstevel@tonic-gate krb5_rcache rcache = NULL; 1301*0Sstevel@tonic-gate 1302*0Sstevel@tonic-gate kssl_err_set(kssl_err, 0, ""); 1303*0Sstevel@tonic-gate 1304*0Sstevel@tonic-gate if (!kssl_ctx) 1305*0Sstevel@tonic-gate { 1306*0Sstevel@tonic-gate kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, 1307*0Sstevel@tonic-gate "No kssl_ctx defined.\n"); 1308*0Sstevel@tonic-gate goto err; 1309*0Sstevel@tonic-gate } 1310*0Sstevel@tonic-gate 1311*0Sstevel@tonic-gate #ifdef KSSL_DEBUG 1312*0Sstevel@tonic-gate printf("in kssl_sget_tkt(%s)\n", kstring(kssl_ctx->service_name)); 1313*0Sstevel@tonic-gate #endif /* KSSL_DEBUG */ 1314*0Sstevel@tonic-gate 1315*0Sstevel@tonic-gate if (!krb5context && (krb5rc = krb5_init_context(&krb5context))) 1316*0Sstevel@tonic-gate { 1317*0Sstevel@tonic-gate kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, 1318*0Sstevel@tonic-gate "krb5_init_context() fails.\n"); 1319*0Sstevel@tonic-gate goto err; 1320*0Sstevel@tonic-gate } 1321*0Sstevel@tonic-gate if (krb5auth_context && 1322*0Sstevel@tonic-gate (krb5rc = krb5_auth_con_free(krb5context, krb5auth_context))) 1323*0Sstevel@tonic-gate { 1324*0Sstevel@tonic-gate kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, 1325*0Sstevel@tonic-gate "krb5_auth_con_free() fails.\n"); 1326*0Sstevel@tonic-gate goto err; 1327*0Sstevel@tonic-gate } 1328*0Sstevel@tonic-gate else krb5auth_context = NULL; 1329*0Sstevel@tonic-gate if (!krb5auth_context && 1330*0Sstevel@tonic-gate (krb5rc = krb5_auth_con_init(krb5context, &krb5auth_context))) 1331*0Sstevel@tonic-gate { 1332*0Sstevel@tonic-gate kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, 1333*0Sstevel@tonic-gate "krb5_auth_con_init() fails.\n"); 1334*0Sstevel@tonic-gate goto err; 1335*0Sstevel@tonic-gate } 1336*0Sstevel@tonic-gate 1337*0Sstevel@tonic-gate 1338*0Sstevel@tonic-gate if ((krb5rc = krb5_auth_con_getrcache(krb5context, krb5auth_context, 1339*0Sstevel@tonic-gate &rcache))) 1340*0Sstevel@tonic-gate { 1341*0Sstevel@tonic-gate kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, 1342*0Sstevel@tonic-gate "krb5_auth_con_getrcache() fails.\n"); 1343*0Sstevel@tonic-gate goto err; 1344*0Sstevel@tonic-gate } 1345*0Sstevel@tonic-gate 1346*0Sstevel@tonic-gate if ((krb5rc = krb5_sname_to_principal(krb5context, NULL, 1347*0Sstevel@tonic-gate (kssl_ctx->service_name)? kssl_ctx->service_name: KRB5SVC, 1348*0Sstevel@tonic-gate KRB5_NT_SRV_HST, &krb5server)) != 0) 1349*0Sstevel@tonic-gate { 1350*0Sstevel@tonic-gate kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, 1351*0Sstevel@tonic-gate "krb5_sname_to_principal() fails.\n"); 1352*0Sstevel@tonic-gate goto err; 1353*0Sstevel@tonic-gate } 1354*0Sstevel@tonic-gate 1355*0Sstevel@tonic-gate if (rcache == NULL) 1356*0Sstevel@tonic-gate { 1357*0Sstevel@tonic-gate if ((krb5rc = krb5_get_server_rcache(krb5context, 1358*0Sstevel@tonic-gate krb5_princ_component(krb5context, krb5server, 0), 1359*0Sstevel@tonic-gate &rcache))) 1360*0Sstevel@tonic-gate { 1361*0Sstevel@tonic-gate kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, 1362*0Sstevel@tonic-gate "krb5_get_server_rcache() fails.\n"); 1363*0Sstevel@tonic-gate goto err; 1364*0Sstevel@tonic-gate } 1365*0Sstevel@tonic-gate } 1366*0Sstevel@tonic-gate 1367*0Sstevel@tonic-gate if ((krb5rc = krb5_auth_con_setrcache(krb5context, krb5auth_context, rcache))) 1368*0Sstevel@tonic-gate { 1369*0Sstevel@tonic-gate kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, 1370*0Sstevel@tonic-gate "krb5_auth_con_setrcache() fails.\n"); 1371*0Sstevel@tonic-gate goto err; 1372*0Sstevel@tonic-gate } 1373*0Sstevel@tonic-gate 1374*0Sstevel@tonic-gate 1375*0Sstevel@tonic-gate /* kssl_ctx->keytab_file == NULL ==> use Kerberos default 1376*0Sstevel@tonic-gate */ 1377*0Sstevel@tonic-gate if (kssl_ctx->keytab_file) 1378*0Sstevel@tonic-gate { 1379*0Sstevel@tonic-gate krb5rc = krb5_kt_resolve(krb5context, kssl_ctx->keytab_file, 1380*0Sstevel@tonic-gate &krb5keytab); 1381*0Sstevel@tonic-gate if (krb5rc) 1382*0Sstevel@tonic-gate { 1383*0Sstevel@tonic-gate kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, 1384*0Sstevel@tonic-gate "krb5_kt_resolve() fails.\n"); 1385*0Sstevel@tonic-gate goto err; 1386*0Sstevel@tonic-gate } 1387*0Sstevel@tonic-gate } 1388*0Sstevel@tonic-gate else 1389*0Sstevel@tonic-gate { 1390*0Sstevel@tonic-gate krb5rc = krb5_kt_default(krb5context,&krb5keytab); 1391*0Sstevel@tonic-gate if (krb5rc) 1392*0Sstevel@tonic-gate { 1393*0Sstevel@tonic-gate kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, 1394*0Sstevel@tonic-gate "krb5_kt_default() fails.\n"); 1395*0Sstevel@tonic-gate goto err; 1396*0Sstevel@tonic-gate } 1397*0Sstevel@tonic-gate } 1398*0Sstevel@tonic-gate 1399*0Sstevel@tonic-gate /* Actual Kerberos5 krb5_recvauth() has initial conversation here 1400*0Sstevel@tonic-gate ** o check KRB5_SENDAUTH_BADAUTHVERS 1401*0Sstevel@tonic-gate ** unless KRB5_RECVAUTH_SKIP_VERSION 1402*0Sstevel@tonic-gate ** o check KRB5_SENDAUTH_BADAPPLVERS 1403*0Sstevel@tonic-gate ** o send "0" msg if all OK 1404*0Sstevel@tonic-gate */ 1405*0Sstevel@tonic-gate 1406*0Sstevel@tonic-gate /* 20010411 was using AP_REQ instead of true KerberosWrapper 1407*0Sstevel@tonic-gate ** 1408*0Sstevel@tonic-gate ** if ((krb5rc = krb5_rd_req(krb5context, &krb5auth_context, 1409*0Sstevel@tonic-gate ** &krb5in_data, krb5server, krb5keytab, 1410*0Sstevel@tonic-gate ** &ap_option, &krb5ticket)) != 0) { Error } 1411*0Sstevel@tonic-gate */ 1412*0Sstevel@tonic-gate 1413*0Sstevel@tonic-gate p = (unsigned char *)indata->data; 1414*0Sstevel@tonic-gate if ((asn1ticket = (KRB5_TKTBODY *) d2i_KRB5_TICKET(NULL, &p, 1415*0Sstevel@tonic-gate (long) indata->length)) == NULL) 1416*0Sstevel@tonic-gate { 1417*0Sstevel@tonic-gate BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, 1418*0Sstevel@tonic-gate "d2i_KRB5_TICKET() ASN.1 decode failure.\n"); 1419*0Sstevel@tonic-gate kssl_err->reason = SSL_R_KRB5_S_RD_REQ; 1420*0Sstevel@tonic-gate goto err; 1421*0Sstevel@tonic-gate } 1422*0Sstevel@tonic-gate 1423*0Sstevel@tonic-gate /* Was: krb5rc = krb5_decode_ticket(krb5in_data,&krb5ticket)) != 0) */ 1424*0Sstevel@tonic-gate if ((krb5rc = kssl_TKT2tkt(krb5context, asn1ticket, &krb5ticket, 1425*0Sstevel@tonic-gate kssl_err)) != 0) 1426*0Sstevel@tonic-gate { 1427*0Sstevel@tonic-gate BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, 1428*0Sstevel@tonic-gate "Error converting ASN.1 ticket to krb5_ticket.\n"); 1429*0Sstevel@tonic-gate kssl_err->reason = SSL_R_KRB5_S_RD_REQ; 1430*0Sstevel@tonic-gate goto err; 1431*0Sstevel@tonic-gate } 1432*0Sstevel@tonic-gate 1433*0Sstevel@tonic-gate if (! krb5_principal_compare(krb5context, krb5server, 1434*0Sstevel@tonic-gate krb5ticket->server)) { 1435*0Sstevel@tonic-gate krb5rc = KRB5_PRINC_NOMATCH; 1436*0Sstevel@tonic-gate BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, 1437*0Sstevel@tonic-gate "server principal != ticket principal\n"); 1438*0Sstevel@tonic-gate kssl_err->reason = SSL_R_KRB5_S_RD_REQ; 1439*0Sstevel@tonic-gate goto err; 1440*0Sstevel@tonic-gate } 1441*0Sstevel@tonic-gate if ((krb5rc = krb5_kt_get_entry(krb5context, krb5keytab, 1442*0Sstevel@tonic-gate krb5ticket->server, krb5ticket->enc_part.kvno, 1443*0Sstevel@tonic-gate krb5ticket->enc_part.enctype, &kt_entry)) != 0) { 1444*0Sstevel@tonic-gate BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, 1445*0Sstevel@tonic-gate "krb5_kt_get_entry() fails with %x.\n", krb5rc); 1446*0Sstevel@tonic-gate kssl_err->reason = SSL_R_KRB5_S_RD_REQ; 1447*0Sstevel@tonic-gate goto err; 1448*0Sstevel@tonic-gate } 1449*0Sstevel@tonic-gate if ((krb5rc = krb5_decrypt_tkt_part(krb5context, &kt_entry.key, 1450*0Sstevel@tonic-gate krb5ticket)) != 0) { 1451*0Sstevel@tonic-gate BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, 1452*0Sstevel@tonic-gate "krb5_decrypt_tkt_part() failed.\n"); 1453*0Sstevel@tonic-gate kssl_err->reason = SSL_R_KRB5_S_RD_REQ; 1454*0Sstevel@tonic-gate goto err; 1455*0Sstevel@tonic-gate } 1456*0Sstevel@tonic-gate else { 1457*0Sstevel@tonic-gate krb5_kt_free_entry(krb5context, &kt_entry); 1458*0Sstevel@tonic-gate #ifdef KSSL_DEBUG 1459*0Sstevel@tonic-gate { 1460*0Sstevel@tonic-gate int i; krb5_address **paddr = krb5ticket->enc_part2->caddrs; 1461*0Sstevel@tonic-gate printf("Decrypted ticket fields:\n"); 1462*0Sstevel@tonic-gate printf("\tflags: %X, transit-type: %X", 1463*0Sstevel@tonic-gate krb5ticket->enc_part2->flags, 1464*0Sstevel@tonic-gate krb5ticket->enc_part2->transited.tr_type); 1465*0Sstevel@tonic-gate print_krb5_data("\ttransit-data: ", 1466*0Sstevel@tonic-gate &(krb5ticket->enc_part2->transited.tr_contents)); 1467*0Sstevel@tonic-gate printf("\tcaddrs: %p, authdata: %p\n", 1468*0Sstevel@tonic-gate krb5ticket->enc_part2->caddrs, 1469*0Sstevel@tonic-gate krb5ticket->enc_part2->authorization_data); 1470*0Sstevel@tonic-gate if (paddr) 1471*0Sstevel@tonic-gate { 1472*0Sstevel@tonic-gate printf("\tcaddrs:\n"); 1473*0Sstevel@tonic-gate for (i=0; paddr[i] != NULL; i++) 1474*0Sstevel@tonic-gate { 1475*0Sstevel@tonic-gate krb5_data d; 1476*0Sstevel@tonic-gate d.length=paddr[i]->length; 1477*0Sstevel@tonic-gate d.data=paddr[i]->contents; 1478*0Sstevel@tonic-gate print_krb5_data("\t\tIP: ", &d); 1479*0Sstevel@tonic-gate } 1480*0Sstevel@tonic-gate } 1481*0Sstevel@tonic-gate printf("\tstart/auth/end times: %d / %d / %d\n", 1482*0Sstevel@tonic-gate krb5ticket->enc_part2->times.starttime, 1483*0Sstevel@tonic-gate krb5ticket->enc_part2->times.authtime, 1484*0Sstevel@tonic-gate krb5ticket->enc_part2->times.endtime); 1485*0Sstevel@tonic-gate } 1486*0Sstevel@tonic-gate #endif /* KSSL_DEBUG */ 1487*0Sstevel@tonic-gate } 1488*0Sstevel@tonic-gate 1489*0Sstevel@tonic-gate krb5rc = KRB5_NO_TKT_SUPPLIED; 1490*0Sstevel@tonic-gate if (!krb5ticket || !krb5ticket->enc_part2 || 1491*0Sstevel@tonic-gate !krb5ticket->enc_part2->client || 1492*0Sstevel@tonic-gate !krb5ticket->enc_part2->client->data || 1493*0Sstevel@tonic-gate !krb5ticket->enc_part2->session) 1494*0Sstevel@tonic-gate { 1495*0Sstevel@tonic-gate kssl_err_set(kssl_err, SSL_R_KRB5_S_BAD_TICKET, 1496*0Sstevel@tonic-gate "bad ticket from krb5_rd_req.\n"); 1497*0Sstevel@tonic-gate } 1498*0Sstevel@tonic-gate else if (kssl_ctx_setprinc(kssl_ctx, KSSL_CLIENT, 1499*0Sstevel@tonic-gate &krb5ticket->enc_part2->client->realm, 1500*0Sstevel@tonic-gate krb5ticket->enc_part2->client->data, 1501*0Sstevel@tonic-gate krb5ticket->enc_part2->client->length)) 1502*0Sstevel@tonic-gate { 1503*0Sstevel@tonic-gate kssl_err_set(kssl_err, SSL_R_KRB5_S_BAD_TICKET, 1504*0Sstevel@tonic-gate "kssl_ctx_setprinc() fails.\n"); 1505*0Sstevel@tonic-gate } 1506*0Sstevel@tonic-gate else if (kssl_ctx_setkey(kssl_ctx, krb5ticket->enc_part2->session)) 1507*0Sstevel@tonic-gate { 1508*0Sstevel@tonic-gate kssl_err_set(kssl_err, SSL_R_KRB5_S_BAD_TICKET, 1509*0Sstevel@tonic-gate "kssl_ctx_setkey() fails.\n"); 1510*0Sstevel@tonic-gate } 1511*0Sstevel@tonic-gate else if (krb5ticket->enc_part2->flags & TKT_FLG_INVALID) 1512*0Sstevel@tonic-gate { 1513*0Sstevel@tonic-gate krb5rc = KRB5KRB_AP_ERR_TKT_INVALID; 1514*0Sstevel@tonic-gate kssl_err_set(kssl_err, SSL_R_KRB5_S_BAD_TICKET, 1515*0Sstevel@tonic-gate "invalid ticket from krb5_rd_req.\n"); 1516*0Sstevel@tonic-gate } 1517*0Sstevel@tonic-gate else krb5rc = 0; 1518*0Sstevel@tonic-gate 1519*0Sstevel@tonic-gate kssl_ctx->enctype = krb5ticket->enc_part.enctype; 1520*0Sstevel@tonic-gate ttimes->authtime = krb5ticket->enc_part2->times.authtime; 1521*0Sstevel@tonic-gate ttimes->starttime = krb5ticket->enc_part2->times.starttime; 1522*0Sstevel@tonic-gate ttimes->endtime = krb5ticket->enc_part2->times.endtime; 1523*0Sstevel@tonic-gate ttimes->renew_till = krb5ticket->enc_part2->times.renew_till; 1524*0Sstevel@tonic-gate 1525*0Sstevel@tonic-gate err: 1526*0Sstevel@tonic-gate #ifdef KSSL_DEBUG 1527*0Sstevel@tonic-gate kssl_ctx_show(kssl_ctx); 1528*0Sstevel@tonic-gate #endif /* KSSL_DEBUG */ 1529*0Sstevel@tonic-gate 1530*0Sstevel@tonic-gate if (asn1ticket) KRB5_TICKET_free((KRB5_TICKET *) asn1ticket); 1531*0Sstevel@tonic-gate if (krb5keytab) krb5_kt_close(krb5context, krb5keytab); 1532*0Sstevel@tonic-gate if (krb5ticket) krb5_free_ticket(krb5context, krb5ticket); 1533*0Sstevel@tonic-gate if (krb5server) krb5_free_principal(krb5context, krb5server); 1534*0Sstevel@tonic-gate return (krb5rc); 1535*0Sstevel@tonic-gate } 1536*0Sstevel@tonic-gate 1537*0Sstevel@tonic-gate 1538*0Sstevel@tonic-gate /* Allocate & return a new kssl_ctx struct. 1539*0Sstevel@tonic-gate */ 1540*0Sstevel@tonic-gate KSSL_CTX * 1541*0Sstevel@tonic-gate kssl_ctx_new(void) 1542*0Sstevel@tonic-gate { 1543*0Sstevel@tonic-gate return ((KSSL_CTX *) calloc(1, sizeof(KSSL_CTX))); 1544*0Sstevel@tonic-gate } 1545*0Sstevel@tonic-gate 1546*0Sstevel@tonic-gate 1547*0Sstevel@tonic-gate /* Frees a kssl_ctx struct and any allocated memory it holds. 1548*0Sstevel@tonic-gate ** Returns NULL. 1549*0Sstevel@tonic-gate */ 1550*0Sstevel@tonic-gate KSSL_CTX * 1551*0Sstevel@tonic-gate kssl_ctx_free(KSSL_CTX *kssl_ctx) 1552*0Sstevel@tonic-gate { 1553*0Sstevel@tonic-gate if (kssl_ctx == NULL) return kssl_ctx; 1554*0Sstevel@tonic-gate 1555*0Sstevel@tonic-gate if (kssl_ctx->key) OPENSSL_cleanse(kssl_ctx->key, 1556*0Sstevel@tonic-gate kssl_ctx->length); 1557*0Sstevel@tonic-gate if (kssl_ctx->key) free(kssl_ctx->key); 1558*0Sstevel@tonic-gate if (kssl_ctx->client_princ) free(kssl_ctx->client_princ); 1559*0Sstevel@tonic-gate if (kssl_ctx->service_host) free(kssl_ctx->service_host); 1560*0Sstevel@tonic-gate if (kssl_ctx->service_name) free(kssl_ctx->service_name); 1561*0Sstevel@tonic-gate if (kssl_ctx->keytab_file) free(kssl_ctx->keytab_file); 1562*0Sstevel@tonic-gate 1563*0Sstevel@tonic-gate free(kssl_ctx); 1564*0Sstevel@tonic-gate return (KSSL_CTX *) NULL; 1565*0Sstevel@tonic-gate } 1566*0Sstevel@tonic-gate 1567*0Sstevel@tonic-gate 1568*0Sstevel@tonic-gate /* Given an array of (krb5_data *) entity (and optional realm), 1569*0Sstevel@tonic-gate ** set the plain (char *) client_princ or service_host member 1570*0Sstevel@tonic-gate ** of the kssl_ctx struct. 1571*0Sstevel@tonic-gate */ 1572*0Sstevel@tonic-gate krb5_error_code 1573*0Sstevel@tonic-gate kssl_ctx_setprinc(KSSL_CTX *kssl_ctx, int which, 1574*0Sstevel@tonic-gate krb5_data *realm, krb5_data *entity, int nentities) 1575*0Sstevel@tonic-gate { 1576*0Sstevel@tonic-gate char **princ; 1577*0Sstevel@tonic-gate int length; 1578*0Sstevel@tonic-gate int i; 1579*0Sstevel@tonic-gate 1580*0Sstevel@tonic-gate if (kssl_ctx == NULL || entity == NULL) return KSSL_CTX_ERR; 1581*0Sstevel@tonic-gate 1582*0Sstevel@tonic-gate switch (which) 1583*0Sstevel@tonic-gate { 1584*0Sstevel@tonic-gate case KSSL_CLIENT: princ = &kssl_ctx->client_princ; break; 1585*0Sstevel@tonic-gate case KSSL_SERVER: princ = &kssl_ctx->service_host; break; 1586*0Sstevel@tonic-gate default: return KSSL_CTX_ERR; break; 1587*0Sstevel@tonic-gate } 1588*0Sstevel@tonic-gate if (*princ) free(*princ); 1589*0Sstevel@tonic-gate 1590*0Sstevel@tonic-gate /* Add up all the entity->lengths */ 1591*0Sstevel@tonic-gate length = 0; 1592*0Sstevel@tonic-gate for (i=0; i < nentities; i++) 1593*0Sstevel@tonic-gate { 1594*0Sstevel@tonic-gate length += entity[i].length; 1595*0Sstevel@tonic-gate } 1596*0Sstevel@tonic-gate /* Add in space for the '/' character(s) (if any) */ 1597*0Sstevel@tonic-gate length += nentities-1; 1598*0Sstevel@tonic-gate /* Space for the ('@'+realm+NULL | NULL) */ 1599*0Sstevel@tonic-gate length += ((realm)? realm->length + 2: 1); 1600*0Sstevel@tonic-gate 1601*0Sstevel@tonic-gate if ((*princ = calloc(1, length)) == NULL) 1602*0Sstevel@tonic-gate return KSSL_CTX_ERR; 1603*0Sstevel@tonic-gate else 1604*0Sstevel@tonic-gate { 1605*0Sstevel@tonic-gate for (i = 0; i < nentities; i++) 1606*0Sstevel@tonic-gate { 1607*0Sstevel@tonic-gate strncat(*princ, entity[i].data, entity[i].length); 1608*0Sstevel@tonic-gate if (i < nentities-1) 1609*0Sstevel@tonic-gate { 1610*0Sstevel@tonic-gate strcat (*princ, "/"); 1611*0Sstevel@tonic-gate } 1612*0Sstevel@tonic-gate } 1613*0Sstevel@tonic-gate if (realm) 1614*0Sstevel@tonic-gate { 1615*0Sstevel@tonic-gate strcat (*princ, "@"); 1616*0Sstevel@tonic-gate (void) strncat(*princ, realm->data, realm->length); 1617*0Sstevel@tonic-gate } 1618*0Sstevel@tonic-gate } 1619*0Sstevel@tonic-gate 1620*0Sstevel@tonic-gate return KSSL_CTX_OK; 1621*0Sstevel@tonic-gate } 1622*0Sstevel@tonic-gate 1623*0Sstevel@tonic-gate 1624*0Sstevel@tonic-gate /* Set one of the plain (char *) string members of the kssl_ctx struct. 1625*0Sstevel@tonic-gate ** Default values should be: 1626*0Sstevel@tonic-gate ** which == KSSL_SERVICE => "khost" (KRB5SVC) 1627*0Sstevel@tonic-gate ** which == KSSL_KEYTAB => "/etc/krb5.keytab" (KRB5KEYTAB) 1628*0Sstevel@tonic-gate */ 1629*0Sstevel@tonic-gate krb5_error_code 1630*0Sstevel@tonic-gate kssl_ctx_setstring(KSSL_CTX *kssl_ctx, int which, char *text) 1631*0Sstevel@tonic-gate { 1632*0Sstevel@tonic-gate char **string; 1633*0Sstevel@tonic-gate 1634*0Sstevel@tonic-gate if (!kssl_ctx) return KSSL_CTX_ERR; 1635*0Sstevel@tonic-gate 1636*0Sstevel@tonic-gate switch (which) 1637*0Sstevel@tonic-gate { 1638*0Sstevel@tonic-gate case KSSL_SERVICE: string = &kssl_ctx->service_name; break; 1639*0Sstevel@tonic-gate case KSSL_SERVER: string = &kssl_ctx->service_host; break; 1640*0Sstevel@tonic-gate case KSSL_CLIENT: string = &kssl_ctx->client_princ; break; 1641*0Sstevel@tonic-gate case KSSL_KEYTAB: string = &kssl_ctx->keytab_file; break; 1642*0Sstevel@tonic-gate default: return KSSL_CTX_ERR; break; 1643*0Sstevel@tonic-gate } 1644*0Sstevel@tonic-gate if (*string) free(*string); 1645*0Sstevel@tonic-gate 1646*0Sstevel@tonic-gate if (!text) 1647*0Sstevel@tonic-gate { 1648*0Sstevel@tonic-gate *string = '\0'; 1649*0Sstevel@tonic-gate return KSSL_CTX_OK; 1650*0Sstevel@tonic-gate } 1651*0Sstevel@tonic-gate 1652*0Sstevel@tonic-gate if ((*string = calloc(1, strlen(text) + 1)) == NULL) 1653*0Sstevel@tonic-gate return KSSL_CTX_ERR; 1654*0Sstevel@tonic-gate else 1655*0Sstevel@tonic-gate strcpy(*string, text); 1656*0Sstevel@tonic-gate 1657*0Sstevel@tonic-gate return KSSL_CTX_OK; 1658*0Sstevel@tonic-gate } 1659*0Sstevel@tonic-gate 1660*0Sstevel@tonic-gate 1661*0Sstevel@tonic-gate /* Copy the Kerberos session key from a (krb5_keyblock *) to a kssl_ctx 1662*0Sstevel@tonic-gate ** struct. Clear kssl_ctx->key if Kerberos session key is NULL. 1663*0Sstevel@tonic-gate */ 1664*0Sstevel@tonic-gate krb5_error_code 1665*0Sstevel@tonic-gate kssl_ctx_setkey(KSSL_CTX *kssl_ctx, krb5_keyblock *session) 1666*0Sstevel@tonic-gate { 1667*0Sstevel@tonic-gate int length; 1668*0Sstevel@tonic-gate krb5_enctype enctype; 1669*0Sstevel@tonic-gate krb5_octet FAR *contents = NULL; 1670*0Sstevel@tonic-gate 1671*0Sstevel@tonic-gate if (!kssl_ctx) return KSSL_CTX_ERR; 1672*0Sstevel@tonic-gate 1673*0Sstevel@tonic-gate if (kssl_ctx->key) 1674*0Sstevel@tonic-gate { 1675*0Sstevel@tonic-gate OPENSSL_cleanse(kssl_ctx->key, kssl_ctx->length); 1676*0Sstevel@tonic-gate free(kssl_ctx->key); 1677*0Sstevel@tonic-gate } 1678*0Sstevel@tonic-gate 1679*0Sstevel@tonic-gate if (session) 1680*0Sstevel@tonic-gate { 1681*0Sstevel@tonic-gate 1682*0Sstevel@tonic-gate #ifdef KRB5_HEIMDAL 1683*0Sstevel@tonic-gate length = session->keyvalue->length; 1684*0Sstevel@tonic-gate enctype = session->keytype; 1685*0Sstevel@tonic-gate contents = session->keyvalue->contents; 1686*0Sstevel@tonic-gate #else 1687*0Sstevel@tonic-gate length = session->length; 1688*0Sstevel@tonic-gate enctype = session->enctype; 1689*0Sstevel@tonic-gate contents = session->contents; 1690*0Sstevel@tonic-gate #endif 1691*0Sstevel@tonic-gate kssl_ctx->enctype = enctype; 1692*0Sstevel@tonic-gate kssl_ctx->length = length; 1693*0Sstevel@tonic-gate } 1694*0Sstevel@tonic-gate else 1695*0Sstevel@tonic-gate { 1696*0Sstevel@tonic-gate kssl_ctx->enctype = ENCTYPE_UNKNOWN; 1697*0Sstevel@tonic-gate kssl_ctx->length = 0; 1698*0Sstevel@tonic-gate return KSSL_CTX_OK; 1699*0Sstevel@tonic-gate } 1700*0Sstevel@tonic-gate 1701*0Sstevel@tonic-gate if ((kssl_ctx->key = 1702*0Sstevel@tonic-gate (krb5_octet FAR *) calloc(1, kssl_ctx->length)) == NULL) 1703*0Sstevel@tonic-gate { 1704*0Sstevel@tonic-gate kssl_ctx->length = 0; 1705*0Sstevel@tonic-gate return KSSL_CTX_ERR; 1706*0Sstevel@tonic-gate } 1707*0Sstevel@tonic-gate else 1708*0Sstevel@tonic-gate memcpy(kssl_ctx->key, contents, length); 1709*0Sstevel@tonic-gate 1710*0Sstevel@tonic-gate return KSSL_CTX_OK; 1711*0Sstevel@tonic-gate } 1712*0Sstevel@tonic-gate 1713*0Sstevel@tonic-gate 1714*0Sstevel@tonic-gate /* Display contents of kssl_ctx struct 1715*0Sstevel@tonic-gate */ 1716*0Sstevel@tonic-gate void 1717*0Sstevel@tonic-gate kssl_ctx_show(KSSL_CTX *kssl_ctx) 1718*0Sstevel@tonic-gate { 1719*0Sstevel@tonic-gate int i; 1720*0Sstevel@tonic-gate 1721*0Sstevel@tonic-gate printf("kssl_ctx: "); 1722*0Sstevel@tonic-gate if (kssl_ctx == NULL) 1723*0Sstevel@tonic-gate { 1724*0Sstevel@tonic-gate printf("NULL\n"); 1725*0Sstevel@tonic-gate return; 1726*0Sstevel@tonic-gate } 1727*0Sstevel@tonic-gate else 1728*0Sstevel@tonic-gate printf("%p\n", (void *)kssl_ctx); 1729*0Sstevel@tonic-gate 1730*0Sstevel@tonic-gate printf("\tservice:\t%s\n", 1731*0Sstevel@tonic-gate (kssl_ctx->service_name)? kssl_ctx->service_name: "NULL"); 1732*0Sstevel@tonic-gate printf("\tclient:\t%s\n", 1733*0Sstevel@tonic-gate (kssl_ctx->client_princ)? kssl_ctx->client_princ: "NULL"); 1734*0Sstevel@tonic-gate printf("\tserver:\t%s\n", 1735*0Sstevel@tonic-gate (kssl_ctx->service_host)? kssl_ctx->service_host: "NULL"); 1736*0Sstevel@tonic-gate printf("\tkeytab:\t%s\n", 1737*0Sstevel@tonic-gate (kssl_ctx->keytab_file)? kssl_ctx->keytab_file: "NULL"); 1738*0Sstevel@tonic-gate printf("\tkey [%d:%d]:\t", 1739*0Sstevel@tonic-gate kssl_ctx->enctype, kssl_ctx->length); 1740*0Sstevel@tonic-gate 1741*0Sstevel@tonic-gate for (i=0; i < kssl_ctx->length && kssl_ctx->key; i++) 1742*0Sstevel@tonic-gate { 1743*0Sstevel@tonic-gate printf("%02x", kssl_ctx->key[i]); 1744*0Sstevel@tonic-gate } 1745*0Sstevel@tonic-gate printf("\n"); 1746*0Sstevel@tonic-gate return; 1747*0Sstevel@tonic-gate } 1748*0Sstevel@tonic-gate 1749*0Sstevel@tonic-gate int 1750*0Sstevel@tonic-gate kssl_keytab_is_available(KSSL_CTX *kssl_ctx) 1751*0Sstevel@tonic-gate { 1752*0Sstevel@tonic-gate krb5_context krb5context = NULL; 1753*0Sstevel@tonic-gate krb5_keytab krb5keytab = NULL; 1754*0Sstevel@tonic-gate krb5_keytab_entry entry; 1755*0Sstevel@tonic-gate krb5_principal princ = NULL; 1756*0Sstevel@tonic-gate krb5_error_code krb5rc = KRB5KRB_ERR_GENERIC; 1757*0Sstevel@tonic-gate int rc = 0; 1758*0Sstevel@tonic-gate 1759*0Sstevel@tonic-gate if ((krb5rc = krb5_init_context(&krb5context))) 1760*0Sstevel@tonic-gate return(0); 1761*0Sstevel@tonic-gate 1762*0Sstevel@tonic-gate /* kssl_ctx->keytab_file == NULL ==> use Kerberos default 1763*0Sstevel@tonic-gate */ 1764*0Sstevel@tonic-gate if (kssl_ctx->keytab_file) 1765*0Sstevel@tonic-gate { 1766*0Sstevel@tonic-gate krb5rc = krb5_kt_resolve(krb5context, kssl_ctx->keytab_file, 1767*0Sstevel@tonic-gate &krb5keytab); 1768*0Sstevel@tonic-gate if (krb5rc) 1769*0Sstevel@tonic-gate goto exit; 1770*0Sstevel@tonic-gate } 1771*0Sstevel@tonic-gate else 1772*0Sstevel@tonic-gate { 1773*0Sstevel@tonic-gate krb5rc = krb5_kt_default(krb5context,&krb5keytab); 1774*0Sstevel@tonic-gate if (krb5rc) 1775*0Sstevel@tonic-gate goto exit; 1776*0Sstevel@tonic-gate } 1777*0Sstevel@tonic-gate 1778*0Sstevel@tonic-gate /* the host key we are looking for */ 1779*0Sstevel@tonic-gate krb5rc = krb5_sname_to_principal(krb5context, NULL, 1780*0Sstevel@tonic-gate kssl_ctx->service_name ? kssl_ctx->service_name: KRB5SVC, 1781*0Sstevel@tonic-gate KRB5_NT_SRV_HST, &princ); 1782*0Sstevel@tonic-gate 1783*0Sstevel@tonic-gate krb5rc = krb5_kt_get_entry(krb5context, krb5keytab, 1784*0Sstevel@tonic-gate princ, 1785*0Sstevel@tonic-gate 0 /* IGNORE_VNO */, 1786*0Sstevel@tonic-gate 0 /* IGNORE_ENCTYPE */, 1787*0Sstevel@tonic-gate &entry); 1788*0Sstevel@tonic-gate if ( krb5rc == KRB5_KT_NOTFOUND ) { 1789*0Sstevel@tonic-gate rc = 1; 1790*0Sstevel@tonic-gate goto exit; 1791*0Sstevel@tonic-gate } else if ( krb5rc ) 1792*0Sstevel@tonic-gate goto exit; 1793*0Sstevel@tonic-gate 1794*0Sstevel@tonic-gate krb5_kt_free_entry(krb5context, &entry); 1795*0Sstevel@tonic-gate rc = 1; 1796*0Sstevel@tonic-gate 1797*0Sstevel@tonic-gate exit: 1798*0Sstevel@tonic-gate if (krb5keytab) krb5_kt_close(krb5context, krb5keytab); 1799*0Sstevel@tonic-gate if (princ) krb5_free_principal(krb5context, princ); 1800*0Sstevel@tonic-gate if (krb5context) krb5_free_context(krb5context); 1801*0Sstevel@tonic-gate return(rc); 1802*0Sstevel@tonic-gate } 1803*0Sstevel@tonic-gate 1804*0Sstevel@tonic-gate int 1805*0Sstevel@tonic-gate kssl_tgt_is_available(KSSL_CTX *kssl_ctx) 1806*0Sstevel@tonic-gate { 1807*0Sstevel@tonic-gate krb5_error_code krb5rc = KRB5KRB_ERR_GENERIC; 1808*0Sstevel@tonic-gate krb5_context krb5context = NULL; 1809*0Sstevel@tonic-gate krb5_ccache krb5ccdef = NULL; 1810*0Sstevel@tonic-gate krb5_creds krb5creds, *krb5credsp = NULL; 1811*0Sstevel@tonic-gate int rc = 0; 1812*0Sstevel@tonic-gate 1813*0Sstevel@tonic-gate memset((char *)&krb5creds, 0, sizeof(krb5creds)); 1814*0Sstevel@tonic-gate 1815*0Sstevel@tonic-gate if (!kssl_ctx) 1816*0Sstevel@tonic-gate return(0); 1817*0Sstevel@tonic-gate 1818*0Sstevel@tonic-gate if (!kssl_ctx->service_host) 1819*0Sstevel@tonic-gate return(0); 1820*0Sstevel@tonic-gate 1821*0Sstevel@tonic-gate if ((krb5rc = krb5_init_context(&krb5context)) != 0) 1822*0Sstevel@tonic-gate goto err; 1823*0Sstevel@tonic-gate 1824*0Sstevel@tonic-gate if ((krb5rc = krb5_sname_to_principal(krb5context, 1825*0Sstevel@tonic-gate kssl_ctx->service_host, 1826*0Sstevel@tonic-gate (kssl_ctx->service_name)? kssl_ctx->service_name: KRB5SVC, 1827*0Sstevel@tonic-gate KRB5_NT_SRV_HST, &krb5creds.server)) != 0) 1828*0Sstevel@tonic-gate goto err; 1829*0Sstevel@tonic-gate 1830*0Sstevel@tonic-gate if ((krb5rc = krb5_cc_default(krb5context, &krb5ccdef)) != 0) 1831*0Sstevel@tonic-gate goto err; 1832*0Sstevel@tonic-gate 1833*0Sstevel@tonic-gate if ((krb5rc = krb5_cc_get_principal(krb5context, krb5ccdef, 1834*0Sstevel@tonic-gate &krb5creds.client)) != 0) 1835*0Sstevel@tonic-gate goto err; 1836*0Sstevel@tonic-gate 1837*0Sstevel@tonic-gate if ((krb5rc = krb5_get_credentials(krb5context, 0, krb5ccdef, 1838*0Sstevel@tonic-gate &krb5creds, &krb5credsp)) != 0) 1839*0Sstevel@tonic-gate goto err; 1840*0Sstevel@tonic-gate 1841*0Sstevel@tonic-gate rc = 1; 1842*0Sstevel@tonic-gate 1843*0Sstevel@tonic-gate err: 1844*0Sstevel@tonic-gate #ifdef KSSL_DEBUG 1845*0Sstevel@tonic-gate kssl_ctx_show(kssl_ctx); 1846*0Sstevel@tonic-gate #endif /* KSSL_DEBUG */ 1847*0Sstevel@tonic-gate 1848*0Sstevel@tonic-gate if (krb5creds.client) krb5_free_principal(krb5context, krb5creds.client); 1849*0Sstevel@tonic-gate if (krb5creds.server) krb5_free_principal(krb5context, krb5creds.server); 1850*0Sstevel@tonic-gate if (krb5context) krb5_free_context(krb5context); 1851*0Sstevel@tonic-gate return(rc); 1852*0Sstevel@tonic-gate } 1853*0Sstevel@tonic-gate 1854*0Sstevel@tonic-gate #if !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_WIN32) 1855*0Sstevel@tonic-gate void kssl_krb5_free_data_contents(krb5_context context, krb5_data *data) 1856*0Sstevel@tonic-gate { 1857*0Sstevel@tonic-gate #ifdef KRB5_HEIMDAL 1858*0Sstevel@tonic-gate data->length = 0; 1859*0Sstevel@tonic-gate if (data->data) 1860*0Sstevel@tonic-gate free(data->data); 1861*0Sstevel@tonic-gate #elif defined(KRB5_MIT_OLD11) 1862*0Sstevel@tonic-gate if (data->data) { 1863*0Sstevel@tonic-gate krb5_xfree(data->data); 1864*0Sstevel@tonic-gate data->data = 0; 1865*0Sstevel@tonic-gate } 1866*0Sstevel@tonic-gate #else 1867*0Sstevel@tonic-gate krb5_free_data_contents(NULL, data); 1868*0Sstevel@tonic-gate #endif 1869*0Sstevel@tonic-gate } 1870*0Sstevel@tonic-gate #endif /* !OPENSSL_SYS_WINDOWS && !OPENSSL_SYS_WIN32 */ 1871*0Sstevel@tonic-gate 1872*0Sstevel@tonic-gate 1873*0Sstevel@tonic-gate /* Given pointers to KerberosTime and struct tm structs, convert the 1874*0Sstevel@tonic-gate ** KerberosTime string to struct tm. Note that KerberosTime is a 1875*0Sstevel@tonic-gate ** ASN1_GENERALIZEDTIME value, constrained to GMT with no fractional 1876*0Sstevel@tonic-gate ** seconds as defined in RFC 1510. 1877*0Sstevel@tonic-gate ** Return pointer to the (partially) filled in struct tm on success, 1878*0Sstevel@tonic-gate ** return NULL on failure. 1879*0Sstevel@tonic-gate */ 1880*0Sstevel@tonic-gate struct tm *k_gmtime(ASN1_GENERALIZEDTIME *gtime, struct tm *k_tm) 1881*0Sstevel@tonic-gate { 1882*0Sstevel@tonic-gate char c, *p; 1883*0Sstevel@tonic-gate 1884*0Sstevel@tonic-gate if (!k_tm) return NULL; 1885*0Sstevel@tonic-gate if (gtime == NULL || gtime->length < 14) return NULL; 1886*0Sstevel@tonic-gate if (gtime->data == NULL) return NULL; 1887*0Sstevel@tonic-gate 1888*0Sstevel@tonic-gate p = (char *)>ime->data[14]; 1889*0Sstevel@tonic-gate 1890*0Sstevel@tonic-gate c = *p; *p = '\0'; p -= 2; k_tm->tm_sec = atoi(p); *(p+2) = c; 1891*0Sstevel@tonic-gate c = *p; *p = '\0'; p -= 2; k_tm->tm_min = atoi(p); *(p+2) = c; 1892*0Sstevel@tonic-gate c = *p; *p = '\0'; p -= 2; k_tm->tm_hour = atoi(p); *(p+2) = c; 1893*0Sstevel@tonic-gate c = *p; *p = '\0'; p -= 2; k_tm->tm_mday = atoi(p); *(p+2) = c; 1894*0Sstevel@tonic-gate c = *p; *p = '\0'; p -= 2; k_tm->tm_mon = atoi(p)-1; *(p+2) = c; 1895*0Sstevel@tonic-gate c = *p; *p = '\0'; p -= 4; k_tm->tm_year = atoi(p)-1900; *(p+4) = c; 1896*0Sstevel@tonic-gate 1897*0Sstevel@tonic-gate return k_tm; 1898*0Sstevel@tonic-gate } 1899*0Sstevel@tonic-gate 1900*0Sstevel@tonic-gate 1901*0Sstevel@tonic-gate /* Helper function for kssl_validate_times(). 1902*0Sstevel@tonic-gate ** We need context->clockskew, but krb5_context is an opaque struct. 1903*0Sstevel@tonic-gate ** So we try to sneek the clockskew out through the replay cache. 1904*0Sstevel@tonic-gate ** If that fails just return a likely default (300 seconds). 1905*0Sstevel@tonic-gate */ 1906*0Sstevel@tonic-gate krb5_deltat get_rc_clockskew(krb5_context context) 1907*0Sstevel@tonic-gate { 1908*0Sstevel@tonic-gate krb5_rcache rc; 1909*0Sstevel@tonic-gate krb5_deltat clockskew; 1910*0Sstevel@tonic-gate 1911*0Sstevel@tonic-gate if (krb5_rc_default(context, &rc)) return KSSL_CLOCKSKEW; 1912*0Sstevel@tonic-gate if (krb5_rc_initialize(context, rc, 0)) return KSSL_CLOCKSKEW; 1913*0Sstevel@tonic-gate if (krb5_rc_get_lifespan(context, rc, &clockskew)) { 1914*0Sstevel@tonic-gate clockskew = KSSL_CLOCKSKEW; 1915*0Sstevel@tonic-gate } 1916*0Sstevel@tonic-gate (void) krb5_rc_destroy(context, rc); 1917*0Sstevel@tonic-gate return clockskew; 1918*0Sstevel@tonic-gate } 1919*0Sstevel@tonic-gate 1920*0Sstevel@tonic-gate 1921*0Sstevel@tonic-gate /* kssl_validate_times() combines (and more importantly exposes) 1922*0Sstevel@tonic-gate ** the MIT KRB5 internal function krb5_validate_times() and the 1923*0Sstevel@tonic-gate ** in_clock_skew() macro. The authenticator client time is checked 1924*0Sstevel@tonic-gate ** to be within clockskew secs of the current time and the current 1925*0Sstevel@tonic-gate ** time is checked to be within the ticket start and expire times. 1926*0Sstevel@tonic-gate ** Either check may be omitted by supplying a NULL value. 1927*0Sstevel@tonic-gate ** Returns 0 for valid times, SSL_R_KRB5* error codes otherwise. 1928*0Sstevel@tonic-gate ** See Also: (Kerberos source)/krb5/lib/krb5/krb/valid_times.c 1929*0Sstevel@tonic-gate ** 20010420 VRS 1930*0Sstevel@tonic-gate */ 1931*0Sstevel@tonic-gate krb5_error_code kssl_validate_times( krb5_timestamp atime, 1932*0Sstevel@tonic-gate krb5_ticket_times *ttimes) 1933*0Sstevel@tonic-gate { 1934*0Sstevel@tonic-gate krb5_deltat skew; 1935*0Sstevel@tonic-gate krb5_timestamp start, now; 1936*0Sstevel@tonic-gate krb5_error_code rc; 1937*0Sstevel@tonic-gate krb5_context context; 1938*0Sstevel@tonic-gate 1939*0Sstevel@tonic-gate if ((rc = krb5_init_context(&context))) return SSL_R_KRB5_S_BAD_TICKET; 1940*0Sstevel@tonic-gate skew = get_rc_clockskew(context); 1941*0Sstevel@tonic-gate if ((rc = krb5_timeofday(context,&now))) return SSL_R_KRB5_S_BAD_TICKET; 1942*0Sstevel@tonic-gate krb5_free_context(context); 1943*0Sstevel@tonic-gate 1944*0Sstevel@tonic-gate if (atime && labs(atime - now) >= skew) return SSL_R_KRB5_S_TKT_SKEW; 1945*0Sstevel@tonic-gate 1946*0Sstevel@tonic-gate if (! ttimes) return 0; 1947*0Sstevel@tonic-gate 1948*0Sstevel@tonic-gate start = (ttimes->starttime != 0)? ttimes->starttime: ttimes->authtime; 1949*0Sstevel@tonic-gate if (start - now > skew) return SSL_R_KRB5_S_TKT_NYV; 1950*0Sstevel@tonic-gate if ((now - ttimes->endtime) > skew) return SSL_R_KRB5_S_TKT_EXPIRED; 1951*0Sstevel@tonic-gate 1952*0Sstevel@tonic-gate #ifdef KSSL_DEBUG 1953*0Sstevel@tonic-gate printf("kssl_validate_times: %d |<- | %d - %d | < %d ->| %d\n", 1954*0Sstevel@tonic-gate start, atime, now, skew, ttimes->endtime); 1955*0Sstevel@tonic-gate #endif /* KSSL_DEBUG */ 1956*0Sstevel@tonic-gate 1957*0Sstevel@tonic-gate return 0; 1958*0Sstevel@tonic-gate } 1959*0Sstevel@tonic-gate 1960*0Sstevel@tonic-gate 1961*0Sstevel@tonic-gate /* Decode and decrypt given DER-encoded authenticator, then pass 1962*0Sstevel@tonic-gate ** authenticator ctime back in *atimep (or 0 if time unavailable). 1963*0Sstevel@tonic-gate ** Returns krb5_error_code and kssl_err on error. A NULL 1964*0Sstevel@tonic-gate ** authenticator (authentp->length == 0) is not considered an error. 1965*0Sstevel@tonic-gate ** Note that kssl_check_authent() makes use of the KRB5 session key; 1966*0Sstevel@tonic-gate ** you must call kssl_sget_tkt() to get the key before calling this routine. 1967*0Sstevel@tonic-gate */ 1968*0Sstevel@tonic-gate krb5_error_code kssl_check_authent( 1969*0Sstevel@tonic-gate /* IN */ KSSL_CTX *kssl_ctx, 1970*0Sstevel@tonic-gate /* IN */ krb5_data *authentp, 1971*0Sstevel@tonic-gate /* OUT */ krb5_timestamp *atimep, 1972*0Sstevel@tonic-gate /* OUT */ KSSL_ERR *kssl_err ) 1973*0Sstevel@tonic-gate { 1974*0Sstevel@tonic-gate krb5_error_code krb5rc = 0; 1975*0Sstevel@tonic-gate KRB5_ENCDATA *dec_authent = NULL; 1976*0Sstevel@tonic-gate KRB5_AUTHENTBODY *auth = NULL; 1977*0Sstevel@tonic-gate krb5_enctype enctype; 1978*0Sstevel@tonic-gate EVP_CIPHER_CTX ciph_ctx; 1979*0Sstevel@tonic-gate const EVP_CIPHER *enc = NULL; 1980*0Sstevel@tonic-gate unsigned char iv[EVP_MAX_IV_LENGTH]; 1981*0Sstevel@tonic-gate unsigned char *p, *unenc_authent; 1982*0Sstevel@tonic-gate int outl, unencbufsize; 1983*0Sstevel@tonic-gate struct tm tm_time, *tm_l, *tm_g; 1984*0Sstevel@tonic-gate time_t now, tl, tg, tr, tz_offset; 1985*0Sstevel@tonic-gate 1986*0Sstevel@tonic-gate EVP_CIPHER_CTX_init(&ciph_ctx); 1987*0Sstevel@tonic-gate *atimep = 0; 1988*0Sstevel@tonic-gate kssl_err_set(kssl_err, 0, ""); 1989*0Sstevel@tonic-gate 1990*0Sstevel@tonic-gate #ifndef KRB5CHECKAUTH 1991*0Sstevel@tonic-gate authentp = NULL; 1992*0Sstevel@tonic-gate #else 1993*0Sstevel@tonic-gate #if KRB5CHECKAUTH == 0 1994*0Sstevel@tonic-gate authentp = NULL; 1995*0Sstevel@tonic-gate #endif 1996*0Sstevel@tonic-gate #endif /* KRB5CHECKAUTH */ 1997*0Sstevel@tonic-gate 1998*0Sstevel@tonic-gate if (authentp == NULL || authentp->length == 0) return 0; 1999*0Sstevel@tonic-gate 2000*0Sstevel@tonic-gate #ifdef KSSL_DEBUG 2001*0Sstevel@tonic-gate { 2002*0Sstevel@tonic-gate unsigned int ui; 2003*0Sstevel@tonic-gate printf("kssl_check_authent: authenticator[%d]:\n",authentp->length); 2004*0Sstevel@tonic-gate p = authentp->data; 2005*0Sstevel@tonic-gate for (ui=0; ui < authentp->length; ui++) printf("%02x ",p[ui]); 2006*0Sstevel@tonic-gate printf("\n"); 2007*0Sstevel@tonic-gate } 2008*0Sstevel@tonic-gate #endif /* KSSL_DEBUG */ 2009*0Sstevel@tonic-gate 2010*0Sstevel@tonic-gate unencbufsize = 2 * authentp->length; 2011*0Sstevel@tonic-gate if ((unenc_authent = calloc(1, unencbufsize)) == NULL) 2012*0Sstevel@tonic-gate { 2013*0Sstevel@tonic-gate kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, 2014*0Sstevel@tonic-gate "Unable to allocate authenticator buffer.\n"); 2015*0Sstevel@tonic-gate krb5rc = KRB5KRB_ERR_GENERIC; 2016*0Sstevel@tonic-gate goto err; 2017*0Sstevel@tonic-gate } 2018*0Sstevel@tonic-gate 2019*0Sstevel@tonic-gate p = (unsigned char *)authentp->data; 2020*0Sstevel@tonic-gate if ((dec_authent = d2i_KRB5_ENCDATA(NULL, &p, 2021*0Sstevel@tonic-gate (long) authentp->length)) == NULL) 2022*0Sstevel@tonic-gate { 2023*0Sstevel@tonic-gate kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, 2024*0Sstevel@tonic-gate "Error decoding authenticator.\n"); 2025*0Sstevel@tonic-gate krb5rc = KRB5KRB_AP_ERR_BAD_INTEGRITY; 2026*0Sstevel@tonic-gate goto err; 2027*0Sstevel@tonic-gate } 2028*0Sstevel@tonic-gate 2029*0Sstevel@tonic-gate enctype = dec_authent->etype->data[0]; /* should = kssl_ctx->enctype */ 2030*0Sstevel@tonic-gate #if !defined(KRB5_MIT_OLD11) 2031*0Sstevel@tonic-gate switch ( enctype ) { 2032*0Sstevel@tonic-gate case ENCTYPE_DES3_CBC_SHA1: /* EVP_des_ede3_cbc(); */ 2033*0Sstevel@tonic-gate case ENCTYPE_DES3_CBC_SHA: 2034*0Sstevel@tonic-gate case ENCTYPE_DES3_CBC_RAW: 2035*0Sstevel@tonic-gate krb5rc = 0; /* Skip, can't handle derived keys */ 2036*0Sstevel@tonic-gate goto err; 2037*0Sstevel@tonic-gate } 2038*0Sstevel@tonic-gate #endif 2039*0Sstevel@tonic-gate enc = kssl_map_enc(enctype); 2040*0Sstevel@tonic-gate memset(iv, 0, sizeof iv); /* per RFC 1510 */ 2041*0Sstevel@tonic-gate 2042*0Sstevel@tonic-gate if (enc == NULL) 2043*0Sstevel@tonic-gate { 2044*0Sstevel@tonic-gate /* Disable kssl_check_authent for ENCTYPE_DES3_CBC_SHA1. 2045*0Sstevel@tonic-gate ** This enctype indicates the authenticator was encrypted 2046*0Sstevel@tonic-gate ** using key-usage derived keys which openssl cannot decrypt. 2047*0Sstevel@tonic-gate */ 2048*0Sstevel@tonic-gate goto err; 2049*0Sstevel@tonic-gate } 2050*0Sstevel@tonic-gate 2051*0Sstevel@tonic-gate if (!EVP_CipherInit(&ciph_ctx,enc,kssl_ctx->key,iv,0)) 2052*0Sstevel@tonic-gate { 2053*0Sstevel@tonic-gate kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, 2054*0Sstevel@tonic-gate "EVP_CipherInit error decrypting authenticator.\n"); 2055*0Sstevel@tonic-gate krb5rc = KRB5KRB_AP_ERR_BAD_INTEGRITY; 2056*0Sstevel@tonic-gate goto err; 2057*0Sstevel@tonic-gate } 2058*0Sstevel@tonic-gate outl = dec_authent->cipher->length; 2059*0Sstevel@tonic-gate if (!EVP_Cipher(&ciph_ctx,unenc_authent,dec_authent->cipher->data,outl)) 2060*0Sstevel@tonic-gate { 2061*0Sstevel@tonic-gate kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, 2062*0Sstevel@tonic-gate "EVP_Cipher error decrypting authenticator.\n"); 2063*0Sstevel@tonic-gate krb5rc = KRB5KRB_AP_ERR_BAD_INTEGRITY; 2064*0Sstevel@tonic-gate goto err; 2065*0Sstevel@tonic-gate } 2066*0Sstevel@tonic-gate EVP_CIPHER_CTX_cleanup(&ciph_ctx); 2067*0Sstevel@tonic-gate 2068*0Sstevel@tonic-gate #ifdef KSSL_DEBUG 2069*0Sstevel@tonic-gate printf("kssl_check_authent: decrypted authenticator[%d] =\n", outl); 2070*0Sstevel@tonic-gate for (padl=0; padl < outl; padl++) printf("%02x ",unenc_authent[padl]); 2071*0Sstevel@tonic-gate printf("\n"); 2072*0Sstevel@tonic-gate #endif /* KSSL_DEBUG */ 2073*0Sstevel@tonic-gate 2074*0Sstevel@tonic-gate if ((p = kssl_skip_confound(enctype, unenc_authent)) == NULL) 2075*0Sstevel@tonic-gate { 2076*0Sstevel@tonic-gate kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, 2077*0Sstevel@tonic-gate "confounded by authenticator.\n"); 2078*0Sstevel@tonic-gate krb5rc = KRB5KRB_AP_ERR_BAD_INTEGRITY; 2079*0Sstevel@tonic-gate goto err; 2080*0Sstevel@tonic-gate } 2081*0Sstevel@tonic-gate outl -= p - unenc_authent; 2082*0Sstevel@tonic-gate 2083*0Sstevel@tonic-gate if ((auth = (KRB5_AUTHENTBODY *) d2i_KRB5_AUTHENT(NULL, &p, 2084*0Sstevel@tonic-gate (long) outl))==NULL) 2085*0Sstevel@tonic-gate { 2086*0Sstevel@tonic-gate kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, 2087*0Sstevel@tonic-gate "Error decoding authenticator body.\n"); 2088*0Sstevel@tonic-gate krb5rc = KRB5KRB_AP_ERR_BAD_INTEGRITY; 2089*0Sstevel@tonic-gate goto err; 2090*0Sstevel@tonic-gate } 2091*0Sstevel@tonic-gate 2092*0Sstevel@tonic-gate memset(&tm_time,0,sizeof(struct tm)); 2093*0Sstevel@tonic-gate if (k_gmtime(auth->ctime, &tm_time) && 2094*0Sstevel@tonic-gate ((tr = mktime(&tm_time)) != (time_t)(-1))) 2095*0Sstevel@tonic-gate { 2096*0Sstevel@tonic-gate now = time(&now); 2097*0Sstevel@tonic-gate tm_l = localtime(&now); tl = mktime(tm_l); 2098*0Sstevel@tonic-gate tm_g = gmtime(&now); tg = mktime(tm_g); 2099*0Sstevel@tonic-gate tz_offset = tg - tl; 2100*0Sstevel@tonic-gate 2101*0Sstevel@tonic-gate *atimep = tr - tz_offset; 2102*0Sstevel@tonic-gate } 2103*0Sstevel@tonic-gate 2104*0Sstevel@tonic-gate #ifdef KSSL_DEBUG 2105*0Sstevel@tonic-gate printf("kssl_check_authent: returns %d for client time ", *atimep); 2106*0Sstevel@tonic-gate if (auth && auth->ctime && auth->ctime->length && auth->ctime->data) 2107*0Sstevel@tonic-gate printf("%.*s\n", auth->ctime->length, auth->ctime->data); 2108*0Sstevel@tonic-gate else printf("NULL\n"); 2109*0Sstevel@tonic-gate #endif /* KSSL_DEBUG */ 2110*0Sstevel@tonic-gate 2111*0Sstevel@tonic-gate err: 2112*0Sstevel@tonic-gate if (auth) KRB5_AUTHENT_free((KRB5_AUTHENT *) auth); 2113*0Sstevel@tonic-gate if (dec_authent) KRB5_ENCDATA_free(dec_authent); 2114*0Sstevel@tonic-gate if (unenc_authent) free(unenc_authent); 2115*0Sstevel@tonic-gate EVP_CIPHER_CTX_cleanup(&ciph_ctx); 2116*0Sstevel@tonic-gate return krb5rc; 2117*0Sstevel@tonic-gate } 2118*0Sstevel@tonic-gate 2119*0Sstevel@tonic-gate 2120*0Sstevel@tonic-gate /* Replaces krb5_build_principal_ext(), with varargs length == 2 (svc, host), 2121*0Sstevel@tonic-gate ** because I dont't know how to stub varargs. 2122*0Sstevel@tonic-gate ** Returns krb5_error_code == ENOMEM on alloc error, otherwise 2123*0Sstevel@tonic-gate ** passes back newly constructed principal, which should be freed by caller. 2124*0Sstevel@tonic-gate */ 2125*0Sstevel@tonic-gate krb5_error_code kssl_build_principal_2( 2126*0Sstevel@tonic-gate /* UPDATE */ krb5_context context, 2127*0Sstevel@tonic-gate /* OUT */ krb5_principal *princ, 2128*0Sstevel@tonic-gate /* IN */ int rlen, const char *realm, 2129*0Sstevel@tonic-gate /* IN */ int slen, const char *svc, 2130*0Sstevel@tonic-gate /* IN */ int hlen, const char *host) 2131*0Sstevel@tonic-gate { 2132*0Sstevel@tonic-gate krb5_data *p_data = NULL; 2133*0Sstevel@tonic-gate krb5_principal new_p = NULL; 2134*0Sstevel@tonic-gate char *new_r = NULL; 2135*0Sstevel@tonic-gate 2136*0Sstevel@tonic-gate if ((p_data = (krb5_data *) calloc(2, sizeof(krb5_data))) == NULL || 2137*0Sstevel@tonic-gate (new_p = (krb5_principal) calloc(1, sizeof(krb5_principal_data))) 2138*0Sstevel@tonic-gate == NULL) goto err; 2139*0Sstevel@tonic-gate new_p->length = 2; 2140*0Sstevel@tonic-gate new_p->data = p_data; 2141*0Sstevel@tonic-gate 2142*0Sstevel@tonic-gate if ((new_r = calloc(1, rlen + 1)) == NULL) goto err; 2143*0Sstevel@tonic-gate memcpy(new_r, realm, rlen); 2144*0Sstevel@tonic-gate krb5_princ_set_realm_length(context, new_p, rlen); 2145*0Sstevel@tonic-gate krb5_princ_set_realm_data(context, new_p, new_r); 2146*0Sstevel@tonic-gate 2147*0Sstevel@tonic-gate if ((new_p->data[0].data = calloc(1, slen + 1)) == NULL) goto err; 2148*0Sstevel@tonic-gate memcpy(new_p->data[0].data, svc, slen); 2149*0Sstevel@tonic-gate new_p->data[0].length = slen; 2150*0Sstevel@tonic-gate 2151*0Sstevel@tonic-gate if ((new_p->data[1].data = calloc(1, hlen + 1)) == NULL) goto err; 2152*0Sstevel@tonic-gate memcpy(new_p->data[1].data, host, hlen); 2153*0Sstevel@tonic-gate new_p->data[1].length = hlen; 2154*0Sstevel@tonic-gate 2155*0Sstevel@tonic-gate krb5_princ_type(context, new_p) = KRB5_NT_UNKNOWN; 2156*0Sstevel@tonic-gate *princ = new_p; 2157*0Sstevel@tonic-gate return 0; 2158*0Sstevel@tonic-gate 2159*0Sstevel@tonic-gate err: 2160*0Sstevel@tonic-gate if (new_p && new_p[0].data) free(new_p[0].data); 2161*0Sstevel@tonic-gate if (new_p && new_p[1].data) free(new_p[1].data); 2162*0Sstevel@tonic-gate if (new_p) free(new_p); 2163*0Sstevel@tonic-gate if (new_r) free(new_r); 2164*0Sstevel@tonic-gate return ENOMEM; 2165*0Sstevel@tonic-gate } 2166*0Sstevel@tonic-gate 2167*0Sstevel@tonic-gate 2168*0Sstevel@tonic-gate #else /* !OPENSSL_NO_KRB5 */ 2169*0Sstevel@tonic-gate 2170*0Sstevel@tonic-gate #if defined(PEDANTIC) || defined(OPENSSL_SYS_VMS) 2171*0Sstevel@tonic-gate static int dummy=(int)&dummy; 2172*0Sstevel@tonic-gate #endif 2173*0Sstevel@tonic-gate 2174*0Sstevel@tonic-gate #endif /* !OPENSSL_NO_KRB5 */ 2175*0Sstevel@tonic-gate 2176