1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 3*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 4*7c478bd9Sstevel@tonic-gate */ 5*7c478bd9Sstevel@tonic-gate 6*7c478bd9Sstevel@tonic-gate /* GSSAPI SASL plugin 7*7c478bd9Sstevel@tonic-gate * Leif Johansson 8*7c478bd9Sstevel@tonic-gate * Rob Siemborski (SASL v2 Conversion) 9*7c478bd9Sstevel@tonic-gate * $Id: gssapi.c,v 1.75 2003/07/02 13:13:42 rjs3 Exp $ 10*7c478bd9Sstevel@tonic-gate */ 11*7c478bd9Sstevel@tonic-gate /* 12*7c478bd9Sstevel@tonic-gate * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * Redistribution and use in source and binary forms, with or without 15*7c478bd9Sstevel@tonic-gate * modification, are permitted provided that the following conditions 16*7c478bd9Sstevel@tonic-gate * are met: 17*7c478bd9Sstevel@tonic-gate * 18*7c478bd9Sstevel@tonic-gate * 1. Redistributions of source code must retain the above copyright 19*7c478bd9Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer. 20*7c478bd9Sstevel@tonic-gate * 21*7c478bd9Sstevel@tonic-gate * 2. Redistributions in binary form must reproduce the above copyright 22*7c478bd9Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer in 23*7c478bd9Sstevel@tonic-gate * the documentation and/or other materials provided with the 24*7c478bd9Sstevel@tonic-gate * distribution. 25*7c478bd9Sstevel@tonic-gate * 26*7c478bd9Sstevel@tonic-gate * 3. The name "Carnegie Mellon University" must not be used to 27*7c478bd9Sstevel@tonic-gate * endorse or promote products derived from this software without 28*7c478bd9Sstevel@tonic-gate * prior written permission. For permission or any other legal 29*7c478bd9Sstevel@tonic-gate * details, please contact 30*7c478bd9Sstevel@tonic-gate * Office of Technology Transfer 31*7c478bd9Sstevel@tonic-gate * Carnegie Mellon University 32*7c478bd9Sstevel@tonic-gate * 5000 Forbes Avenue 33*7c478bd9Sstevel@tonic-gate * Pittsburgh, PA 15213-3890 34*7c478bd9Sstevel@tonic-gate * (412) 268-4387, fax: (412) 268-7395 35*7c478bd9Sstevel@tonic-gate * tech-transfer@andrew.cmu.edu 36*7c478bd9Sstevel@tonic-gate * 37*7c478bd9Sstevel@tonic-gate * 4. Redistributions of any form whatsoever must retain the following 38*7c478bd9Sstevel@tonic-gate * acknowledgment: 39*7c478bd9Sstevel@tonic-gate * "This product includes software developed by Computing Services 40*7c478bd9Sstevel@tonic-gate * at Carnegie Mellon University (http://www.cmu.edu/computing/)." 41*7c478bd9Sstevel@tonic-gate * 42*7c478bd9Sstevel@tonic-gate * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO 43*7c478bd9Sstevel@tonic-gate * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 44*7c478bd9Sstevel@tonic-gate * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE 45*7c478bd9Sstevel@tonic-gate * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 46*7c478bd9Sstevel@tonic-gate * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 47*7c478bd9Sstevel@tonic-gate * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 48*7c478bd9Sstevel@tonic-gate * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 49*7c478bd9Sstevel@tonic-gate */ 50*7c478bd9Sstevel@tonic-gate 51*7c478bd9Sstevel@tonic-gate #include <config.h> 52*7c478bd9Sstevel@tonic-gate 53*7c478bd9Sstevel@tonic-gate #ifdef HAVE_GSSAPI_H 54*7c478bd9Sstevel@tonic-gate #include <gssapi.h> 55*7c478bd9Sstevel@tonic-gate #else 56*7c478bd9Sstevel@tonic-gate #include <gssapi/gssapi.h> 57*7c478bd9Sstevel@tonic-gate #endif 58*7c478bd9Sstevel@tonic-gate 59*7c478bd9Sstevel@tonic-gate #ifdef WIN32 60*7c478bd9Sstevel@tonic-gate # include <winsock.h> 61*7c478bd9Sstevel@tonic-gate 62*7c478bd9Sstevel@tonic-gate # ifndef R_OK 63*7c478bd9Sstevel@tonic-gate # define R_OK 04 64*7c478bd9Sstevel@tonic-gate # endif 65*7c478bd9Sstevel@tonic-gate /* we also need io.h for access() prototype */ 66*7c478bd9Sstevel@tonic-gate # include <io.h> 67*7c478bd9Sstevel@tonic-gate #else 68*7c478bd9Sstevel@tonic-gate # include <sys/param.h> 69*7c478bd9Sstevel@tonic-gate # include <sys/socket.h> 70*7c478bd9Sstevel@tonic-gate # include <netinet/in.h> 71*7c478bd9Sstevel@tonic-gate # include <arpa/inet.h> 72*7c478bd9Sstevel@tonic-gate # include <netdb.h> 73*7c478bd9Sstevel@tonic-gate #endif /* WIN32 */ 74*7c478bd9Sstevel@tonic-gate #include <fcntl.h> 75*7c478bd9Sstevel@tonic-gate #include <stdio.h> 76*7c478bd9Sstevel@tonic-gate #include <sasl.h> 77*7c478bd9Sstevel@tonic-gate #include <saslutil.h> 78*7c478bd9Sstevel@tonic-gate #include <saslplug.h> 79*7c478bd9Sstevel@tonic-gate 80*7c478bd9Sstevel@tonic-gate #include "plugin_common.h" 81*7c478bd9Sstevel@tonic-gate 82*7c478bd9Sstevel@tonic-gate #ifdef HAVE_UNISTD_H 83*7c478bd9Sstevel@tonic-gate #include <unistd.h> 84*7c478bd9Sstevel@tonic-gate #endif 85*7c478bd9Sstevel@tonic-gate 86*7c478bd9Sstevel@tonic-gate #include <errno.h> 87*7c478bd9Sstevel@tonic-gate 88*7c478bd9Sstevel@tonic-gate #ifdef WIN32 89*7c478bd9Sstevel@tonic-gate /* This must be after sasl.h */ 90*7c478bd9Sstevel@tonic-gate # include "saslgssapi.h" 91*7c478bd9Sstevel@tonic-gate #endif /* WIN32 */ 92*7c478bd9Sstevel@tonic-gate 93*7c478bd9Sstevel@tonic-gate /***************************** Common Section *****************************/ 94*7c478bd9Sstevel@tonic-gate 95*7c478bd9Sstevel@tonic-gate #ifndef _SUN_SDK_ 96*7c478bd9Sstevel@tonic-gate static const char plugin_id[] = "$Id: gssapi.c,v 1.75 2003/07/02 13:13:42 rjs3 Exp $"; 97*7c478bd9Sstevel@tonic-gate #endif /* !_SUN_SDK_ */ 98*7c478bd9Sstevel@tonic-gate 99*7c478bd9Sstevel@tonic-gate static const char * GSSAPI_BLANK_STRING = ""; 100*7c478bd9Sstevel@tonic-gate 101*7c478bd9Sstevel@tonic-gate #ifndef HAVE_GSS_C_NT_HOSTBASED_SERVICE 102*7c478bd9Sstevel@tonic-gate extern gss_OID gss_nt_service_name; 103*7c478bd9Sstevel@tonic-gate #define GSS_C_NT_HOSTBASED_SERVICE gss_nt_service_name 104*7c478bd9Sstevel@tonic-gate #endif 105*7c478bd9Sstevel@tonic-gate 106*7c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_ 107*7c478bd9Sstevel@tonic-gate static int 108*7c478bd9Sstevel@tonic-gate get_oid(const sasl_utils_t *utils, gss_OID *oid); 109*7c478bd9Sstevel@tonic-gate #ifdef GSSAPI_PROTECT 110*7c478bd9Sstevel@tonic-gate DEFINE_STATIC_MUTEX(global_mutex); 111*7c478bd9Sstevel@tonic-gate #endif /* GSSAPI_PROTECT */ 112*7c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */ 113*7c478bd9Sstevel@tonic-gate 114*7c478bd9Sstevel@tonic-gate /* GSSAPI SASL Mechanism by Leif Johansson <leifj@matematik.su.se> 115*7c478bd9Sstevel@tonic-gate * inspired by the kerberos mechanism and the gssapi_server and 116*7c478bd9Sstevel@tonic-gate * gssapi_client from the heimdal distribution by Assar Westerlund 117*7c478bd9Sstevel@tonic-gate * <assar@sics.se> and Johan Danielsson <joda@pdc.kth.se>. 118*7c478bd9Sstevel@tonic-gate * See the configure.in file for details on dependencies. 119*7c478bd9Sstevel@tonic-gate * Heimdal can be obtained from http://www.pdc.kth.se/heimdal 120*7c478bd9Sstevel@tonic-gate * 121*7c478bd9Sstevel@tonic-gate * Important contributions from Sam Hartman <hartmans@fundsxpress.com>. 122*7c478bd9Sstevel@tonic-gate */ 123*7c478bd9Sstevel@tonic-gate 124*7c478bd9Sstevel@tonic-gate typedef struct context { 125*7c478bd9Sstevel@tonic-gate int state; 126*7c478bd9Sstevel@tonic-gate 127*7c478bd9Sstevel@tonic-gate gss_ctx_id_t gss_ctx; 128*7c478bd9Sstevel@tonic-gate gss_name_t client_name; 129*7c478bd9Sstevel@tonic-gate gss_name_t server_name; 130*7c478bd9Sstevel@tonic-gate gss_cred_id_t server_creds; 131*7c478bd9Sstevel@tonic-gate sasl_ssf_t limitssf, requiressf; /* application defined bounds, for the 132*7c478bd9Sstevel@tonic-gate server */ 133*7c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_ 134*7c478bd9Sstevel@tonic-gate gss_cred_id_t client_creds; 135*7c478bd9Sstevel@tonic-gate gss_OID mech_oid; 136*7c478bd9Sstevel@tonic-gate int use_authid; 137*7c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */ 138*7c478bd9Sstevel@tonic-gate const sasl_utils_t *utils; 139*7c478bd9Sstevel@tonic-gate 140*7c478bd9Sstevel@tonic-gate /* layers buffering */ 141*7c478bd9Sstevel@tonic-gate char *buffer; 142*7c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_ 143*7c478bd9Sstevel@tonic-gate unsigned bufsize; 144*7c478bd9Sstevel@tonic-gate #else 145*7c478bd9Sstevel@tonic-gate int bufsize; 146*7c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */ 147*7c478bd9Sstevel@tonic-gate char sizebuf[4]; 148*7c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_ 149*7c478bd9Sstevel@tonic-gate unsigned cursize; 150*7c478bd9Sstevel@tonic-gate unsigned size; 151*7c478bd9Sstevel@tonic-gate #else 152*7c478bd9Sstevel@tonic-gate int cursize; 153*7c478bd9Sstevel@tonic-gate int size; 154*7c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */ 155*7c478bd9Sstevel@tonic-gate unsigned needsize; 156*7c478bd9Sstevel@tonic-gate 157*7c478bd9Sstevel@tonic-gate char *encode_buf; /* For encoding/decoding mem management */ 158*7c478bd9Sstevel@tonic-gate char *decode_buf; 159*7c478bd9Sstevel@tonic-gate char *decode_once_buf; 160*7c478bd9Sstevel@tonic-gate unsigned encode_buf_len; 161*7c478bd9Sstevel@tonic-gate unsigned decode_buf_len; 162*7c478bd9Sstevel@tonic-gate unsigned decode_once_buf_len; 163*7c478bd9Sstevel@tonic-gate buffer_info_t *enc_in_buf; 164*7c478bd9Sstevel@tonic-gate 165*7c478bd9Sstevel@tonic-gate char *out_buf; /* per-step mem management */ 166*7c478bd9Sstevel@tonic-gate unsigned out_buf_len; 167*7c478bd9Sstevel@tonic-gate 168*7c478bd9Sstevel@tonic-gate char *authid; /* hold the authid between steps - server */ 169*7c478bd9Sstevel@tonic-gate const char *user; /* hold the userid between steps - client */ 170*7c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_ 171*7c478bd9Sstevel@tonic-gate const char *client_authid; 172*7c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */ 173*7c478bd9Sstevel@tonic-gate #ifdef _INTEGRATED_SOLARIS_ 174*7c478bd9Sstevel@tonic-gate void *h; 175*7c478bd9Sstevel@tonic-gate #endif /* _INTEGRATED_SOLARIS_ */ 176*7c478bd9Sstevel@tonic-gate } context_t; 177*7c478bd9Sstevel@tonic-gate 178*7c478bd9Sstevel@tonic-gate enum { 179*7c478bd9Sstevel@tonic-gate SASL_GSSAPI_STATE_AUTHNEG = 1, 180*7c478bd9Sstevel@tonic-gate SASL_GSSAPI_STATE_SSFCAP = 2, 181*7c478bd9Sstevel@tonic-gate SASL_GSSAPI_STATE_SSFREQ = 3, 182*7c478bd9Sstevel@tonic-gate SASL_GSSAPI_STATE_AUTHENTICATED = 4 183*7c478bd9Sstevel@tonic-gate }; 184*7c478bd9Sstevel@tonic-gate 185*7c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_ 186*7c478bd9Sstevel@tonic-gate /* sasl_gss_log only logs gss_display_status() error string */ 187*7c478bd9Sstevel@tonic-gate #define sasl_gss_log(x,y,z) sasl_gss_seterror_(text,y,z,1) 188*7c478bd9Sstevel@tonic-gate #define sasl_gss_seterror(x,y,z) sasl_gss_seterror_(text,y,z,0) 189*7c478bd9Sstevel@tonic-gate static void 190*7c478bd9Sstevel@tonic-gate sasl_gss_seterror_(const context_t *text, OM_uint32 maj, OM_uint32 min, 191*7c478bd9Sstevel@tonic-gate int logonly) 192*7c478bd9Sstevel@tonic-gate #else 193*7c478bd9Sstevel@tonic-gate static void 194*7c478bd9Sstevel@tonic-gate sasl_gss_seterror(const sasl_utils_t *utils, OM_uint32 maj, OM_uint32 min) 195*7c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */ 196*7c478bd9Sstevel@tonic-gate { 197*7c478bd9Sstevel@tonic-gate OM_uint32 maj_stat, min_stat; 198*7c478bd9Sstevel@tonic-gate gss_buffer_desc msg; 199*7c478bd9Sstevel@tonic-gate OM_uint32 msg_ctx; 200*7c478bd9Sstevel@tonic-gate int ret; 201*7c478bd9Sstevel@tonic-gate char *out = NULL; 202*7c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_ 203*7c478bd9Sstevel@tonic-gate unsigned len, curlen = 0; 204*7c478bd9Sstevel@tonic-gate const sasl_utils_t *utils = text->utils; 205*7c478bd9Sstevel@tonic-gate char *prefix = dgettext(TEXT_DOMAIN, "GSSAPI Error: "); 206*7c478bd9Sstevel@tonic-gate #else 207*7c478bd9Sstevel@tonic-gate size_t len, curlen = 0; 208*7c478bd9Sstevel@tonic-gate const char prefix[] = "GSSAPI Error: "; 209*7c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */ 210*7c478bd9Sstevel@tonic-gate 211*7c478bd9Sstevel@tonic-gate if(!utils) return; 212*7c478bd9Sstevel@tonic-gate 213*7c478bd9Sstevel@tonic-gate len = sizeof(prefix); 214*7c478bd9Sstevel@tonic-gate ret = _plug_buf_alloc(utils, &out, &curlen, 256); 215*7c478bd9Sstevel@tonic-gate if(ret != SASL_OK) return; 216*7c478bd9Sstevel@tonic-gate 217*7c478bd9Sstevel@tonic-gate strcpy(out, prefix); 218*7c478bd9Sstevel@tonic-gate 219*7c478bd9Sstevel@tonic-gate msg_ctx = 0; 220*7c478bd9Sstevel@tonic-gate while (1) { 221*7c478bd9Sstevel@tonic-gate maj_stat = gss_display_status(&min_stat, maj, 222*7c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_ 223*7c478bd9Sstevel@tonic-gate GSS_C_GSS_CODE, text->mech_oid, 224*7c478bd9Sstevel@tonic-gate #else 225*7c478bd9Sstevel@tonic-gate GSS_C_GSS_CODE, GSS_C_NULL_OID, 226*7c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */ 227*7c478bd9Sstevel@tonic-gate &msg_ctx, &msg); 228*7c478bd9Sstevel@tonic-gate if(GSS_ERROR(maj_stat)) { 229*7c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_ 230*7c478bd9Sstevel@tonic-gate if (logonly) { 231*7c478bd9Sstevel@tonic-gate utils->log(text->utils->conn, SASL_LOG_FAIL, 232*7c478bd9Sstevel@tonic-gate "GSSAPI Failure: (could not get major error message)"); 233*7c478bd9Sstevel@tonic-gate } else { 234*7c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */ 235*7c478bd9Sstevel@tonic-gate #ifdef _INTEGRATED_SOLARIS_ 236*7c478bd9Sstevel@tonic-gate utils->seterror(utils->conn, 0, 237*7c478bd9Sstevel@tonic-gate gettext("GSSAPI Failure " 238*7c478bd9Sstevel@tonic-gate "(could not get major error message)")); 239*7c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_ 240*7c478bd9Sstevel@tonic-gate } 241*7c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */ 242*7c478bd9Sstevel@tonic-gate #else 243*7c478bd9Sstevel@tonic-gate utils->seterror(utils->conn, 0, 244*7c478bd9Sstevel@tonic-gate "GSSAPI Failure " 245*7c478bd9Sstevel@tonic-gate "(could not get major error message)"); 246*7c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_ 247*7c478bd9Sstevel@tonic-gate } 248*7c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */ 249*7c478bd9Sstevel@tonic-gate #endif /* _INTEGRATED_SOLARIS_ */ 250*7c478bd9Sstevel@tonic-gate utils->free(out); 251*7c478bd9Sstevel@tonic-gate return; 252*7c478bd9Sstevel@tonic-gate } 253*7c478bd9Sstevel@tonic-gate 254*7c478bd9Sstevel@tonic-gate len += len + msg.length; 255*7c478bd9Sstevel@tonic-gate ret = _plug_buf_alloc(utils, &out, &curlen, len); 256*7c478bd9Sstevel@tonic-gate 257*7c478bd9Sstevel@tonic-gate if(ret != SASL_OK) { 258*7c478bd9Sstevel@tonic-gate utils->free(out); 259*7c478bd9Sstevel@tonic-gate return; 260*7c478bd9Sstevel@tonic-gate } 261*7c478bd9Sstevel@tonic-gate 262*7c478bd9Sstevel@tonic-gate strcat(out, msg.value); 263*7c478bd9Sstevel@tonic-gate 264*7c478bd9Sstevel@tonic-gate gss_release_buffer(&min_stat, &msg); 265*7c478bd9Sstevel@tonic-gate 266*7c478bd9Sstevel@tonic-gate if (!msg_ctx) 267*7c478bd9Sstevel@tonic-gate break; 268*7c478bd9Sstevel@tonic-gate } 269*7c478bd9Sstevel@tonic-gate 270*7c478bd9Sstevel@tonic-gate /* Now get the minor status */ 271*7c478bd9Sstevel@tonic-gate 272*7c478bd9Sstevel@tonic-gate len += 2; 273*7c478bd9Sstevel@tonic-gate ret = _plug_buf_alloc(utils, &out, &curlen, len); 274*7c478bd9Sstevel@tonic-gate if(ret != SASL_OK) { 275*7c478bd9Sstevel@tonic-gate utils->free(out); 276*7c478bd9Sstevel@tonic-gate return; 277*7c478bd9Sstevel@tonic-gate } 278*7c478bd9Sstevel@tonic-gate 279*7c478bd9Sstevel@tonic-gate strcat(out, " ("); 280*7c478bd9Sstevel@tonic-gate 281*7c478bd9Sstevel@tonic-gate msg_ctx = 0; 282*7c478bd9Sstevel@tonic-gate while (1) { 283*7c478bd9Sstevel@tonic-gate maj_stat = gss_display_status(&min_stat, min, 284*7c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_ 285*7c478bd9Sstevel@tonic-gate GSS_C_MECH_CODE, text->mech_oid, 286*7c478bd9Sstevel@tonic-gate #else 287*7c478bd9Sstevel@tonic-gate GSS_C_MECH_CODE, GSS_C_NULL_OID, 288*7c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */ 289*7c478bd9Sstevel@tonic-gate &msg_ctx, &msg); 290*7c478bd9Sstevel@tonic-gate if(GSS_ERROR(maj_stat)) { 291*7c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_ 292*7c478bd9Sstevel@tonic-gate if (logonly) { 293*7c478bd9Sstevel@tonic-gate utils->log(text->utils->conn, SASL_LOG_FAIL, 294*7c478bd9Sstevel@tonic-gate "GSSAPI Failure: (could not get minor error message)"); 295*7c478bd9Sstevel@tonic-gate } else { 296*7c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */ 297*7c478bd9Sstevel@tonic-gate #ifdef _INTEGRATED_SOLARIS_ 298*7c478bd9Sstevel@tonic-gate utils->seterror(utils->conn, 0, 299*7c478bd9Sstevel@tonic-gate gettext("GSSAPI Failure " 300*7c478bd9Sstevel@tonic-gate "(could not get minor error message)")); 301*7c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_ 302*7c478bd9Sstevel@tonic-gate } 303*7c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */ 304*7c478bd9Sstevel@tonic-gate #else 305*7c478bd9Sstevel@tonic-gate utils->seterror(utils->conn, 0, 306*7c478bd9Sstevel@tonic-gate "GSSAPI Failure " 307*7c478bd9Sstevel@tonic-gate "(could not get minor error message)"); 308*7c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_ 309*7c478bd9Sstevel@tonic-gate } 310*7c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */ 311*7c478bd9Sstevel@tonic-gate #endif /* _INTEGRATED_SOLARIS_ */ 312*7c478bd9Sstevel@tonic-gate utils->free(out); 313*7c478bd9Sstevel@tonic-gate return; 314*7c478bd9Sstevel@tonic-gate } 315*7c478bd9Sstevel@tonic-gate 316*7c478bd9Sstevel@tonic-gate len += len + msg.length; 317*7c478bd9Sstevel@tonic-gate ret = _plug_buf_alloc(utils, &out, &curlen, len); 318*7c478bd9Sstevel@tonic-gate 319*7c478bd9Sstevel@tonic-gate if(ret != SASL_OK) { 320*7c478bd9Sstevel@tonic-gate utils->free(out); 321*7c478bd9Sstevel@tonic-gate return; 322*7c478bd9Sstevel@tonic-gate } 323*7c478bd9Sstevel@tonic-gate 324*7c478bd9Sstevel@tonic-gate strcat(out, msg.value); 325*7c478bd9Sstevel@tonic-gate 326*7c478bd9Sstevel@tonic-gate gss_release_buffer(&min_stat, &msg); 327*7c478bd9Sstevel@tonic-gate 328*7c478bd9Sstevel@tonic-gate if (!msg_ctx) 329*7c478bd9Sstevel@tonic-gate break; 330*7c478bd9Sstevel@tonic-gate } 331*7c478bd9Sstevel@tonic-gate 332*7c478bd9Sstevel@tonic-gate len += 1; 333*7c478bd9Sstevel@tonic-gate ret = _plug_buf_alloc(utils, &out, &curlen, len); 334*7c478bd9Sstevel@tonic-gate if(ret != SASL_OK) { 335*7c478bd9Sstevel@tonic-gate utils->free(out); 336*7c478bd9Sstevel@tonic-gate return; 337*7c478bd9Sstevel@tonic-gate } 338*7c478bd9Sstevel@tonic-gate 339*7c478bd9Sstevel@tonic-gate strcat(out, ")"); 340*7c478bd9Sstevel@tonic-gate 341*7c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_ 342*7c478bd9Sstevel@tonic-gate if (logonly) { 343*7c478bd9Sstevel@tonic-gate utils->log(text->utils->conn, SASL_LOG_FAIL, out); 344*7c478bd9Sstevel@tonic-gate } else { 345*7c478bd9Sstevel@tonic-gate utils->seterror(utils->conn, 0, out); 346*7c478bd9Sstevel@tonic-gate } 347*7c478bd9Sstevel@tonic-gate #else 348*7c478bd9Sstevel@tonic-gate utils->seterror(utils->conn, 0, out); 349*7c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */ 350*7c478bd9Sstevel@tonic-gate utils->free(out); 351*7c478bd9Sstevel@tonic-gate } 352*7c478bd9Sstevel@tonic-gate 353*7c478bd9Sstevel@tonic-gate static int 354*7c478bd9Sstevel@tonic-gate sasl_gss_encode(void *context, const struct iovec *invec, unsigned numiov, 355*7c478bd9Sstevel@tonic-gate const char **output, unsigned *outputlen, int privacy) 356*7c478bd9Sstevel@tonic-gate { 357*7c478bd9Sstevel@tonic-gate context_t *text = (context_t *)context; 358*7c478bd9Sstevel@tonic-gate OM_uint32 maj_stat, min_stat; 359*7c478bd9Sstevel@tonic-gate gss_buffer_t input_token, output_token; 360*7c478bd9Sstevel@tonic-gate gss_buffer_desc real_input_token, real_output_token; 361*7c478bd9Sstevel@tonic-gate int ret; 362*7c478bd9Sstevel@tonic-gate struct buffer_info *inblob, bufinfo; 363*7c478bd9Sstevel@tonic-gate 364*7c478bd9Sstevel@tonic-gate if(!output) return SASL_BADPARAM; 365*7c478bd9Sstevel@tonic-gate 366*7c478bd9Sstevel@tonic-gate if(numiov > 1) { 367*7c478bd9Sstevel@tonic-gate ret = _plug_iovec_to_buf(text->utils, invec, numiov, &text->enc_in_buf); 368*7c478bd9Sstevel@tonic-gate if(ret != SASL_OK) return ret; 369*7c478bd9Sstevel@tonic-gate inblob = text->enc_in_buf; 370*7c478bd9Sstevel@tonic-gate } else { 371*7c478bd9Sstevel@tonic-gate bufinfo.data = invec[0].iov_base; 372*7c478bd9Sstevel@tonic-gate bufinfo.curlen = invec[0].iov_len; 373*7c478bd9Sstevel@tonic-gate inblob = &bufinfo; 374*7c478bd9Sstevel@tonic-gate } 375*7c478bd9Sstevel@tonic-gate 376*7c478bd9Sstevel@tonic-gate if (text->state != SASL_GSSAPI_STATE_AUTHENTICATED) return SASL_NOTDONE; 377*7c478bd9Sstevel@tonic-gate 378*7c478bd9Sstevel@tonic-gate input_token = &real_input_token; 379*7c478bd9Sstevel@tonic-gate 380*7c478bd9Sstevel@tonic-gate real_input_token.value = inblob->data; 381*7c478bd9Sstevel@tonic-gate real_input_token.length = inblob->curlen; 382*7c478bd9Sstevel@tonic-gate 383*7c478bd9Sstevel@tonic-gate output_token = &real_output_token; 384*7c478bd9Sstevel@tonic-gate output_token->value = NULL; 385*7c478bd9Sstevel@tonic-gate output_token->length = 0; 386*7c478bd9Sstevel@tonic-gate 387*7c478bd9Sstevel@tonic-gate #if defined _SUN_SDK_ && defined GSSAPI_PROTECT 388*7c478bd9Sstevel@tonic-gate if (LOCK_MUTEX(&global_mutex) < 0) 389*7c478bd9Sstevel@tonic-gate return (SASL_FAIL); 390*7c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ && GSSAPI_PROTECT */ 391*7c478bd9Sstevel@tonic-gate maj_stat = gss_wrap (&min_stat, 392*7c478bd9Sstevel@tonic-gate text->gss_ctx, 393*7c478bd9Sstevel@tonic-gate privacy, 394*7c478bd9Sstevel@tonic-gate GSS_C_QOP_DEFAULT, 395*7c478bd9Sstevel@tonic-gate input_token, 396*7c478bd9Sstevel@tonic-gate NULL, 397*7c478bd9Sstevel@tonic-gate output_token); 398*7c478bd9Sstevel@tonic-gate 399*7c478bd9Sstevel@tonic-gate if (GSS_ERROR(maj_stat)) 400*7c478bd9Sstevel@tonic-gate { 401*7c478bd9Sstevel@tonic-gate sasl_gss_seterror(text->utils, maj_stat, min_stat); 402*7c478bd9Sstevel@tonic-gate if (output_token->value) 403*7c478bd9Sstevel@tonic-gate gss_release_buffer(&min_stat, output_token); 404*7c478bd9Sstevel@tonic-gate #if defined _SUN_SDK_ && defined GSSAPI_PROTECT 405*7c478bd9Sstevel@tonic-gate UNLOCK_MUTEX(&global_mutex); 406*7c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ && GSSAPI_PROTECT */ 407*7c478bd9Sstevel@tonic-gate return SASL_FAIL; 408*7c478bd9Sstevel@tonic-gate } 409*7c478bd9Sstevel@tonic-gate 410*7c478bd9Sstevel@tonic-gate if (output_token->value && output) { 411*7c478bd9Sstevel@tonic-gate int len; 412*7c478bd9Sstevel@tonic-gate 413*7c478bd9Sstevel@tonic-gate ret = _plug_buf_alloc(text->utils, &(text->encode_buf), 414*7c478bd9Sstevel@tonic-gate &(text->encode_buf_len), output_token->length + 4); 415*7c478bd9Sstevel@tonic-gate 416*7c478bd9Sstevel@tonic-gate if (ret != SASL_OK) { 417*7c478bd9Sstevel@tonic-gate gss_release_buffer(&min_stat, output_token); 418*7c478bd9Sstevel@tonic-gate #if defined _SUN_SDK_ && defined GSSAPI_PROTECT 419*7c478bd9Sstevel@tonic-gate UNLOCK_MUTEX(&global_mutex); 420*7c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ && GSSAPI_PROTECT */ 421*7c478bd9Sstevel@tonic-gate return ret; 422*7c478bd9Sstevel@tonic-gate } 423*7c478bd9Sstevel@tonic-gate 424*7c478bd9Sstevel@tonic-gate len = htonl(output_token->length); 425*7c478bd9Sstevel@tonic-gate memcpy(text->encode_buf, &len, 4); 426*7c478bd9Sstevel@tonic-gate memcpy(text->encode_buf + 4, output_token->value, output_token->length); 427*7c478bd9Sstevel@tonic-gate } 428*7c478bd9Sstevel@tonic-gate 429*7c478bd9Sstevel@tonic-gate if (outputlen) { 430*7c478bd9Sstevel@tonic-gate *outputlen = output_token->length + 4; 431*7c478bd9Sstevel@tonic-gate } 432*7c478bd9Sstevel@tonic-gate 433*7c478bd9Sstevel@tonic-gate *output = text->encode_buf; 434*7c478bd9Sstevel@tonic-gate 435*7c478bd9Sstevel@tonic-gate if (output_token->value) 436*7c478bd9Sstevel@tonic-gate gss_release_buffer(&min_stat, output_token); 437*7c478bd9Sstevel@tonic-gate 438*7c478bd9Sstevel@tonic-gate #if defined _SUN_SDK_ && defined GSSAPI_PROTECT 439*7c478bd9Sstevel@tonic-gate UNLOCK_MUTEX(&global_mutex); 440*7c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ && GSSAPI_PROTECT */ 441*7c478bd9Sstevel@tonic-gate 442*7c478bd9Sstevel@tonic-gate return SASL_OK; 443*7c478bd9Sstevel@tonic-gate } 444*7c478bd9Sstevel@tonic-gate 445*7c478bd9Sstevel@tonic-gate static int gssapi_privacy_encode(void *context, const struct iovec *invec, 446*7c478bd9Sstevel@tonic-gate unsigned numiov, const char **output, 447*7c478bd9Sstevel@tonic-gate unsigned *outputlen) 448*7c478bd9Sstevel@tonic-gate { 449*7c478bd9Sstevel@tonic-gate return sasl_gss_encode(context,invec,numiov,output,outputlen,1); 450*7c478bd9Sstevel@tonic-gate } 451*7c478bd9Sstevel@tonic-gate 452*7c478bd9Sstevel@tonic-gate static int gssapi_integrity_encode(void *context, const struct iovec *invec, 453*7c478bd9Sstevel@tonic-gate unsigned numiov, const char **output, 454*7c478bd9Sstevel@tonic-gate unsigned *outputlen) 455*7c478bd9Sstevel@tonic-gate { 456*7c478bd9Sstevel@tonic-gate return sasl_gss_encode(context,invec,numiov,output,outputlen,0); 457*7c478bd9Sstevel@tonic-gate } 458*7c478bd9Sstevel@tonic-gate 459*7c478bd9Sstevel@tonic-gate #define myMIN(a,b) (((a) < (b)) ? (a) : (b)) 460*7c478bd9Sstevel@tonic-gate 461*7c478bd9Sstevel@tonic-gate static int gssapi_decode_once(void *context, 462*7c478bd9Sstevel@tonic-gate const char **input, unsigned *inputlen, 463*7c478bd9Sstevel@tonic-gate char **output, unsigned *outputlen) 464*7c478bd9Sstevel@tonic-gate { 465*7c478bd9Sstevel@tonic-gate context_t *text = (context_t *) context; 466*7c478bd9Sstevel@tonic-gate OM_uint32 maj_stat, min_stat; 467*7c478bd9Sstevel@tonic-gate gss_buffer_t input_token, output_token; 468*7c478bd9Sstevel@tonic-gate gss_buffer_desc real_input_token, real_output_token; 469*7c478bd9Sstevel@tonic-gate int result; 470*7c478bd9Sstevel@tonic-gate unsigned diff; 471*7c478bd9Sstevel@tonic-gate 472*7c478bd9Sstevel@tonic-gate if (text->state != SASL_GSSAPI_STATE_AUTHENTICATED) { 473*7c478bd9Sstevel@tonic-gate #ifdef _INTEGRATED_SOLARIS_ 474*7c478bd9Sstevel@tonic-gate SETERROR(text->utils, gettext("GSSAPI Failure")); 475*7c478bd9Sstevel@tonic-gate #else 476*7c478bd9Sstevel@tonic-gate SETERROR(text->utils, "GSSAPI Failure"); 477*7c478bd9Sstevel@tonic-gate #endif /* _INTEGRATED_SOLARIS_ */ 478*7c478bd9Sstevel@tonic-gate return SASL_NOTDONE; 479*7c478bd9Sstevel@tonic-gate } 480*7c478bd9Sstevel@tonic-gate 481*7c478bd9Sstevel@tonic-gate /* first we need to extract a packet */ 482*7c478bd9Sstevel@tonic-gate if (text->needsize > 0) { 483*7c478bd9Sstevel@tonic-gate /* how long is it? */ 484*7c478bd9Sstevel@tonic-gate int tocopy = myMIN(text->needsize, *inputlen); 485*7c478bd9Sstevel@tonic-gate 486*7c478bd9Sstevel@tonic-gate memcpy(text->sizebuf + 4 - text->needsize, *input, tocopy); 487*7c478bd9Sstevel@tonic-gate text->needsize -= tocopy; 488*7c478bd9Sstevel@tonic-gate *input += tocopy; 489*7c478bd9Sstevel@tonic-gate *inputlen -= tocopy; 490*7c478bd9Sstevel@tonic-gate 491*7c478bd9Sstevel@tonic-gate if (text->needsize == 0) { 492*7c478bd9Sstevel@tonic-gate /* got the entire size */ 493*7c478bd9Sstevel@tonic-gate memcpy(&text->size, text->sizebuf, 4); 494*7c478bd9Sstevel@tonic-gate text->size = ntohl(text->size); 495*7c478bd9Sstevel@tonic-gate text->cursize = 0; 496*7c478bd9Sstevel@tonic-gate 497*7c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_ 498*7c478bd9Sstevel@tonic-gate if (text->size > 0xFFFFFF) { 499*7c478bd9Sstevel@tonic-gate text->utils->log(text->utils->conn, SASL_LOG_ERR, 500*7c478bd9Sstevel@tonic-gate "Illegal size in sasl_gss_decode_once"); 501*7c478bd9Sstevel@tonic-gate #else 502*7c478bd9Sstevel@tonic-gate if (text->size > 0xFFFFFF || text->size <= 0) { 503*7c478bd9Sstevel@tonic-gate SETERROR(text->utils, "Illegal size in sasl_gss_decode_once"); 504*7c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */ 505*7c478bd9Sstevel@tonic-gate return SASL_FAIL; 506*7c478bd9Sstevel@tonic-gate } 507*7c478bd9Sstevel@tonic-gate 508*7c478bd9Sstevel@tonic-gate if (text->bufsize < text->size + 5) { 509*7c478bd9Sstevel@tonic-gate result = _plug_buf_alloc(text->utils, &text->buffer, 510*7c478bd9Sstevel@tonic-gate &(text->bufsize), text->size+5); 511*7c478bd9Sstevel@tonic-gate if(result != SASL_OK) return result; 512*7c478bd9Sstevel@tonic-gate } 513*7c478bd9Sstevel@tonic-gate } 514*7c478bd9Sstevel@tonic-gate if (*inputlen == 0) { 515*7c478bd9Sstevel@tonic-gate /* need more data ! */ 516*7c478bd9Sstevel@tonic-gate *outputlen = 0; 517*7c478bd9Sstevel@tonic-gate *output = NULL; 518*7c478bd9Sstevel@tonic-gate 519*7c478bd9Sstevel@tonic-gate return SASL_OK; 520*7c478bd9Sstevel@tonic-gate } 521*7c478bd9Sstevel@tonic-gate } 522*7c478bd9Sstevel@tonic-gate 523*7c478bd9Sstevel@tonic-gate diff = text->size - text->cursize; 524*7c478bd9Sstevel@tonic-gate 525*7c478bd9Sstevel@tonic-gate if (*inputlen < diff) { 526*7c478bd9Sstevel@tonic-gate /* ok, let's queue it up; not enough data */ 527*7c478bd9Sstevel@tonic-gate memcpy(text->buffer + text->cursize, *input, *inputlen); 528*7c478bd9Sstevel@tonic-gate text->cursize += *inputlen; 529*7c478bd9Sstevel@tonic-gate *inputlen = 0; 530*7c478bd9Sstevel@tonic-gate *outputlen = 0; 531*7c478bd9Sstevel@tonic-gate *output = NULL; 532*7c478bd9Sstevel@tonic-gate return SASL_OK; 533*7c478bd9Sstevel@tonic-gate } else { 534*7c478bd9Sstevel@tonic-gate memcpy(text->buffer + text->cursize, *input, diff); 535*7c478bd9Sstevel@tonic-gate *input += diff; 536*7c478bd9Sstevel@tonic-gate *inputlen -= diff; 537*7c478bd9Sstevel@tonic-gate } 538*7c478bd9Sstevel@tonic-gate 539*7c478bd9Sstevel@tonic-gate input_token = &real_input_token; 540*7c478bd9Sstevel@tonic-gate real_input_token.value = text->buffer; 541*7c478bd9Sstevel@tonic-gate real_input_token.length = text->size; 542*7c478bd9Sstevel@tonic-gate 543*7c478bd9Sstevel@tonic-gate output_token = &real_output_token; 544*7c478bd9Sstevel@tonic-gate output_token->value = NULL; 545*7c478bd9Sstevel@tonic-gate output_token->length = 0; 546*7c478bd9Sstevel@tonic-gate 547*7c478bd9Sstevel@tonic-gate #if defined _SUN_SDK_ && defined GSSAPI_PROTECT 548*7c478bd9Sstevel@tonic-gate if (LOCK_MUTEX(&global_mutex) < 0) 549*7c478bd9Sstevel@tonic-gate return (SASL_FAIL); 550*7c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ && GSSAPI_PROTECT */ 551*7c478bd9Sstevel@tonic-gate 552*7c478bd9Sstevel@tonic-gate maj_stat = gss_unwrap (&min_stat, 553*7c478bd9Sstevel@tonic-gate text->gss_ctx, 554*7c478bd9Sstevel@tonic-gate input_token, 555*7c478bd9Sstevel@tonic-gate output_token, 556*7c478bd9Sstevel@tonic-gate NULL, 557*7c478bd9Sstevel@tonic-gate NULL); 558*7c478bd9Sstevel@tonic-gate 559*7c478bd9Sstevel@tonic-gate if (GSS_ERROR(maj_stat)) 560*7c478bd9Sstevel@tonic-gate { 561*7c478bd9Sstevel@tonic-gate sasl_gss_seterror(text->utils, maj_stat, min_stat); 562*7c478bd9Sstevel@tonic-gate if (output_token->value) 563*7c478bd9Sstevel@tonic-gate gss_release_buffer(&min_stat, output_token); 564*7c478bd9Sstevel@tonic-gate #if defined _SUN_SDK_ && defined GSSAPI_PROTECT 565*7c478bd9Sstevel@tonic-gate UNLOCK_MUTEX(&global_mutex); 566*7c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ && GSSAPI_PROTECT */ 567*7c478bd9Sstevel@tonic-gate return SASL_FAIL; 568*7c478bd9Sstevel@tonic-gate } 569*7c478bd9Sstevel@tonic-gate 570*7c478bd9Sstevel@tonic-gate if (outputlen) 571*7c478bd9Sstevel@tonic-gate *outputlen = output_token->length; 572*7c478bd9Sstevel@tonic-gate 573*7c478bd9Sstevel@tonic-gate if (output_token->value) { 574*7c478bd9Sstevel@tonic-gate if (output) { 575*7c478bd9Sstevel@tonic-gate result = _plug_buf_alloc(text->utils, &text->decode_once_buf, 576*7c478bd9Sstevel@tonic-gate &text->decode_once_buf_len, 577*7c478bd9Sstevel@tonic-gate *outputlen); 578*7c478bd9Sstevel@tonic-gate if(result != SASL_OK) { 579*7c478bd9Sstevel@tonic-gate gss_release_buffer(&min_stat, output_token); 580*7c478bd9Sstevel@tonic-gate #if defined _SUN_SDK_ && defined GSSAPI_PROTECT 581*7c478bd9Sstevel@tonic-gate UNLOCK_MUTEX(&global_mutex); 582*7c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ && GSSAPI_PROTECT */ 583*7c478bd9Sstevel@tonic-gate return result; 584*7c478bd9Sstevel@tonic-gate } 585*7c478bd9Sstevel@tonic-gate *output = text->decode_once_buf; 586*7c478bd9Sstevel@tonic-gate memcpy(*output, output_token->value, *outputlen); 587*7c478bd9Sstevel@tonic-gate } 588*7c478bd9Sstevel@tonic-gate gss_release_buffer(&min_stat, output_token); 589*7c478bd9Sstevel@tonic-gate } 590*7c478bd9Sstevel@tonic-gate #if defined _SUN_SDK_ && defined GSSAPI_PROTECT 591*7c478bd9Sstevel@tonic-gate UNLOCK_MUTEX(&global_mutex); 592*7c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ && GSSAPI_PROTECT */ 593*7c478bd9Sstevel@tonic-gate 594*7c478bd9Sstevel@tonic-gate /* reset for the next packet */ 595*7c478bd9Sstevel@tonic-gate #ifndef _SUN_SDK_ 596*7c478bd9Sstevel@tonic-gate text->size = -1; 597*7c478bd9Sstevel@tonic-gate #endif /* !_SUN_SDK_ */ 598*7c478bd9Sstevel@tonic-gate text->needsize = 4; 599*7c478bd9Sstevel@tonic-gate 600*7c478bd9Sstevel@tonic-gate return SASL_OK; 601*7c478bd9Sstevel@tonic-gate } 602*7c478bd9Sstevel@tonic-gate 603*7c478bd9Sstevel@tonic-gate static int gssapi_decode(void *context, 604*7c478bd9Sstevel@tonic-gate const char *input, unsigned inputlen, 605*7c478bd9Sstevel@tonic-gate const char **output, unsigned *outputlen) 606*7c478bd9Sstevel@tonic-gate { 607*7c478bd9Sstevel@tonic-gate context_t *text = (context_t *) context; 608*7c478bd9Sstevel@tonic-gate int ret; 609*7c478bd9Sstevel@tonic-gate 610*7c478bd9Sstevel@tonic-gate ret = _plug_decode(text->utils, context, input, inputlen, 611*7c478bd9Sstevel@tonic-gate &text->decode_buf, &text->decode_buf_len, outputlen, 612*7c478bd9Sstevel@tonic-gate gssapi_decode_once); 613*7c478bd9Sstevel@tonic-gate 614*7c478bd9Sstevel@tonic-gate *output = text->decode_buf; 615*7c478bd9Sstevel@tonic-gate 616*7c478bd9Sstevel@tonic-gate return ret; 617*7c478bd9Sstevel@tonic-gate } 618*7c478bd9Sstevel@tonic-gate 619*7c478bd9Sstevel@tonic-gate static context_t *gss_new_context(const sasl_utils_t *utils) 620*7c478bd9Sstevel@tonic-gate { 621*7c478bd9Sstevel@tonic-gate context_t *ret; 622*7c478bd9Sstevel@tonic-gate 623*7c478bd9Sstevel@tonic-gate ret = utils->malloc(sizeof(context_t)); 624*7c478bd9Sstevel@tonic-gate if(!ret) return NULL; 625*7c478bd9Sstevel@tonic-gate 626*7c478bd9Sstevel@tonic-gate memset(ret,0,sizeof(context_t)); 627*7c478bd9Sstevel@tonic-gate ret->utils = utils; 628*7c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_ 629*7c478bd9Sstevel@tonic-gate ret->gss_ctx = GSS_C_NO_CONTEXT; 630*7c478bd9Sstevel@tonic-gate ret->client_name = GSS_C_NO_NAME; 631*7c478bd9Sstevel@tonic-gate ret->server_name = GSS_C_NO_NAME; 632*7c478bd9Sstevel@tonic-gate ret->server_creds = GSS_C_NO_CREDENTIAL; 633*7c478bd9Sstevel@tonic-gate ret->client_creds = GSS_C_NO_CREDENTIAL; 634*7c478bd9Sstevel@tonic-gate if (get_oid(utils, &ret->mech_oid) != SASL_OK) { 635*7c478bd9Sstevel@tonic-gate utils->free(ret); 636*7c478bd9Sstevel@tonic-gate return (NULL); 637*7c478bd9Sstevel@tonic-gate } 638*7c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */ 639*7c478bd9Sstevel@tonic-gate 640*7c478bd9Sstevel@tonic-gate ret->needsize = 4; 641*7c478bd9Sstevel@tonic-gate 642*7c478bd9Sstevel@tonic-gate return ret; 643*7c478bd9Sstevel@tonic-gate } 644*7c478bd9Sstevel@tonic-gate 645*7c478bd9Sstevel@tonic-gate static void sasl_gss_free_context_contents(context_t *text) 646*7c478bd9Sstevel@tonic-gate { 647*7c478bd9Sstevel@tonic-gate OM_uint32 maj_stat, min_stat; 648*7c478bd9Sstevel@tonic-gate 649*7c478bd9Sstevel@tonic-gate if (!text) return; 650*7c478bd9Sstevel@tonic-gate 651*7c478bd9Sstevel@tonic-gate if (text->gss_ctx != GSS_C_NO_CONTEXT) { 652*7c478bd9Sstevel@tonic-gate maj_stat = gss_delete_sec_context (&min_stat,&text->gss_ctx,GSS_C_NO_BUFFER); 653*7c478bd9Sstevel@tonic-gate text->gss_ctx = GSS_C_NO_CONTEXT; 654*7c478bd9Sstevel@tonic-gate } 655*7c478bd9Sstevel@tonic-gate 656*7c478bd9Sstevel@tonic-gate if (text->client_name != GSS_C_NO_NAME) { 657*7c478bd9Sstevel@tonic-gate maj_stat = gss_release_name(&min_stat,&text->client_name); 658*7c478bd9Sstevel@tonic-gate text->client_name = GSS_C_NO_NAME; 659*7c478bd9Sstevel@tonic-gate } 660*7c478bd9Sstevel@tonic-gate 661*7c478bd9Sstevel@tonic-gate if (text->server_name != GSS_C_NO_NAME) { 662*7c478bd9Sstevel@tonic-gate maj_stat = gss_release_name(&min_stat,&text->server_name); 663*7c478bd9Sstevel@tonic-gate text->server_name = GSS_C_NO_NAME; 664*7c478bd9Sstevel@tonic-gate } 665*7c478bd9Sstevel@tonic-gate 666*7c478bd9Sstevel@tonic-gate if ( text->server_creds != GSS_C_NO_CREDENTIAL) { 667*7c478bd9Sstevel@tonic-gate maj_stat = gss_release_cred(&min_stat, &text->server_creds); 668*7c478bd9Sstevel@tonic-gate text->server_creds = GSS_C_NO_CREDENTIAL; 669*7c478bd9Sstevel@tonic-gate } 670*7c478bd9Sstevel@tonic-gate 671*7c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_ 672*7c478bd9Sstevel@tonic-gate if ( text->client_creds != GSS_C_NO_CREDENTIAL) { 673*7c478bd9Sstevel@tonic-gate maj_stat = gss_release_cred(&min_stat, &text->client_creds); 674*7c478bd9Sstevel@tonic-gate text->client_creds = GSS_C_NO_CREDENTIAL; 675*7c478bd9Sstevel@tonic-gate } 676*7c478bd9Sstevel@tonic-gate 677*7c478bd9Sstevel@tonic-gate /* 678*7c478bd9Sstevel@tonic-gate * Note that the oid returned by rpc_gss_mech_to_oid should not 679*7c478bd9Sstevel@tonic-gate * be released 680*7c478bd9Sstevel@tonic-gate */ 681*7c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */ 682*7c478bd9Sstevel@tonic-gate 683*7c478bd9Sstevel@tonic-gate if (text->out_buf) { 684*7c478bd9Sstevel@tonic-gate text->utils->free(text->out_buf); 685*7c478bd9Sstevel@tonic-gate text->out_buf = NULL; 686*7c478bd9Sstevel@tonic-gate } 687*7c478bd9Sstevel@tonic-gate 688*7c478bd9Sstevel@tonic-gate if (text->encode_buf) { 689*7c478bd9Sstevel@tonic-gate text->utils->free(text->encode_buf); 690*7c478bd9Sstevel@tonic-gate text->encode_buf = NULL; 691*7c478bd9Sstevel@tonic-gate } 692*7c478bd9Sstevel@tonic-gate 693*7c478bd9Sstevel@tonic-gate if (text->decode_buf) { 694*7c478bd9Sstevel@tonic-gate text->utils->free(text->decode_buf); 695*7c478bd9Sstevel@tonic-gate text->decode_buf = NULL; 696*7c478bd9Sstevel@tonic-gate } 697*7c478bd9Sstevel@tonic-gate 698*7c478bd9Sstevel@tonic-gate if (text->decode_once_buf) { 699*7c478bd9Sstevel@tonic-gate text->utils->free(text->decode_once_buf); 700*7c478bd9Sstevel@tonic-gate text->decode_once_buf = NULL; 701*7c478bd9Sstevel@tonic-gate } 702*7c478bd9Sstevel@tonic-gate 703*7c478bd9Sstevel@tonic-gate if (text->enc_in_buf) { 704*7c478bd9Sstevel@tonic-gate if(text->enc_in_buf->data) text->utils->free(text->enc_in_buf->data); 705*7c478bd9Sstevel@tonic-gate text->utils->free(text->enc_in_buf); 706*7c478bd9Sstevel@tonic-gate text->enc_in_buf = NULL; 707*7c478bd9Sstevel@tonic-gate } 708*7c478bd9Sstevel@tonic-gate 709*7c478bd9Sstevel@tonic-gate if (text->buffer) { 710*7c478bd9Sstevel@tonic-gate text->utils->free(text->buffer); 711*7c478bd9Sstevel@tonic-gate text->buffer = NULL; 712*7c478bd9Sstevel@tonic-gate } 713*7c478bd9Sstevel@tonic-gate 714*7c478bd9Sstevel@tonic-gate if (text->authid) { /* works for both client and server */ 715*7c478bd9Sstevel@tonic-gate text->utils->free(text->authid); 716*7c478bd9Sstevel@tonic-gate text->authid = NULL; 717*7c478bd9Sstevel@tonic-gate } 718*7c478bd9Sstevel@tonic-gate } 719*7c478bd9Sstevel@tonic-gate 720*7c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_ 721*7c478bd9Sstevel@tonic-gate 722*7c478bd9Sstevel@tonic-gate #ifdef HAVE_RPC_GSS_MECH_TO_OID 723*7c478bd9Sstevel@tonic-gate #include <rpc/rpcsec_gss.h> 724*7c478bd9Sstevel@tonic-gate #endif /* HAVE_RPC_GSS_MECH_TO_OID */ 725*7c478bd9Sstevel@tonic-gate 726*7c478bd9Sstevel@tonic-gate static int 727*7c478bd9Sstevel@tonic-gate get_oid(const sasl_utils_t *utils, gss_OID *oid) 728*7c478bd9Sstevel@tonic-gate { 729*7c478bd9Sstevel@tonic-gate #ifdef HAVE_RPC_GSS_MECH_TO_OID 730*7c478bd9Sstevel@tonic-gate static gss_OID_desc kerb_v5 = 731*7c478bd9Sstevel@tonic-gate {9, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x02"}; 732*7c478bd9Sstevel@tonic-gate /* 1.2.840.113554.1.2.2 */ 733*7c478bd9Sstevel@tonic-gate *oid = &kerb_v5; 734*7c478bd9Sstevel@tonic-gate #endif /* HAVE_RPC_GSS_MECH_TO_OID */ 735*7c478bd9Sstevel@tonic-gate return (SASL_OK); 736*7c478bd9Sstevel@tonic-gate } 737*7c478bd9Sstevel@tonic-gate 738*7c478bd9Sstevel@tonic-gate static int 739*7c478bd9Sstevel@tonic-gate add_mech_to_set(context_t *text, gss_OID_set *desired_mechs) 740*7c478bd9Sstevel@tonic-gate { 741*7c478bd9Sstevel@tonic-gate OM_uint32 maj_stat, min_stat; 742*7c478bd9Sstevel@tonic-gate 743*7c478bd9Sstevel@tonic-gate maj_stat = gss_create_empty_oid_set(&min_stat, desired_mechs); 744*7c478bd9Sstevel@tonic-gate 745*7c478bd9Sstevel@tonic-gate if (GSS_ERROR(maj_stat)) { 746*7c478bd9Sstevel@tonic-gate sasl_gss_seterror(text->utils, maj_stat, min_stat); 747*7c478bd9Sstevel@tonic-gate sasl_gss_free_context_contents(text); 748*7c478bd9Sstevel@tonic-gate return SASL_FAIL; 749*7c478bd9Sstevel@tonic-gate } 750*7c478bd9Sstevel@tonic-gate 751*7c478bd9Sstevel@tonic-gate maj_stat = gss_add_oid_set_member(&min_stat, text->mech_oid, desired_mechs); 752*7c478bd9Sstevel@tonic-gate if (GSS_ERROR(maj_stat)) { 753*7c478bd9Sstevel@tonic-gate sasl_gss_seterror(text->utils, maj_stat, min_stat); 754*7c478bd9Sstevel@tonic-gate sasl_gss_free_context_contents(text); 755*7c478bd9Sstevel@tonic-gate (void) gss_release_oid_set(&min_stat, desired_mechs); 756*7c478bd9Sstevel@tonic-gate return SASL_FAIL; 757*7c478bd9Sstevel@tonic-gate } 758*7c478bd9Sstevel@tonic-gate return SASL_OK; 759*7c478bd9Sstevel@tonic-gate } 760*7c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */ 761*7c478bd9Sstevel@tonic-gate 762*7c478bd9Sstevel@tonic-gate static void gssapi_common_mech_dispose(void *conn_context, 763*7c478bd9Sstevel@tonic-gate const sasl_utils_t *utils) 764*7c478bd9Sstevel@tonic-gate { 765*7c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_ 766*7c478bd9Sstevel@tonic-gate if (conn_context == NULL) 767*7c478bd9Sstevel@tonic-gate return; 768*7c478bd9Sstevel@tonic-gate #ifdef _INTEGRATED_SOLARIS_ 769*7c478bd9Sstevel@tonic-gate convert_prompt(utils, &((context_t *)conn_context)->h, NULL); 770*7c478bd9Sstevel@tonic-gate #endif /* _INTEGRATED_SOLARIS_ */ 771*7c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */ 772*7c478bd9Sstevel@tonic-gate #if defined _SUN_SDK_ && defined GSSAPI_PROTECT 773*7c478bd9Sstevel@tonic-gate (void) LOCK_MUTEX(&global_mutex); 774*7c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ && GSSAPI_PROTECT */ 775*7c478bd9Sstevel@tonic-gate sasl_gss_free_context_contents((context_t *)(conn_context)); 776*7c478bd9Sstevel@tonic-gate #if defined _SUN_SDK_ && defined GSSAPI_PROTECT 777*7c478bd9Sstevel@tonic-gate UNLOCK_MUTEX(&global_mutex); 778*7c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ && GSSAPI_PROTECT */ 779*7c478bd9Sstevel@tonic-gate utils->free(conn_context); 780*7c478bd9Sstevel@tonic-gate } 781*7c478bd9Sstevel@tonic-gate 782*7c478bd9Sstevel@tonic-gate /***************************** Server Section *****************************/ 783*7c478bd9Sstevel@tonic-gate 784*7c478bd9Sstevel@tonic-gate static int 785*7c478bd9Sstevel@tonic-gate gssapi_server_mech_new(void *glob_context __attribute__((unused)), 786*7c478bd9Sstevel@tonic-gate sasl_server_params_t *params, 787*7c478bd9Sstevel@tonic-gate const char *challenge __attribute__((unused)), 788*7c478bd9Sstevel@tonic-gate unsigned challen __attribute__((unused)), 789*7c478bd9Sstevel@tonic-gate void **conn_context) 790*7c478bd9Sstevel@tonic-gate { 791*7c478bd9Sstevel@tonic-gate context_t *text; 792*7c478bd9Sstevel@tonic-gate 793*7c478bd9Sstevel@tonic-gate #if defined _SUN_SDK_ && defined GSSAPI_PROTECT 794*7c478bd9Sstevel@tonic-gate if (LOCK_MUTEX(&global_mutex) < 0) 795*7c478bd9Sstevel@tonic-gate return (SASL_FAIL); 796*7c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ && GSSAPI_PROTECT */ 797*7c478bd9Sstevel@tonic-gate text = gss_new_context(params->utils); 798*7c478bd9Sstevel@tonic-gate #if defined _SUN_SDK_ && defined GSSAPI_PROTECT 799*7c478bd9Sstevel@tonic-gate UNLOCK_MUTEX(&global_mutex); 800*7c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ && GSSAPI_PROTECT */ 801*7c478bd9Sstevel@tonic-gate if (text == NULL) { 802*7c478bd9Sstevel@tonic-gate #ifndef _SUN_SDK_ 803*7c478bd9Sstevel@tonic-gate MEMERROR(params->utils); 804*7c478bd9Sstevel@tonic-gate #endif /* !_SUN_SDK_ */ 805*7c478bd9Sstevel@tonic-gate return SASL_NOMEM; 806*7c478bd9Sstevel@tonic-gate } 807*7c478bd9Sstevel@tonic-gate 808*7c478bd9Sstevel@tonic-gate text->gss_ctx = GSS_C_NO_CONTEXT; 809*7c478bd9Sstevel@tonic-gate text->client_name = GSS_C_NO_NAME; 810*7c478bd9Sstevel@tonic-gate text->server_name = GSS_C_NO_NAME; 811*7c478bd9Sstevel@tonic-gate text->server_creds = GSS_C_NO_CREDENTIAL; 812*7c478bd9Sstevel@tonic-gate text->state = SASL_GSSAPI_STATE_AUTHNEG; 813*7c478bd9Sstevel@tonic-gate 814*7c478bd9Sstevel@tonic-gate *conn_context = text; 815*7c478bd9Sstevel@tonic-gate 816*7c478bd9Sstevel@tonic-gate return SASL_OK; 817*7c478bd9Sstevel@tonic-gate } 818*7c478bd9Sstevel@tonic-gate 819*7c478bd9Sstevel@tonic-gate static int 820*7c478bd9Sstevel@tonic-gate gssapi_server_mech_step(void *conn_context, 821*7c478bd9Sstevel@tonic-gate sasl_server_params_t *params, 822*7c478bd9Sstevel@tonic-gate const char *clientin, 823*7c478bd9Sstevel@tonic-gate unsigned clientinlen, 824*7c478bd9Sstevel@tonic-gate const char **serverout, 825*7c478bd9Sstevel@tonic-gate unsigned *serveroutlen, 826*7c478bd9Sstevel@tonic-gate sasl_out_params_t *oparams) 827*7c478bd9Sstevel@tonic-gate { 828*7c478bd9Sstevel@tonic-gate context_t *text = (context_t *)conn_context; 829*7c478bd9Sstevel@tonic-gate gss_buffer_t input_token, output_token; 830*7c478bd9Sstevel@tonic-gate gss_buffer_desc real_input_token, real_output_token; 831*7c478bd9Sstevel@tonic-gate OM_uint32 maj_stat, min_stat; 832*7c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_ 833*7c478bd9Sstevel@tonic-gate OM_uint32 max_input_size; 834*7c478bd9Sstevel@tonic-gate gss_OID_set desired_mechs = GSS_C_NULL_OID_SET; 835*7c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */ 836*7c478bd9Sstevel@tonic-gate gss_buffer_desc name_token; 837*7c478bd9Sstevel@tonic-gate int ret; 838*7c478bd9Sstevel@tonic-gate 839*7c478bd9Sstevel@tonic-gate input_token = &real_input_token; 840*7c478bd9Sstevel@tonic-gate output_token = &real_output_token; 841*7c478bd9Sstevel@tonic-gate output_token->value = NULL; output_token->length = 0; 842*7c478bd9Sstevel@tonic-gate input_token->value = NULL; input_token->length = 0; 843*7c478bd9Sstevel@tonic-gate 844*7c478bd9Sstevel@tonic-gate if(!serverout) { 845*7c478bd9Sstevel@tonic-gate PARAMERROR(text->utils); 846*7c478bd9Sstevel@tonic-gate return SASL_BADPARAM; 847*7c478bd9Sstevel@tonic-gate } 848*7c478bd9Sstevel@tonic-gate 849*7c478bd9Sstevel@tonic-gate *serverout = NULL; 850*7c478bd9Sstevel@tonic-gate *serveroutlen = 0; 851*7c478bd9Sstevel@tonic-gate 852*7c478bd9Sstevel@tonic-gate switch (text->state) { 853*7c478bd9Sstevel@tonic-gate 854*7c478bd9Sstevel@tonic-gate case SASL_GSSAPI_STATE_AUTHNEG: 855*7c478bd9Sstevel@tonic-gate if (text->server_name == GSS_C_NO_NAME) { /* only once */ 856*7c478bd9Sstevel@tonic-gate name_token.length = strlen(params->service) + 1 + strlen(params->serverFQDN); 857*7c478bd9Sstevel@tonic-gate name_token.value = (char *)params->utils->malloc((name_token.length + 1) * sizeof(char)); 858*7c478bd9Sstevel@tonic-gate if (name_token.value == NULL) { 859*7c478bd9Sstevel@tonic-gate MEMERROR(text->utils); 860*7c478bd9Sstevel@tonic-gate sasl_gss_free_context_contents(text); 861*7c478bd9Sstevel@tonic-gate return SASL_NOMEM; 862*7c478bd9Sstevel@tonic-gate } 863*7c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_ 864*7c478bd9Sstevel@tonic-gate snprintf(name_token.value, name_token.length + 1, 865*7c478bd9Sstevel@tonic-gate "%s@%s", params->service, params->serverFQDN); 866*7c478bd9Sstevel@tonic-gate #else 867*7c478bd9Sstevel@tonic-gate sprintf(name_token.value,"%s@%s", params->service, params->serverFQDN); 868*7c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */ 869*7c478bd9Sstevel@tonic-gate 870*7c478bd9Sstevel@tonic-gate maj_stat = gss_import_name (&min_stat, 871*7c478bd9Sstevel@tonic-gate &name_token, 872*7c478bd9Sstevel@tonic-gate GSS_C_NT_HOSTBASED_SERVICE, 873*7c478bd9Sstevel@tonic-gate &text->server_name); 874*7c478bd9Sstevel@tonic-gate 875*7c478bd9Sstevel@tonic-gate params->utils->free(name_token.value); 876*7c478bd9Sstevel@tonic-gate name_token.value = NULL; 877*7c478bd9Sstevel@tonic-gate 878*7c478bd9Sstevel@tonic-gate if (GSS_ERROR(maj_stat)) { 879*7c478bd9Sstevel@tonic-gate sasl_gss_seterror(text->utils, maj_stat, min_stat); 880*7c478bd9Sstevel@tonic-gate sasl_gss_free_context_contents(text); 881*7c478bd9Sstevel@tonic-gate return SASL_FAIL; 882*7c478bd9Sstevel@tonic-gate } 883*7c478bd9Sstevel@tonic-gate 884*7c478bd9Sstevel@tonic-gate if ( text->server_creds != GSS_C_NO_CREDENTIAL) { 885*7c478bd9Sstevel@tonic-gate maj_stat = gss_release_cred(&min_stat, &text->server_creds); 886*7c478bd9Sstevel@tonic-gate text->server_creds = GSS_C_NO_CREDENTIAL; 887*7c478bd9Sstevel@tonic-gate } 888*7c478bd9Sstevel@tonic-gate 889*7c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_ 890*7c478bd9Sstevel@tonic-gate if (text->mech_oid != GSS_C_NULL_OID) { 891*7c478bd9Sstevel@tonic-gate ret = add_mech_to_set(text, &desired_mechs); 892*7c478bd9Sstevel@tonic-gate if (ret != SASL_OK) 893*7c478bd9Sstevel@tonic-gate return (ret); 894*7c478bd9Sstevel@tonic-gate } 895*7c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */ 896*7c478bd9Sstevel@tonic-gate 897*7c478bd9Sstevel@tonic-gate maj_stat = gss_acquire_cred(&min_stat, 898*7c478bd9Sstevel@tonic-gate text->server_name, 899*7c478bd9Sstevel@tonic-gate GSS_C_INDEFINITE, 900*7c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_ 901*7c478bd9Sstevel@tonic-gate desired_mechs, 902*7c478bd9Sstevel@tonic-gate #else 903*7c478bd9Sstevel@tonic-gate GSS_C_NO_OID_SET, 904*7c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */ 905*7c478bd9Sstevel@tonic-gate GSS_C_ACCEPT, 906*7c478bd9Sstevel@tonic-gate &text->server_creds, 907*7c478bd9Sstevel@tonic-gate NULL, 908*7c478bd9Sstevel@tonic-gate NULL); 909*7c478bd9Sstevel@tonic-gate 910*7c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_ 911*7c478bd9Sstevel@tonic-gate if (desired_mechs != GSS_C_NULL_OID_SET) { 912*7c478bd9Sstevel@tonic-gate OM_uint32 min_stat2; 913*7c478bd9Sstevel@tonic-gate (void) gss_release_oid_set(&min_stat2, &desired_mechs); 914*7c478bd9Sstevel@tonic-gate } 915*7c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */ 916*7c478bd9Sstevel@tonic-gate 917*7c478bd9Sstevel@tonic-gate if (GSS_ERROR(maj_stat)) { 918*7c478bd9Sstevel@tonic-gate sasl_gss_seterror(text->utils, maj_stat, min_stat); 919*7c478bd9Sstevel@tonic-gate sasl_gss_free_context_contents(text); 920*7c478bd9Sstevel@tonic-gate return SASL_FAIL; 921*7c478bd9Sstevel@tonic-gate } 922*7c478bd9Sstevel@tonic-gate } 923*7c478bd9Sstevel@tonic-gate 924*7c478bd9Sstevel@tonic-gate if (clientinlen) { 925*7c478bd9Sstevel@tonic-gate real_input_token.value = (void *)clientin; 926*7c478bd9Sstevel@tonic-gate real_input_token.length = clientinlen; 927*7c478bd9Sstevel@tonic-gate } 928*7c478bd9Sstevel@tonic-gate 929*7c478bd9Sstevel@tonic-gate maj_stat = 930*7c478bd9Sstevel@tonic-gate gss_accept_sec_context(&min_stat, 931*7c478bd9Sstevel@tonic-gate &(text->gss_ctx), 932*7c478bd9Sstevel@tonic-gate text->server_creds, 933*7c478bd9Sstevel@tonic-gate input_token, 934*7c478bd9Sstevel@tonic-gate GSS_C_NO_CHANNEL_BINDINGS, 935*7c478bd9Sstevel@tonic-gate &text->client_name, 936*7c478bd9Sstevel@tonic-gate NULL, 937*7c478bd9Sstevel@tonic-gate output_token, 938*7c478bd9Sstevel@tonic-gate NULL, 939*7c478bd9Sstevel@tonic-gate NULL, 940*7c478bd9Sstevel@tonic-gate NULL); 941*7c478bd9Sstevel@tonic-gate 942*7c478bd9Sstevel@tonic-gate if (GSS_ERROR(maj_stat)) { 943*7c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_ 944*7c478bd9Sstevel@tonic-gate /* log the local error info, set a more generic error */ 945*7c478bd9Sstevel@tonic-gate sasl_gss_log(text->utils, maj_stat, min_stat); 946*7c478bd9Sstevel@tonic-gate text->utils->seterror(text->utils->conn, SASL_NOLOG, 947*7c478bd9Sstevel@tonic-gate gettext("GSSAPI Failure: accept security context error")); 948*7c478bd9Sstevel@tonic-gate if (output_token->value) { 949*7c478bd9Sstevel@tonic-gate gss_release_buffer(&min_stat, output_token); 950*7c478bd9Sstevel@tonic-gate } 951*7c478bd9Sstevel@tonic-gate #else 952*7c478bd9Sstevel@tonic-gate if (output_token->value) { 953*7c478bd9Sstevel@tonic-gate gss_release_buffer(&min_stat, output_token); 954*7c478bd9Sstevel@tonic-gate } 955*7c478bd9Sstevel@tonic-gate text->utils->seterror(text->utils->conn, SASL_NOLOG, "GSSAPI Failure: gss_accept_sec_context"); 956*7c478bd9Sstevel@tonic-gate text->utils->log(NULL, SASL_LOG_DEBUG, "GSSAPI Failure: gss_accept_sec_context"); 957*7c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */ 958*7c478bd9Sstevel@tonic-gate sasl_gss_free_context_contents(text); 959*7c478bd9Sstevel@tonic-gate return SASL_BADAUTH; 960*7c478bd9Sstevel@tonic-gate } 961*7c478bd9Sstevel@tonic-gate 962*7c478bd9Sstevel@tonic-gate if (serveroutlen) 963*7c478bd9Sstevel@tonic-gate *serveroutlen = output_token->length; 964*7c478bd9Sstevel@tonic-gate if (output_token->value) { 965*7c478bd9Sstevel@tonic-gate if (serverout) { 966*7c478bd9Sstevel@tonic-gate ret = _plug_buf_alloc(text->utils, &(text->out_buf), 967*7c478bd9Sstevel@tonic-gate &(text->out_buf_len), *serveroutlen); 968*7c478bd9Sstevel@tonic-gate if(ret != SASL_OK) { 969*7c478bd9Sstevel@tonic-gate gss_release_buffer(&min_stat, output_token); 970*7c478bd9Sstevel@tonic-gate return ret; 971*7c478bd9Sstevel@tonic-gate } 972*7c478bd9Sstevel@tonic-gate memcpy(text->out_buf, output_token->value, *serveroutlen); 973*7c478bd9Sstevel@tonic-gate *serverout = text->out_buf; 974*7c478bd9Sstevel@tonic-gate } 975*7c478bd9Sstevel@tonic-gate 976*7c478bd9Sstevel@tonic-gate gss_release_buffer(&min_stat, output_token); 977*7c478bd9Sstevel@tonic-gate } else { 978*7c478bd9Sstevel@tonic-gate /* No output token, send an empty string */ 979*7c478bd9Sstevel@tonic-gate *serverout = GSSAPI_BLANK_STRING; 980*7c478bd9Sstevel@tonic-gate #ifndef _SUN_SDK_ 981*7c478bd9Sstevel@tonic-gate serveroutlen = 0; 982*7c478bd9Sstevel@tonic-gate #endif /* !_SUN_SDK_ */ 983*7c478bd9Sstevel@tonic-gate } 984*7c478bd9Sstevel@tonic-gate 985*7c478bd9Sstevel@tonic-gate 986*7c478bd9Sstevel@tonic-gate if (maj_stat == GSS_S_COMPLETE) { 987*7c478bd9Sstevel@tonic-gate /* Switch to ssf negotiation */ 988*7c478bd9Sstevel@tonic-gate text->state = SASL_GSSAPI_STATE_SSFCAP; 989*7c478bd9Sstevel@tonic-gate } 990*7c478bd9Sstevel@tonic-gate 991*7c478bd9Sstevel@tonic-gate return SASL_CONTINUE; 992*7c478bd9Sstevel@tonic-gate 993*7c478bd9Sstevel@tonic-gate case SASL_GSSAPI_STATE_SSFCAP: { 994*7c478bd9Sstevel@tonic-gate unsigned char sasldata[4]; 995*7c478bd9Sstevel@tonic-gate gss_buffer_desc name_token; 996*7c478bd9Sstevel@tonic-gate #ifndef _SUN_SDK_ 997*7c478bd9Sstevel@tonic-gate gss_buffer_desc name_without_realm; 998*7c478bd9Sstevel@tonic-gate gss_name_t without = NULL; 999*7c478bd9Sstevel@tonic-gate int equal; 1000*7c478bd9Sstevel@tonic-gate #endif /* !_SUN_SDK_ */ 1001*7c478bd9Sstevel@tonic-gate 1002*7c478bd9Sstevel@tonic-gate name_token.value = NULL; 1003*7c478bd9Sstevel@tonic-gate #ifndef _SUN_SDK_ 1004*7c478bd9Sstevel@tonic-gate name_without_realm.value = NULL; 1005*7c478bd9Sstevel@tonic-gate #endif /* !_SUN_SDK_ */ 1006*7c478bd9Sstevel@tonic-gate 1007*7c478bd9Sstevel@tonic-gate /* We ignore whatever the client sent us at this stage */ 1008*7c478bd9Sstevel@tonic-gate 1009*7c478bd9Sstevel@tonic-gate maj_stat = gss_display_name (&min_stat, 1010*7c478bd9Sstevel@tonic-gate text->client_name, 1011*7c478bd9Sstevel@tonic-gate &name_token, 1012*7c478bd9Sstevel@tonic-gate NULL); 1013*7c478bd9Sstevel@tonic-gate 1014*7c478bd9Sstevel@tonic-gate if (GSS_ERROR(maj_stat)) { 1015*7c478bd9Sstevel@tonic-gate #ifndef _SUN_SDK_ 1016*7c478bd9Sstevel@tonic-gate if (name_without_realm.value) 1017*7c478bd9Sstevel@tonic-gate params->utils->free(name_without_realm.value); 1018*7c478bd9Sstevel@tonic-gate #endif /* !_SUN_SDK_ */ 1019*7c478bd9Sstevel@tonic-gate 1020*7c478bd9Sstevel@tonic-gate if (name_token.value) 1021*7c478bd9Sstevel@tonic-gate gss_release_buffer(&min_stat, &name_token); 1022*7c478bd9Sstevel@tonic-gate #ifndef _SUN_SDK_ 1023*7c478bd9Sstevel@tonic-gate if (without) 1024*7c478bd9Sstevel@tonic-gate gss_release_name(&min_stat, &without); 1025*7c478bd9Sstevel@tonic-gate #endif /* !_SUN_SDK_ */ 1026*7c478bd9Sstevel@tonic-gate #ifdef _INTEGRATED_SOLARIS_ 1027*7c478bd9Sstevel@tonic-gate SETERROR(text->utils, gettext("GSSAPI Failure")); 1028*7c478bd9Sstevel@tonic-gate #else 1029*7c478bd9Sstevel@tonic-gate SETERROR(text->utils, "GSSAPI Failure"); 1030*7c478bd9Sstevel@tonic-gate #endif /* _INTEGRATED_SOLARIS_ */ 1031*7c478bd9Sstevel@tonic-gate sasl_gss_free_context_contents(text); 1032*7c478bd9Sstevel@tonic-gate return SASL_BADAUTH; 1033*7c478bd9Sstevel@tonic-gate } 1034*7c478bd9Sstevel@tonic-gate 1035*7c478bd9Sstevel@tonic-gate #ifndef _SUN_SDK_ 1036*7c478bd9Sstevel@tonic-gate /* If the id contains a realm get the identifier for the user 1037*7c478bd9Sstevel@tonic-gate without the realm and see if it's the same id (i.e. 1038*7c478bd9Sstevel@tonic-gate tmartin == tmartin@ANDREW.CMU.EDU. If this is the case we just want 1039*7c478bd9Sstevel@tonic-gate to return the id (i.e. just "tmartin" */ 1040*7c478bd9Sstevel@tonic-gate if (strchr((char *) name_token.value, (int) '@') != NULL) { 1041*7c478bd9Sstevel@tonic-gate /* NOTE: libc malloc, as it is freed below by a gssapi internal 1042*7c478bd9Sstevel@tonic-gate * function! */ 1043*7c478bd9Sstevel@tonic-gate name_without_realm.value = malloc(strlen(name_token.value)+1); 1044*7c478bd9Sstevel@tonic-gate if (name_without_realm.value == NULL) { 1045*7c478bd9Sstevel@tonic-gate MEMERROR(text->utils); 1046*7c478bd9Sstevel@tonic-gate return SASL_NOMEM; 1047*7c478bd9Sstevel@tonic-gate } 1048*7c478bd9Sstevel@tonic-gate 1049*7c478bd9Sstevel@tonic-gate strcpy(name_without_realm.value, name_token.value); 1050*7c478bd9Sstevel@tonic-gate 1051*7c478bd9Sstevel@tonic-gate /* cut off string at '@' */ 1052*7c478bd9Sstevel@tonic-gate (strchr(name_without_realm.value,'@'))[0] = '\0'; 1053*7c478bd9Sstevel@tonic-gate 1054*7c478bd9Sstevel@tonic-gate name_without_realm.length = strlen( (char *) name_without_realm.value ); 1055*7c478bd9Sstevel@tonic-gate 1056*7c478bd9Sstevel@tonic-gate maj_stat = gss_import_name (&min_stat, 1057*7c478bd9Sstevel@tonic-gate &name_without_realm, 1058*7c478bd9Sstevel@tonic-gate /* Solaris 8/9 gss_import_name doesn't accept GSS_C_NULL_OID here, 1059*7c478bd9Sstevel@tonic-gate so use GSS_C_NT_USER_NAME instead if available. */ 1060*7c478bd9Sstevel@tonic-gate #ifdef HAVE_GSS_C_NT_USER_NAME 1061*7c478bd9Sstevel@tonic-gate GSS_C_NT_USER_NAME, 1062*7c478bd9Sstevel@tonic-gate #else 1063*7c478bd9Sstevel@tonic-gate GSS_C_NULL_OID, 1064*7c478bd9Sstevel@tonic-gate #endif 1065*7c478bd9Sstevel@tonic-gate &without); 1066*7c478bd9Sstevel@tonic-gate 1067*7c478bd9Sstevel@tonic-gate if (GSS_ERROR(maj_stat)) { 1068*7c478bd9Sstevel@tonic-gate params->utils->free(name_without_realm.value); 1069*7c478bd9Sstevel@tonic-gate if (name_token.value) 1070*7c478bd9Sstevel@tonic-gate gss_release_buffer(&min_stat, &name_token); 1071*7c478bd9Sstevel@tonic-gate if (without) 1072*7c478bd9Sstevel@tonic-gate gss_release_name(&min_stat, &without); 1073*7c478bd9Sstevel@tonic-gate SETERROR(text->utils, "GSSAPI Failure"); 1074*7c478bd9Sstevel@tonic-gate sasl_gss_free_context_contents(text); 1075*7c478bd9Sstevel@tonic-gate return SASL_BADAUTH; 1076*7c478bd9Sstevel@tonic-gate } 1077*7c478bd9Sstevel@tonic-gate 1078*7c478bd9Sstevel@tonic-gate maj_stat = gss_compare_name(&min_stat, 1079*7c478bd9Sstevel@tonic-gate text->client_name, 1080*7c478bd9Sstevel@tonic-gate without, 1081*7c478bd9Sstevel@tonic-gate &equal); 1082*7c478bd9Sstevel@tonic-gate 1083*7c478bd9Sstevel@tonic-gate if (GSS_ERROR(maj_stat)) { 1084*7c478bd9Sstevel@tonic-gate params->utils->free(name_without_realm.value); 1085*7c478bd9Sstevel@tonic-gate if (name_token.value) 1086*7c478bd9Sstevel@tonic-gate gss_release_buffer(&min_stat, &name_token); 1087*7c478bd9Sstevel@tonic-gate if (without) 1088*7c478bd9Sstevel@tonic-gate gss_release_name(&min_stat, &without); 1089*7c478bd9Sstevel@tonic-gate SETERROR(text->utils, "GSSAPI Failure"); 1090*7c478bd9Sstevel@tonic-gate sasl_gss_free_context_contents(text); 1091*7c478bd9Sstevel@tonic-gate return SASL_BADAUTH; 1092*7c478bd9Sstevel@tonic-gate } 1093*7c478bd9Sstevel@tonic-gate 1094*7c478bd9Sstevel@tonic-gate gss_release_name(&min_stat,&without); 1095*7c478bd9Sstevel@tonic-gate } else { 1096*7c478bd9Sstevel@tonic-gate equal = 0; 1097*7c478bd9Sstevel@tonic-gate } 1098*7c478bd9Sstevel@tonic-gate 1099*7c478bd9Sstevel@tonic-gate if (equal) { 1100*7c478bd9Sstevel@tonic-gate text->authid = strdup(name_without_realm.value); 1101*7c478bd9Sstevel@tonic-gate 1102*7c478bd9Sstevel@tonic-gate if (text->authid == NULL) { 1103*7c478bd9Sstevel@tonic-gate MEMERROR(params->utils); 1104*7c478bd9Sstevel@tonic-gate return SASL_NOMEM; 1105*7c478bd9Sstevel@tonic-gate } 1106*7c478bd9Sstevel@tonic-gate } else { 1107*7c478bd9Sstevel@tonic-gate text->authid = strdup(name_token.value); 1108*7c478bd9Sstevel@tonic-gate 1109*7c478bd9Sstevel@tonic-gate if (text->authid == NULL) { 1110*7c478bd9Sstevel@tonic-gate MEMERROR(params->utils); 1111*7c478bd9Sstevel@tonic-gate return SASL_NOMEM; 1112*7c478bd9Sstevel@tonic-gate } 1113*7c478bd9Sstevel@tonic-gate } 1114*7c478bd9Sstevel@tonic-gate #else 1115*7c478bd9Sstevel@tonic-gate { 1116*7c478bd9Sstevel@tonic-gate ret = _plug_strdup(params->utils, name_token.value, 1117*7c478bd9Sstevel@tonic-gate &text->authid, NULL); 1118*7c478bd9Sstevel@tonic-gate } 1119*7c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */ 1120*7c478bd9Sstevel@tonic-gate 1121*7c478bd9Sstevel@tonic-gate if (name_token.value) 1122*7c478bd9Sstevel@tonic-gate gss_release_buffer(&min_stat, &name_token); 1123*7c478bd9Sstevel@tonic-gate 1124*7c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_ 1125*7c478bd9Sstevel@tonic-gate if (ret != SASL_OK) 1126*7c478bd9Sstevel@tonic-gate return (ret); 1127*7c478bd9Sstevel@tonic-gate #else 1128*7c478bd9Sstevel@tonic-gate if (name_without_realm.value) 1129*7c478bd9Sstevel@tonic-gate params->utils->free(name_without_realm.value); 1130*7c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */ 1131*7c478bd9Sstevel@tonic-gate 1132*7c478bd9Sstevel@tonic-gate 1133*7c478bd9Sstevel@tonic-gate /* we have to decide what sort of encryption/integrity/etc., 1134*7c478bd9Sstevel@tonic-gate we support */ 1135*7c478bd9Sstevel@tonic-gate if (params->props.max_ssf < params->external_ssf) { 1136*7c478bd9Sstevel@tonic-gate text->limitssf = 0; 1137*7c478bd9Sstevel@tonic-gate } else { 1138*7c478bd9Sstevel@tonic-gate text->limitssf = params->props.max_ssf - params->external_ssf; 1139*7c478bd9Sstevel@tonic-gate } 1140*7c478bd9Sstevel@tonic-gate if (params->props.min_ssf < params->external_ssf) { 1141*7c478bd9Sstevel@tonic-gate text->requiressf = 0; 1142*7c478bd9Sstevel@tonic-gate } else { 1143*7c478bd9Sstevel@tonic-gate text->requiressf = params->props.min_ssf - params->external_ssf; 1144*7c478bd9Sstevel@tonic-gate } 1145*7c478bd9Sstevel@tonic-gate 1146*7c478bd9Sstevel@tonic-gate /* build up our security properties token */ 1147*7c478bd9Sstevel@tonic-gate if (params->props.maxbufsize > 0xFFFFFF) { 1148*7c478bd9Sstevel@tonic-gate /* make sure maxbufsize isn't too large */ 1149*7c478bd9Sstevel@tonic-gate /* maxbufsize = 0xFFFFFF */ 1150*7c478bd9Sstevel@tonic-gate sasldata[1] = sasldata[2] = sasldata[3] = 0xFF; 1151*7c478bd9Sstevel@tonic-gate } else { 1152*7c478bd9Sstevel@tonic-gate sasldata[1] = (params->props.maxbufsize >> 16) & 0xFF; 1153*7c478bd9Sstevel@tonic-gate sasldata[2] = (params->props.maxbufsize >> 8) & 0xFF; 1154*7c478bd9Sstevel@tonic-gate sasldata[3] = (params->props.maxbufsize >> 0) & 0xFF; 1155*7c478bd9Sstevel@tonic-gate } 1156*7c478bd9Sstevel@tonic-gate sasldata[0] = 0; 1157*7c478bd9Sstevel@tonic-gate if(text->requiressf != 0 && !params->props.maxbufsize) { 1158*7c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_ 1159*7c478bd9Sstevel@tonic-gate params->utils->log(params->utils->conn, SASL_LOG_ERR, 1160*7c478bd9Sstevel@tonic-gate "GSSAPI needs a security layer but one is forbidden"); 1161*7c478bd9Sstevel@tonic-gate #else 1162*7c478bd9Sstevel@tonic-gate params->utils->seterror(params->utils->conn, 0, 1163*7c478bd9Sstevel@tonic-gate "GSSAPI needs a security layer but one is forbidden"); 1164*7c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */ 1165*7c478bd9Sstevel@tonic-gate return SASL_TOOWEAK; 1166*7c478bd9Sstevel@tonic-gate } 1167*7c478bd9Sstevel@tonic-gate 1168*7c478bd9Sstevel@tonic-gate if (text->requiressf == 0) { 1169*7c478bd9Sstevel@tonic-gate sasldata[0] |= 1; /* authentication */ 1170*7c478bd9Sstevel@tonic-gate } 1171*7c478bd9Sstevel@tonic-gate if (text->requiressf <= 1 && text->limitssf >= 1 1172*7c478bd9Sstevel@tonic-gate && params->props.maxbufsize) { 1173*7c478bd9Sstevel@tonic-gate sasldata[0] |= 2; 1174*7c478bd9Sstevel@tonic-gate } 1175*7c478bd9Sstevel@tonic-gate if (text->requiressf <= 56 && text->limitssf >= 56 1176*7c478bd9Sstevel@tonic-gate && params->props.maxbufsize) { 1177*7c478bd9Sstevel@tonic-gate sasldata[0] |= 4; 1178*7c478bd9Sstevel@tonic-gate } 1179*7c478bd9Sstevel@tonic-gate 1180*7c478bd9Sstevel@tonic-gate real_input_token.value = (void *)sasldata; 1181*7c478bd9Sstevel@tonic-gate real_input_token.length = 4; 1182*7c478bd9Sstevel@tonic-gate 1183*7c478bd9Sstevel@tonic-gate maj_stat = gss_wrap(&min_stat, 1184*7c478bd9Sstevel@tonic-gate text->gss_ctx, 1185*7c478bd9Sstevel@tonic-gate 0, /* Just integrity checking here */ 1186*7c478bd9Sstevel@tonic-gate GSS_C_QOP_DEFAULT, 1187*7c478bd9Sstevel@tonic-gate input_token, 1188*7c478bd9Sstevel@tonic-gate NULL, 1189*7c478bd9Sstevel@tonic-gate output_token); 1190*7c478bd9Sstevel@tonic-gate 1191*7c478bd9Sstevel@tonic-gate if (GSS_ERROR(maj_stat)) { 1192*7c478bd9Sstevel@tonic-gate sasl_gss_seterror(text->utils, maj_stat, min_stat); 1193*7c478bd9Sstevel@tonic-gate if (output_token->value) 1194*7c478bd9Sstevel@tonic-gate gss_release_buffer(&min_stat, output_token); 1195*7c478bd9Sstevel@tonic-gate sasl_gss_free_context_contents(text); 1196*7c478bd9Sstevel@tonic-gate return SASL_FAIL; 1197*7c478bd9Sstevel@tonic-gate } 1198*7c478bd9Sstevel@tonic-gate 1199*7c478bd9Sstevel@tonic-gate 1200*7c478bd9Sstevel@tonic-gate if (serveroutlen) 1201*7c478bd9Sstevel@tonic-gate *serveroutlen = output_token->length; 1202*7c478bd9Sstevel@tonic-gate if (output_token->value) { 1203*7c478bd9Sstevel@tonic-gate if (serverout) { 1204*7c478bd9Sstevel@tonic-gate ret = _plug_buf_alloc(text->utils, &(text->out_buf), 1205*7c478bd9Sstevel@tonic-gate &(text->out_buf_len), *serveroutlen); 1206*7c478bd9Sstevel@tonic-gate if(ret != SASL_OK) { 1207*7c478bd9Sstevel@tonic-gate gss_release_buffer(&min_stat, output_token); 1208*7c478bd9Sstevel@tonic-gate return ret; 1209*7c478bd9Sstevel@tonic-gate } 1210*7c478bd9Sstevel@tonic-gate memcpy(text->out_buf, output_token->value, *serveroutlen); 1211*7c478bd9Sstevel@tonic-gate *serverout = text->out_buf; 1212*7c478bd9Sstevel@tonic-gate } 1213*7c478bd9Sstevel@tonic-gate 1214*7c478bd9Sstevel@tonic-gate gss_release_buffer(&min_stat, output_token); 1215*7c478bd9Sstevel@tonic-gate } 1216*7c478bd9Sstevel@tonic-gate 1217*7c478bd9Sstevel@tonic-gate /* Wait for ssf request and authid */ 1218*7c478bd9Sstevel@tonic-gate text->state = SASL_GSSAPI_STATE_SSFREQ; 1219*7c478bd9Sstevel@tonic-gate 1220*7c478bd9Sstevel@tonic-gate return SASL_CONTINUE; 1221*7c478bd9Sstevel@tonic-gate } 1222*7c478bd9Sstevel@tonic-gate 1223*7c478bd9Sstevel@tonic-gate case SASL_GSSAPI_STATE_SSFREQ: { 1224*7c478bd9Sstevel@tonic-gate int layerchoice; 1225*7c478bd9Sstevel@tonic-gate 1226*7c478bd9Sstevel@tonic-gate real_input_token.value = (void *)clientin; 1227*7c478bd9Sstevel@tonic-gate real_input_token.length = clientinlen; 1228*7c478bd9Sstevel@tonic-gate 1229*7c478bd9Sstevel@tonic-gate maj_stat = gss_unwrap(&min_stat, 1230*7c478bd9Sstevel@tonic-gate text->gss_ctx, 1231*7c478bd9Sstevel@tonic-gate input_token, 1232*7c478bd9Sstevel@tonic-gate output_token, 1233*7c478bd9Sstevel@tonic-gate NULL, 1234*7c478bd9Sstevel@tonic-gate NULL); 1235*7c478bd9Sstevel@tonic-gate 1236*7c478bd9Sstevel@tonic-gate if (GSS_ERROR(maj_stat)) { 1237*7c478bd9Sstevel@tonic-gate sasl_gss_seterror(text->utils, maj_stat, min_stat); 1238*7c478bd9Sstevel@tonic-gate sasl_gss_free_context_contents(text); 1239*7c478bd9Sstevel@tonic-gate return SASL_FAIL; 1240*7c478bd9Sstevel@tonic-gate } 1241*7c478bd9Sstevel@tonic-gate 1242*7c478bd9Sstevel@tonic-gate layerchoice = (int)(((char *)(output_token->value))[0]); 1243*7c478bd9Sstevel@tonic-gate if (layerchoice == 1 && text->requiressf == 0) { /* no encryption */ 1244*7c478bd9Sstevel@tonic-gate oparams->encode = NULL; 1245*7c478bd9Sstevel@tonic-gate oparams->decode = NULL; 1246*7c478bd9Sstevel@tonic-gate oparams->mech_ssf = 0; 1247*7c478bd9Sstevel@tonic-gate } else if (layerchoice == 2 && text->requiressf <= 1 && 1248*7c478bd9Sstevel@tonic-gate text->limitssf >= 1) { /* integrity */ 1249*7c478bd9Sstevel@tonic-gate oparams->encode=&gssapi_integrity_encode; 1250*7c478bd9Sstevel@tonic-gate oparams->decode=&gssapi_decode; 1251*7c478bd9Sstevel@tonic-gate oparams->mech_ssf=1; 1252*7c478bd9Sstevel@tonic-gate } else if (layerchoice == 4 && text->requiressf <= 56 && 1253*7c478bd9Sstevel@tonic-gate text->limitssf >= 56) { /* privacy */ 1254*7c478bd9Sstevel@tonic-gate oparams->encode = &gssapi_privacy_encode; 1255*7c478bd9Sstevel@tonic-gate oparams->decode = &gssapi_decode; 1256*7c478bd9Sstevel@tonic-gate oparams->mech_ssf = 56; 1257*7c478bd9Sstevel@tonic-gate } else { 1258*7c478bd9Sstevel@tonic-gate /* not a supported encryption layer */ 1259*7c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_ 1260*7c478bd9Sstevel@tonic-gate text->utils->log(text->utils->conn, SASL_LOG_ERR, 1261*7c478bd9Sstevel@tonic-gate "protocol violation: client requested invalid layer"); 1262*7c478bd9Sstevel@tonic-gate #else 1263*7c478bd9Sstevel@tonic-gate SETERROR(text->utils, 1264*7c478bd9Sstevel@tonic-gate "protocol violation: client requested invalid layer"); 1265*7c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */ 1266*7c478bd9Sstevel@tonic-gate /* Mark that we attempted negotiation */ 1267*7c478bd9Sstevel@tonic-gate oparams->mech_ssf = 2; 1268*7c478bd9Sstevel@tonic-gate if (output_token->value) 1269*7c478bd9Sstevel@tonic-gate gss_release_buffer(&min_stat, output_token); 1270*7c478bd9Sstevel@tonic-gate sasl_gss_free_context_contents(text); 1271*7c478bd9Sstevel@tonic-gate return SASL_FAIL; 1272*7c478bd9Sstevel@tonic-gate } 1273*7c478bd9Sstevel@tonic-gate 1274*7c478bd9Sstevel@tonic-gate if (output_token->length > 4) { 1275*7c478bd9Sstevel@tonic-gate int ret; 1276*7c478bd9Sstevel@tonic-gate 1277*7c478bd9Sstevel@tonic-gate ret = params->canon_user(params->utils->conn, 1278*7c478bd9Sstevel@tonic-gate ((char *) output_token->value) + 4, 1279*7c478bd9Sstevel@tonic-gate (output_token->length - 4) * sizeof(char), 1280*7c478bd9Sstevel@tonic-gate SASL_CU_AUTHZID, oparams); 1281*7c478bd9Sstevel@tonic-gate 1282*7c478bd9Sstevel@tonic-gate if (ret != SASL_OK) { 1283*7c478bd9Sstevel@tonic-gate sasl_gss_free_context_contents(text); 1284*7c478bd9Sstevel@tonic-gate return ret; 1285*7c478bd9Sstevel@tonic-gate } 1286*7c478bd9Sstevel@tonic-gate 1287*7c478bd9Sstevel@tonic-gate ret = params->canon_user(params->utils->conn, 1288*7c478bd9Sstevel@tonic-gate text->authid, 1289*7c478bd9Sstevel@tonic-gate 0, /* strlen(text->authid) */ 1290*7c478bd9Sstevel@tonic-gate SASL_CU_AUTHID, oparams); 1291*7c478bd9Sstevel@tonic-gate if (ret != SASL_OK) { 1292*7c478bd9Sstevel@tonic-gate sasl_gss_free_context_contents(text); 1293*7c478bd9Sstevel@tonic-gate return ret; 1294*7c478bd9Sstevel@tonic-gate } 1295*7c478bd9Sstevel@tonic-gate } else if(output_token->length == 4) { 1296*7c478bd9Sstevel@tonic-gate /* null authzid */ 1297*7c478bd9Sstevel@tonic-gate int ret; 1298*7c478bd9Sstevel@tonic-gate 1299*7c478bd9Sstevel@tonic-gate ret = params->canon_user(params->utils->conn, 1300*7c478bd9Sstevel@tonic-gate text->authid, 1301*7c478bd9Sstevel@tonic-gate 0, /* strlen(text->authid) */ 1302*7c478bd9Sstevel@tonic-gate SASL_CU_AUTHZID | SASL_CU_AUTHID, 1303*7c478bd9Sstevel@tonic-gate oparams); 1304*7c478bd9Sstevel@tonic-gate 1305*7c478bd9Sstevel@tonic-gate if (ret != SASL_OK) { 1306*7c478bd9Sstevel@tonic-gate sasl_gss_free_context_contents(text); 1307*7c478bd9Sstevel@tonic-gate return ret; 1308*7c478bd9Sstevel@tonic-gate } 1309*7c478bd9Sstevel@tonic-gate } else { 1310*7c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_ 1311*7c478bd9Sstevel@tonic-gate text->utils->log(text->utils->conn, SASL_LOG_ERR, 1312*7c478bd9Sstevel@tonic-gate "token too short"); 1313*7c478bd9Sstevel@tonic-gate #else 1314*7c478bd9Sstevel@tonic-gate SETERROR(text->utils, 1315*7c478bd9Sstevel@tonic-gate "token too short"); 1316*7c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */ 1317*7c478bd9Sstevel@tonic-gate gss_release_buffer(&min_stat, output_token); 1318*7c478bd9Sstevel@tonic-gate sasl_gss_free_context_contents(text); 1319*7c478bd9Sstevel@tonic-gate return SASL_FAIL; 1320*7c478bd9Sstevel@tonic-gate } 1321*7c478bd9Sstevel@tonic-gate 1322*7c478bd9Sstevel@tonic-gate /* No matter what, set the rest of the oparams */ 1323*7c478bd9Sstevel@tonic-gate oparams->maxoutbuf = 1324*7c478bd9Sstevel@tonic-gate (((unsigned char *) output_token->value)[1] << 16) | 1325*7c478bd9Sstevel@tonic-gate (((unsigned char *) output_token->value)[2] << 8) | 1326*7c478bd9Sstevel@tonic-gate (((unsigned char *) output_token->value)[3] << 0); 1327*7c478bd9Sstevel@tonic-gate 1328*7c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_ 1329*7c478bd9Sstevel@tonic-gate if (oparams->mech_ssf) { 1330*7c478bd9Sstevel@tonic-gate oparams->maxoutbuf -= 4; /* Allow for 4 byte tag */ 1331*7c478bd9Sstevel@tonic-gate maj_stat = gss_wrap_size_limit(&min_stat, 1332*7c478bd9Sstevel@tonic-gate text->gss_ctx, 1333*7c478bd9Sstevel@tonic-gate oparams->mech_ssf > 1, 1334*7c478bd9Sstevel@tonic-gate GSS_C_QOP_DEFAULT, 1335*7c478bd9Sstevel@tonic-gate oparams->maxoutbuf, 1336*7c478bd9Sstevel@tonic-gate &max_input_size); 1337*7c478bd9Sstevel@tonic-gate if (GSS_ERROR(maj_stat)) { 1338*7c478bd9Sstevel@tonic-gate sasl_gss_seterror(text->utils, maj_stat, min_stat); 1339*7c478bd9Sstevel@tonic-gate (void) gss_release_buffer(&min_stat, output_token); 1340*7c478bd9Sstevel@tonic-gate sasl_gss_free_context_contents(text); 1341*7c478bd9Sstevel@tonic-gate return (SASL_FAIL); 1342*7c478bd9Sstevel@tonic-gate } 1343*7c478bd9Sstevel@tonic-gate 1344*7c478bd9Sstevel@tonic-gate /* 1345*7c478bd9Sstevel@tonic-gate * gss_wrap_size_limit will return very big sizes for 1346*7c478bd9Sstevel@tonic-gate * small input values 1347*7c478bd9Sstevel@tonic-gate */ 1348*7c478bd9Sstevel@tonic-gate if (max_input_size < oparams->maxoutbuf) 1349*7c478bd9Sstevel@tonic-gate oparams->maxoutbuf = max_input_size; 1350*7c478bd9Sstevel@tonic-gate else { 1351*7c478bd9Sstevel@tonic-gate oparams->maxoutbuf = 0; 1352*7c478bd9Sstevel@tonic-gate } 1353*7c478bd9Sstevel@tonic-gate } 1354*7c478bd9Sstevel@tonic-gate #else 1355*7c478bd9Sstevel@tonic-gate if (oparams->mech_ssf) { 1356*7c478bd9Sstevel@tonic-gate /* xxx this is probably too big */ 1357*7c478bd9Sstevel@tonic-gate oparams->maxoutbuf -= 50; 1358*7c478bd9Sstevel@tonic-gate } 1359*7c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */ 1360*7c478bd9Sstevel@tonic-gate 1361*7c478bd9Sstevel@tonic-gate gss_release_buffer(&min_stat, output_token); 1362*7c478bd9Sstevel@tonic-gate 1363*7c478bd9Sstevel@tonic-gate text->state = SASL_GSSAPI_STATE_AUTHENTICATED; 1364*7c478bd9Sstevel@tonic-gate 1365*7c478bd9Sstevel@tonic-gate oparams->doneflag = 1; 1366*7c478bd9Sstevel@tonic-gate 1367*7c478bd9Sstevel@tonic-gate return SASL_OK; 1368*7c478bd9Sstevel@tonic-gate } 1369*7c478bd9Sstevel@tonic-gate 1370*7c478bd9Sstevel@tonic-gate default: 1371*7c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_ 1372*7c478bd9Sstevel@tonic-gate params->utils->log(text->utils->conn, SASL_LOG_ERR, 1373*7c478bd9Sstevel@tonic-gate "Invalid GSSAPI server step %d", text->state); 1374*7c478bd9Sstevel@tonic-gate #else 1375*7c478bd9Sstevel@tonic-gate params->utils->log(NULL, SASL_LOG_ERR, 1376*7c478bd9Sstevel@tonic-gate "Invalid GSSAPI server step %d\n", text->state); 1377*7c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */ 1378*7c478bd9Sstevel@tonic-gate return SASL_FAIL; 1379*7c478bd9Sstevel@tonic-gate } 1380*7c478bd9Sstevel@tonic-gate 1381*7c478bd9Sstevel@tonic-gate #ifndef _SUN_SDK_ 1382*7c478bd9Sstevel@tonic-gate return SASL_FAIL; /* should never get here */ 1383*7c478bd9Sstevel@tonic-gate #endif /* !_SUN_SDK_ */ 1384*7c478bd9Sstevel@tonic-gate } 1385*7c478bd9Sstevel@tonic-gate 1386*7c478bd9Sstevel@tonic-gate #if defined _SUN_SDK_ && defined GSSAPI_PROTECT 1387*7c478bd9Sstevel@tonic-gate static int 1388*7c478bd9Sstevel@tonic-gate _gssapi_server_mech_step(void *conn_context, 1389*7c478bd9Sstevel@tonic-gate sasl_server_params_t *params, 1390*7c478bd9Sstevel@tonic-gate const char *clientin, 1391*7c478bd9Sstevel@tonic-gate unsigned clientinlen, 1392*7c478bd9Sstevel@tonic-gate const char **serverout, 1393*7c478bd9Sstevel@tonic-gate unsigned *serveroutlen, 1394*7c478bd9Sstevel@tonic-gate sasl_out_params_t *oparams) 1395*7c478bd9Sstevel@tonic-gate { 1396*7c478bd9Sstevel@tonic-gate int ret; 1397*7c478bd9Sstevel@tonic-gate 1398*7c478bd9Sstevel@tonic-gate if (LOCK_MUTEX(&global_mutex) < 0) 1399*7c478bd9Sstevel@tonic-gate return (SASL_FAIL); 1400*7c478bd9Sstevel@tonic-gate 1401*7c478bd9Sstevel@tonic-gate ret = gssapi_server_mech_step(conn_context, params, clientin, clientinlen, 1402*7c478bd9Sstevel@tonic-gate serverout, serveroutlen, oparams); 1403*7c478bd9Sstevel@tonic-gate 1404*7c478bd9Sstevel@tonic-gate UNLOCK_MUTEX(&global_mutex); 1405*7c478bd9Sstevel@tonic-gate return (ret); 1406*7c478bd9Sstevel@tonic-gate } 1407*7c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ && GSSAPI_PROTECT */ 1408*7c478bd9Sstevel@tonic-gate 1409*7c478bd9Sstevel@tonic-gate static sasl_server_plug_t gssapi_server_plugins[] = 1410*7c478bd9Sstevel@tonic-gate { 1411*7c478bd9Sstevel@tonic-gate { 1412*7c478bd9Sstevel@tonic-gate "GSSAPI", /* mech_name */ 1413*7c478bd9Sstevel@tonic-gate 56, /* max_ssf */ 1414*7c478bd9Sstevel@tonic-gate SASL_SEC_NOPLAINTEXT 1415*7c478bd9Sstevel@tonic-gate | SASL_SEC_NOACTIVE 1416*7c478bd9Sstevel@tonic-gate | SASL_SEC_NOANONYMOUS 1417*7c478bd9Sstevel@tonic-gate | SASL_SEC_MUTUAL_AUTH, /* security_flags */ 1418*7c478bd9Sstevel@tonic-gate SASL_FEAT_WANT_CLIENT_FIRST 1419*7c478bd9Sstevel@tonic-gate | SASL_FEAT_ALLOWS_PROXY, /* features */ 1420*7c478bd9Sstevel@tonic-gate NULL, /* glob_context */ 1421*7c478bd9Sstevel@tonic-gate &gssapi_server_mech_new, /* mech_new */ 1422*7c478bd9Sstevel@tonic-gate #if defined _SUN_SDK_ && defined GSSAPI_PROTECT 1423*7c478bd9Sstevel@tonic-gate &_gssapi_server_mech_step, /* mech_step */ 1424*7c478bd9Sstevel@tonic-gate #else 1425*7c478bd9Sstevel@tonic-gate &gssapi_server_mech_step, /* mech_step */ 1426*7c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ && GSSAPI_PROTECT */ 1427*7c478bd9Sstevel@tonic-gate &gssapi_common_mech_dispose, /* mech_dispose */ 1428*7c478bd9Sstevel@tonic-gate NULL, /* mech_free */ 1429*7c478bd9Sstevel@tonic-gate NULL, /* setpass */ 1430*7c478bd9Sstevel@tonic-gate NULL, /* user_query */ 1431*7c478bd9Sstevel@tonic-gate NULL, /* idle */ 1432*7c478bd9Sstevel@tonic-gate NULL, /* mech_avail */ 1433*7c478bd9Sstevel@tonic-gate NULL /* spare */ 1434*7c478bd9Sstevel@tonic-gate } 1435*7c478bd9Sstevel@tonic-gate }; 1436*7c478bd9Sstevel@tonic-gate 1437*7c478bd9Sstevel@tonic-gate int gssapiv2_server_plug_init( 1438*7c478bd9Sstevel@tonic-gate #ifndef HAVE_GSSKRB5_REGISTER_ACCEPTOR_IDENTITY 1439*7c478bd9Sstevel@tonic-gate const sasl_utils_t *utils __attribute__((unused)), 1440*7c478bd9Sstevel@tonic-gate #else 1441*7c478bd9Sstevel@tonic-gate const sasl_utils_t *utils, 1442*7c478bd9Sstevel@tonic-gate #endif 1443*7c478bd9Sstevel@tonic-gate int maxversion, 1444*7c478bd9Sstevel@tonic-gate int *out_version, 1445*7c478bd9Sstevel@tonic-gate sasl_server_plug_t **pluglist, 1446*7c478bd9Sstevel@tonic-gate int *plugcount) 1447*7c478bd9Sstevel@tonic-gate { 1448*7c478bd9Sstevel@tonic-gate #ifdef HAVE_GSSKRB5_REGISTER_ACCEPTOR_IDENTITY 1449*7c478bd9Sstevel@tonic-gate const char *keytab = NULL; 1450*7c478bd9Sstevel@tonic-gate char keytab_path[1024]; 1451*7c478bd9Sstevel@tonic-gate unsigned int rl; 1452*7c478bd9Sstevel@tonic-gate #endif 1453*7c478bd9Sstevel@tonic-gate 1454*7c478bd9Sstevel@tonic-gate if (maxversion < SASL_SERVER_PLUG_VERSION) { 1455*7c478bd9Sstevel@tonic-gate return SASL_BADVERS; 1456*7c478bd9Sstevel@tonic-gate } 1457*7c478bd9Sstevel@tonic-gate 1458*7c478bd9Sstevel@tonic-gate #ifndef _SUN_SDK_ 1459*7c478bd9Sstevel@tonic-gate #ifdef HAVE_GSSKRB5_REGISTER_ACCEPTOR_IDENTITY 1460*7c478bd9Sstevel@tonic-gate /* unfortunately, we don't check for readability of keytab if it's 1461*7c478bd9Sstevel@tonic-gate the standard one, since we don't know where it is */ 1462*7c478bd9Sstevel@tonic-gate 1463*7c478bd9Sstevel@tonic-gate /* FIXME: This code is broken */ 1464*7c478bd9Sstevel@tonic-gate 1465*7c478bd9Sstevel@tonic-gate utils->getopt(utils->getopt_context, "GSSAPI", "keytab", &keytab, &rl); 1466*7c478bd9Sstevel@tonic-gate if (keytab != NULL) { 1467*7c478bd9Sstevel@tonic-gate if (access(keytab, R_OK) != 0) { 1468*7c478bd9Sstevel@tonic-gate utils->log(NULL, SASL_LOG_ERR, 1469*7c478bd9Sstevel@tonic-gate "Could not find keytab file: %s: %m", 1470*7c478bd9Sstevel@tonic-gate keytab, errno); 1471*7c478bd9Sstevel@tonic-gate return SASL_FAIL; 1472*7c478bd9Sstevel@tonic-gate } 1473*7c478bd9Sstevel@tonic-gate 1474*7c478bd9Sstevel@tonic-gate if(strlen(keytab) > 1024) { 1475*7c478bd9Sstevel@tonic-gate utils->log(NULL, SASL_LOG_ERR, 1476*7c478bd9Sstevel@tonic-gate "path to keytab is > 1024 characters"); 1477*7c478bd9Sstevel@tonic-gate return SASL_BUFOVER; 1478*7c478bd9Sstevel@tonic-gate } 1479*7c478bd9Sstevel@tonic-gate 1480*7c478bd9Sstevel@tonic-gate strncpy(keytab_path, keytab, 1024); 1481*7c478bd9Sstevel@tonic-gate 1482*7c478bd9Sstevel@tonic-gate gsskrb5_register_acceptor_identity(keytab_path); 1483*7c478bd9Sstevel@tonic-gate } 1484*7c478bd9Sstevel@tonic-gate #endif 1485*7c478bd9Sstevel@tonic-gate #endif /* !_SUN_SDK_ */ 1486*7c478bd9Sstevel@tonic-gate 1487*7c478bd9Sstevel@tonic-gate #ifdef _INTEGRATED_SOLARIS_ 1488*7c478bd9Sstevel@tonic-gate /* 1489*7c478bd9Sstevel@tonic-gate * Let libsasl know that we are a "Sun" plugin so that privacy 1490*7c478bd9Sstevel@tonic-gate * and integrity will be allowed. 1491*7c478bd9Sstevel@tonic-gate */ 1492*7c478bd9Sstevel@tonic-gate REG_PLUG("GSSAPI", gssapi_server_plugins); 1493*7c478bd9Sstevel@tonic-gate #endif /* _INTEGRATED_SOLARIS_ */ 1494*7c478bd9Sstevel@tonic-gate 1495*7c478bd9Sstevel@tonic-gate *out_version = SASL_SERVER_PLUG_VERSION; 1496*7c478bd9Sstevel@tonic-gate *pluglist = gssapi_server_plugins; 1497*7c478bd9Sstevel@tonic-gate *plugcount = 1; 1498*7c478bd9Sstevel@tonic-gate 1499*7c478bd9Sstevel@tonic-gate return SASL_OK; 1500*7c478bd9Sstevel@tonic-gate } 1501*7c478bd9Sstevel@tonic-gate 1502*7c478bd9Sstevel@tonic-gate /***************************** Client Section *****************************/ 1503*7c478bd9Sstevel@tonic-gate 1504*7c478bd9Sstevel@tonic-gate static int gssapi_client_mech_new(void *glob_context __attribute__((unused)), 1505*7c478bd9Sstevel@tonic-gate sasl_client_params_t *params, 1506*7c478bd9Sstevel@tonic-gate void **conn_context) 1507*7c478bd9Sstevel@tonic-gate { 1508*7c478bd9Sstevel@tonic-gate context_t *text; 1509*7c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_ 1510*7c478bd9Sstevel@tonic-gate const char *use_authid = NULL; 1511*7c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */ 1512*7c478bd9Sstevel@tonic-gate 1513*7c478bd9Sstevel@tonic-gate /* holds state are in */ 1514*7c478bd9Sstevel@tonic-gate #if defined _SUN_SDK_ && defined GSSAPI_PROTECT 1515*7c478bd9Sstevel@tonic-gate if (LOCK_MUTEX(&global_mutex) < 0) 1516*7c478bd9Sstevel@tonic-gate return (SASL_FAIL); 1517*7c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ && GSSAPI_PROTECT */ 1518*7c478bd9Sstevel@tonic-gate text = gss_new_context(params->utils); 1519*7c478bd9Sstevel@tonic-gate #if defined _SUN_SDK_ && defined GSSAPI_PROTECT 1520*7c478bd9Sstevel@tonic-gate UNLOCK_MUTEX(&global_mutex); 1521*7c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ && GSSAPI_PROTECT */ 1522*7c478bd9Sstevel@tonic-gate if (text == NULL) { 1523*7c478bd9Sstevel@tonic-gate #ifndef _SUN_SDK_ 1524*7c478bd9Sstevel@tonic-gate MEMERROR(params->utils); 1525*7c478bd9Sstevel@tonic-gate #endif /* !_SUN_SDK_ */ 1526*7c478bd9Sstevel@tonic-gate return SASL_NOMEM; 1527*7c478bd9Sstevel@tonic-gate } 1528*7c478bd9Sstevel@tonic-gate 1529*7c478bd9Sstevel@tonic-gate text->state = SASL_GSSAPI_STATE_AUTHNEG; 1530*7c478bd9Sstevel@tonic-gate text->gss_ctx = GSS_C_NO_CONTEXT; 1531*7c478bd9Sstevel@tonic-gate text->client_name = GSS_C_NO_NAME; 1532*7c478bd9Sstevel@tonic-gate text->server_creds = GSS_C_NO_CREDENTIAL; 1533*7c478bd9Sstevel@tonic-gate 1534*7c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_ 1535*7c478bd9Sstevel@tonic-gate params->utils->getopt(params->utils->getopt_context, 1536*7c478bd9Sstevel@tonic-gate "GSSAPI", "use_authid", &use_authid, NULL); 1537*7c478bd9Sstevel@tonic-gate text->use_authid = (use_authid != NULL) && 1538*7c478bd9Sstevel@tonic-gate (*use_authid == 'y' || *use_authid == 'Y' || *use_authid == '1'); 1539*7c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */ 1540*7c478bd9Sstevel@tonic-gate 1541*7c478bd9Sstevel@tonic-gate *conn_context = text; 1542*7c478bd9Sstevel@tonic-gate 1543*7c478bd9Sstevel@tonic-gate return SASL_OK; 1544*7c478bd9Sstevel@tonic-gate } 1545*7c478bd9Sstevel@tonic-gate 1546*7c478bd9Sstevel@tonic-gate static int gssapi_client_mech_step(void *conn_context, 1547*7c478bd9Sstevel@tonic-gate sasl_client_params_t *params, 1548*7c478bd9Sstevel@tonic-gate const char *serverin, 1549*7c478bd9Sstevel@tonic-gate unsigned serverinlen, 1550*7c478bd9Sstevel@tonic-gate sasl_interact_t **prompt_need, 1551*7c478bd9Sstevel@tonic-gate const char **clientout, 1552*7c478bd9Sstevel@tonic-gate unsigned *clientoutlen, 1553*7c478bd9Sstevel@tonic-gate sasl_out_params_t *oparams) 1554*7c478bd9Sstevel@tonic-gate { 1555*7c478bd9Sstevel@tonic-gate context_t *text = (context_t *)conn_context; 1556*7c478bd9Sstevel@tonic-gate gss_buffer_t input_token, output_token; 1557*7c478bd9Sstevel@tonic-gate gss_buffer_desc real_input_token, real_output_token; 1558*7c478bd9Sstevel@tonic-gate OM_uint32 maj_stat, min_stat; 1559*7c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_ 1560*7c478bd9Sstevel@tonic-gate OM_uint32 max_input_size; 1561*7c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */ 1562*7c478bd9Sstevel@tonic-gate gss_buffer_desc name_token; 1563*7c478bd9Sstevel@tonic-gate int ret; 1564*7c478bd9Sstevel@tonic-gate OM_uint32 req_flags, out_req_flags; 1565*7c478bd9Sstevel@tonic-gate input_token = &real_input_token; 1566*7c478bd9Sstevel@tonic-gate output_token = &real_output_token; 1567*7c478bd9Sstevel@tonic-gate output_token->value = NULL; 1568*7c478bd9Sstevel@tonic-gate input_token->value = NULL; 1569*7c478bd9Sstevel@tonic-gate input_token->length = 0; 1570*7c478bd9Sstevel@tonic-gate 1571*7c478bd9Sstevel@tonic-gate *clientout = NULL; 1572*7c478bd9Sstevel@tonic-gate *clientoutlen = 0; 1573*7c478bd9Sstevel@tonic-gate 1574*7c478bd9Sstevel@tonic-gate switch (text->state) { 1575*7c478bd9Sstevel@tonic-gate 1576*7c478bd9Sstevel@tonic-gate case SASL_GSSAPI_STATE_AUTHNEG: 1577*7c478bd9Sstevel@tonic-gate /* try to get the userid */ 1578*7c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_ 1579*7c478bd9Sstevel@tonic-gate if (text->user == NULL || 1580*7c478bd9Sstevel@tonic-gate (text->use_authid && text->client_authid == NULL)) { 1581*7c478bd9Sstevel@tonic-gate int auth_result = SASL_OK; 1582*7c478bd9Sstevel@tonic-gate int user_result = SASL_OK; 1583*7c478bd9Sstevel@tonic-gate 1584*7c478bd9Sstevel@tonic-gate if (text->use_authid && text->client_authid == NULL) { 1585*7c478bd9Sstevel@tonic-gate auth_result = _plug_get_authid(params->utils, 1586*7c478bd9Sstevel@tonic-gate &text->client_authid, 1587*7c478bd9Sstevel@tonic-gate prompt_need); 1588*7c478bd9Sstevel@tonic-gate 1589*7c478bd9Sstevel@tonic-gate if ((auth_result != SASL_OK) && 1590*7c478bd9Sstevel@tonic-gate (auth_result != SASL_INTERACT)) { 1591*7c478bd9Sstevel@tonic-gate sasl_gss_free_context_contents(text); 1592*7c478bd9Sstevel@tonic-gate return auth_result; 1593*7c478bd9Sstevel@tonic-gate } 1594*7c478bd9Sstevel@tonic-gate } 1595*7c478bd9Sstevel@tonic-gate if (text->user == NULL) { 1596*7c478bd9Sstevel@tonic-gate user_result = _plug_get_userid(params->utils, &text->user, 1597*7c478bd9Sstevel@tonic-gate prompt_need); 1598*7c478bd9Sstevel@tonic-gate 1599*7c478bd9Sstevel@tonic-gate if ((user_result != SASL_OK) && 1600*7c478bd9Sstevel@tonic-gate (user_result != SASL_INTERACT)) { 1601*7c478bd9Sstevel@tonic-gate sasl_gss_free_context_contents(text); 1602*7c478bd9Sstevel@tonic-gate return user_result; 1603*7c478bd9Sstevel@tonic-gate } 1604*7c478bd9Sstevel@tonic-gate } 1605*7c478bd9Sstevel@tonic-gate #else 1606*7c478bd9Sstevel@tonic-gate if (text->user == NULL) { 1607*7c478bd9Sstevel@tonic-gate int user_result = SASL_OK; 1608*7c478bd9Sstevel@tonic-gate 1609*7c478bd9Sstevel@tonic-gate user_result = _plug_get_userid(params->utils, &text->user, 1610*7c478bd9Sstevel@tonic-gate prompt_need); 1611*7c478bd9Sstevel@tonic-gate 1612*7c478bd9Sstevel@tonic-gate if ((user_result != SASL_OK) && (user_result != SASL_INTERACT)) { 1613*7c478bd9Sstevel@tonic-gate sasl_gss_free_context_contents(text); 1614*7c478bd9Sstevel@tonic-gate return user_result; 1615*7c478bd9Sstevel@tonic-gate } 1616*7c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */ 1617*7c478bd9Sstevel@tonic-gate 1618*7c478bd9Sstevel@tonic-gate /* free prompts we got */ 1619*7c478bd9Sstevel@tonic-gate if (prompt_need && *prompt_need) { 1620*7c478bd9Sstevel@tonic-gate params->utils->free(*prompt_need); 1621*7c478bd9Sstevel@tonic-gate *prompt_need = NULL; 1622*7c478bd9Sstevel@tonic-gate } 1623*7c478bd9Sstevel@tonic-gate 1624*7c478bd9Sstevel@tonic-gate /* if there are prompts not filled in */ 1625*7c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_ 1626*7c478bd9Sstevel@tonic-gate if ((user_result == SASL_INTERACT) || 1627*7c478bd9Sstevel@tonic-gate (auth_result == SASL_INTERACT)) { 1628*7c478bd9Sstevel@tonic-gate /* make the prompt list */ 1629*7c478bd9Sstevel@tonic-gate #ifdef _INTEGRATED_SOLARIS_ 1630*7c478bd9Sstevel@tonic-gate int result = _plug_make_prompts(params->utils, &text->h, 1631*7c478bd9Sstevel@tonic-gate prompt_need, 1632*7c478bd9Sstevel@tonic-gate user_result == SASL_INTERACT ? 1633*7c478bd9Sstevel@tonic-gate convert_prompt(params->utils, &text->h, 1634*7c478bd9Sstevel@tonic-gate gettext("Please enter your authorization name")) 1635*7c478bd9Sstevel@tonic-gate : NULL, NULL, 1636*7c478bd9Sstevel@tonic-gate auth_result == SASL_INTERACT ? 1637*7c478bd9Sstevel@tonic-gate convert_prompt(params->utils, &text->h, 1638*7c478bd9Sstevel@tonic-gate gettext("Please enter your authentication name")) 1639*7c478bd9Sstevel@tonic-gate : NULL, NULL, 1640*7c478bd9Sstevel@tonic-gate NULL, NULL, 1641*7c478bd9Sstevel@tonic-gate NULL, NULL, NULL, 1642*7c478bd9Sstevel@tonic-gate NULL, NULL, NULL); 1643*7c478bd9Sstevel@tonic-gate #else 1644*7c478bd9Sstevel@tonic-gate int result = _plug_make_prompts(params->utils, prompt_need, 1645*7c478bd9Sstevel@tonic-gate user_result == SASL_INTERACT ? 1646*7c478bd9Sstevel@tonic-gate "Please enter your authorization name" 1647*7c478bd9Sstevel@tonic-gate : NULL, NULL, 1648*7c478bd9Sstevel@tonic-gate auth_result == SASL_INTERACT ? 1649*7c478bd9Sstevel@tonic-gate "Please enter your authentication name" 1650*7c478bd9Sstevel@tonic-gate : NULL, NULL, 1651*7c478bd9Sstevel@tonic-gate NULL, NULL, 1652*7c478bd9Sstevel@tonic-gate NULL, NULL, NULL, 1653*7c478bd9Sstevel@tonic-gate NULL, NULL, NULL); 1654*7c478bd9Sstevel@tonic-gate #endif /* _INTEGRATED_SOLARIS_ */ 1655*7c478bd9Sstevel@tonic-gate 1656*7c478bd9Sstevel@tonic-gate if (result != SASL_OK) return result; 1657*7c478bd9Sstevel@tonic-gate 1658*7c478bd9Sstevel@tonic-gate return SASL_INTERACT; 1659*7c478bd9Sstevel@tonic-gate } 1660*7c478bd9Sstevel@tonic-gate #else 1661*7c478bd9Sstevel@tonic-gate if (user_result == SASL_INTERACT) { 1662*7c478bd9Sstevel@tonic-gate /* make the prompt list */ 1663*7c478bd9Sstevel@tonic-gate int result = 1664*7c478bd9Sstevel@tonic-gate _plug_make_prompts(params->utils, prompt_need, 1665*7c478bd9Sstevel@tonic-gate user_result == SASL_INTERACT ? 1666*7c478bd9Sstevel@tonic-gate "Please enter your authorization name" : NULL, NULL, 1667*7c478bd9Sstevel@tonic-gate NULL, NULL, 1668*7c478bd9Sstevel@tonic-gate NULL, NULL, 1669*7c478bd9Sstevel@tonic-gate NULL, NULL, NULL, 1670*7c478bd9Sstevel@tonic-gate NULL, NULL, NULL); 1671*7c478bd9Sstevel@tonic-gate if (result != SASL_OK) return result; 1672*7c478bd9Sstevel@tonic-gate 1673*7c478bd9Sstevel@tonic-gate return SASL_INTERACT; 1674*7c478bd9Sstevel@tonic-gate } 1675*7c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */ 1676*7c478bd9Sstevel@tonic-gate } 1677*7c478bd9Sstevel@tonic-gate 1678*7c478bd9Sstevel@tonic-gate if (text->server_name == GSS_C_NO_NAME) { /* only once */ 1679*7c478bd9Sstevel@tonic-gate name_token.length = strlen(params->service) + 1 + strlen(params->serverFQDN); 1680*7c478bd9Sstevel@tonic-gate name_token.value = (char *)params->utils->malloc((name_token.length + 1) * sizeof(char)); 1681*7c478bd9Sstevel@tonic-gate if (name_token.value == NULL) { 1682*7c478bd9Sstevel@tonic-gate sasl_gss_free_context_contents(text); 1683*7c478bd9Sstevel@tonic-gate return SASL_NOMEM; 1684*7c478bd9Sstevel@tonic-gate } 1685*7c478bd9Sstevel@tonic-gate if (params->serverFQDN == NULL 1686*7c478bd9Sstevel@tonic-gate || strlen(params->serverFQDN) == 0) { 1687*7c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_ 1688*7c478bd9Sstevel@tonic-gate text->utils->log(text->utils->conn, SASL_LOG_ERR, 1689*7c478bd9Sstevel@tonic-gate "GSSAPI Failure: no serverFQDN"); 1690*7c478bd9Sstevel@tonic-gate #else 1691*7c478bd9Sstevel@tonic-gate SETERROR(text->utils, "GSSAPI Failure: no serverFQDN"); 1692*7c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */ 1693*7c478bd9Sstevel@tonic-gate return SASL_FAIL; 1694*7c478bd9Sstevel@tonic-gate } 1695*7c478bd9Sstevel@tonic-gate 1696*7c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_ 1697*7c478bd9Sstevel@tonic-gate snprintf(name_token.value, name_token.length + 1, 1698*7c478bd9Sstevel@tonic-gate "%s@%s", params->service, params->serverFQDN); 1699*7c478bd9Sstevel@tonic-gate #else 1700*7c478bd9Sstevel@tonic-gate sprintf(name_token.value,"%s@%s", params->service, params->serverFQDN); 1701*7c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */ 1702*7c478bd9Sstevel@tonic-gate 1703*7c478bd9Sstevel@tonic-gate maj_stat = gss_import_name (&min_stat, 1704*7c478bd9Sstevel@tonic-gate &name_token, 1705*7c478bd9Sstevel@tonic-gate GSS_C_NT_HOSTBASED_SERVICE, 1706*7c478bd9Sstevel@tonic-gate &text->server_name); 1707*7c478bd9Sstevel@tonic-gate 1708*7c478bd9Sstevel@tonic-gate params->utils->free(name_token.value); 1709*7c478bd9Sstevel@tonic-gate name_token.value = NULL; 1710*7c478bd9Sstevel@tonic-gate 1711*7c478bd9Sstevel@tonic-gate if (GSS_ERROR(maj_stat)) { 1712*7c478bd9Sstevel@tonic-gate sasl_gss_seterror(text->utils, maj_stat, min_stat); 1713*7c478bd9Sstevel@tonic-gate sasl_gss_free_context_contents(text); 1714*7c478bd9Sstevel@tonic-gate return SASL_FAIL; 1715*7c478bd9Sstevel@tonic-gate } 1716*7c478bd9Sstevel@tonic-gate } 1717*7c478bd9Sstevel@tonic-gate 1718*7c478bd9Sstevel@tonic-gate if (serverinlen == 0) 1719*7c478bd9Sstevel@tonic-gate input_token = GSS_C_NO_BUFFER; 1720*7c478bd9Sstevel@tonic-gate 1721*7c478bd9Sstevel@tonic-gate if (serverinlen) { 1722*7c478bd9Sstevel@tonic-gate real_input_token.value = (void *)serverin; 1723*7c478bd9Sstevel@tonic-gate real_input_token.length = serverinlen; 1724*7c478bd9Sstevel@tonic-gate } 1725*7c478bd9Sstevel@tonic-gate else if (text->gss_ctx != GSS_C_NO_CONTEXT ) { 1726*7c478bd9Sstevel@tonic-gate /* This can't happen under GSSAPI: we have a non-null context 1727*7c478bd9Sstevel@tonic-gate * and no input from the server. However, thanks to Imap, 1728*7c478bd9Sstevel@tonic-gate * which discards our first output, this happens all the time. 1729*7c478bd9Sstevel@tonic-gate * Throw away the context and try again. */ 1730*7c478bd9Sstevel@tonic-gate maj_stat = gss_delete_sec_context (&min_stat,&text->gss_ctx,GSS_C_NO_BUFFER); 1731*7c478bd9Sstevel@tonic-gate text->gss_ctx = GSS_C_NO_CONTEXT; 1732*7c478bd9Sstevel@tonic-gate } 1733*7c478bd9Sstevel@tonic-gate 1734*7c478bd9Sstevel@tonic-gate /* Setup req_flags properly */ 1735*7c478bd9Sstevel@tonic-gate req_flags = GSS_C_MUTUAL_FLAG | GSS_C_SEQUENCE_FLAG; 1736*7c478bd9Sstevel@tonic-gate if(params->props.max_ssf > params->external_ssf) { 1737*7c478bd9Sstevel@tonic-gate /* We are requesting a security layer */ 1738*7c478bd9Sstevel@tonic-gate req_flags |= GSS_C_INTEG_FLAG; 1739*7c478bd9Sstevel@tonic-gate if(params->props.max_ssf - params->external_ssf > 56) { 1740*7c478bd9Sstevel@tonic-gate /* We want to try for privacy */ 1741*7c478bd9Sstevel@tonic-gate req_flags |= GSS_C_CONF_FLAG; 1742*7c478bd9Sstevel@tonic-gate } 1743*7c478bd9Sstevel@tonic-gate } 1744*7c478bd9Sstevel@tonic-gate 1745*7c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_ 1746*7c478bd9Sstevel@tonic-gate if (text->use_authid && text->client_creds == GSS_C_NO_CREDENTIAL) { 1747*7c478bd9Sstevel@tonic-gate gss_OID_set desired_mechs = GSS_C_NULL_OID_SET; 1748*7c478bd9Sstevel@tonic-gate gss_buffer_desc name_token; 1749*7c478bd9Sstevel@tonic-gate 1750*7c478bd9Sstevel@tonic-gate name_token.length = strlen(text->client_authid); 1751*7c478bd9Sstevel@tonic-gate name_token.value = (char *)text->client_authid; 1752*7c478bd9Sstevel@tonic-gate 1753*7c478bd9Sstevel@tonic-gate maj_stat = gss_import_name (&min_stat, 1754*7c478bd9Sstevel@tonic-gate &name_token, 1755*7c478bd9Sstevel@tonic-gate #ifdef HAVE_GSS_C_NT_USER_NAME 1756*7c478bd9Sstevel@tonic-gate GSS_C_NT_USER_NAME, 1757*7c478bd9Sstevel@tonic-gate #else 1758*7c478bd9Sstevel@tonic-gate GSS_C_NULL_OID, 1759*7c478bd9Sstevel@tonic-gate #endif 1760*7c478bd9Sstevel@tonic-gate &text->client_name); 1761*7c478bd9Sstevel@tonic-gate if (GSS_ERROR(maj_stat)) { 1762*7c478bd9Sstevel@tonic-gate sasl_gss_seterror(text->utils, maj_stat, min_stat); 1763*7c478bd9Sstevel@tonic-gate sasl_gss_free_context_contents(text); 1764*7c478bd9Sstevel@tonic-gate return SASL_FAIL; 1765*7c478bd9Sstevel@tonic-gate } 1766*7c478bd9Sstevel@tonic-gate 1767*7c478bd9Sstevel@tonic-gate if (text->mech_oid != GSS_C_NULL_OID) { 1768*7c478bd9Sstevel@tonic-gate ret = add_mech_to_set(text, &desired_mechs); 1769*7c478bd9Sstevel@tonic-gate if (ret != SASL_OK) 1770*7c478bd9Sstevel@tonic-gate return (ret); 1771*7c478bd9Sstevel@tonic-gate } 1772*7c478bd9Sstevel@tonic-gate 1773*7c478bd9Sstevel@tonic-gate maj_stat = gss_acquire_cred(&min_stat, 1774*7c478bd9Sstevel@tonic-gate text->client_name, 1775*7c478bd9Sstevel@tonic-gate GSS_C_INDEFINITE, 1776*7c478bd9Sstevel@tonic-gate desired_mechs, 1777*7c478bd9Sstevel@tonic-gate GSS_C_INITIATE, 1778*7c478bd9Sstevel@tonic-gate &text->client_creds, 1779*7c478bd9Sstevel@tonic-gate NULL, 1780*7c478bd9Sstevel@tonic-gate NULL); 1781*7c478bd9Sstevel@tonic-gate 1782*7c478bd9Sstevel@tonic-gate if (desired_mechs != GSS_C_NULL_OID_SET) { 1783*7c478bd9Sstevel@tonic-gate OM_uint32 min_stat2; 1784*7c478bd9Sstevel@tonic-gate (void) gss_release_oid_set(&min_stat2, &desired_mechs); 1785*7c478bd9Sstevel@tonic-gate } 1786*7c478bd9Sstevel@tonic-gate 1787*7c478bd9Sstevel@tonic-gate if (GSS_ERROR(maj_stat)) { 1788*7c478bd9Sstevel@tonic-gate sasl_gss_seterror(text->utils, maj_stat, min_stat); 1789*7c478bd9Sstevel@tonic-gate sasl_gss_free_context_contents(text); 1790*7c478bd9Sstevel@tonic-gate return SASL_FAIL; 1791*7c478bd9Sstevel@tonic-gate } 1792*7c478bd9Sstevel@tonic-gate } 1793*7c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */ 1794*7c478bd9Sstevel@tonic-gate 1795*7c478bd9Sstevel@tonic-gate maj_stat = gss_init_sec_context(&min_stat, 1796*7c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_ 1797*7c478bd9Sstevel@tonic-gate text->client_creds, 1798*7c478bd9Sstevel@tonic-gate #else 1799*7c478bd9Sstevel@tonic-gate GSS_C_NO_CREDENTIAL, 1800*7c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */ 1801*7c478bd9Sstevel@tonic-gate &text->gss_ctx, 1802*7c478bd9Sstevel@tonic-gate text->server_name, 1803*7c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_ 1804*7c478bd9Sstevel@tonic-gate text->mech_oid, 1805*7c478bd9Sstevel@tonic-gate #else 1806*7c478bd9Sstevel@tonic-gate GSS_C_NO_OID, 1807*7c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */ 1808*7c478bd9Sstevel@tonic-gate req_flags, 1809*7c478bd9Sstevel@tonic-gate 0, 1810*7c478bd9Sstevel@tonic-gate GSS_C_NO_CHANNEL_BINDINGS, 1811*7c478bd9Sstevel@tonic-gate input_token, 1812*7c478bd9Sstevel@tonic-gate NULL, 1813*7c478bd9Sstevel@tonic-gate output_token, 1814*7c478bd9Sstevel@tonic-gate &out_req_flags, 1815*7c478bd9Sstevel@tonic-gate NULL); 1816*7c478bd9Sstevel@tonic-gate 1817*7c478bd9Sstevel@tonic-gate if (GSS_ERROR(maj_stat)) { 1818*7c478bd9Sstevel@tonic-gate sasl_gss_seterror(text->utils, maj_stat, min_stat); 1819*7c478bd9Sstevel@tonic-gate if (output_token->value) 1820*7c478bd9Sstevel@tonic-gate gss_release_buffer(&min_stat, output_token); 1821*7c478bd9Sstevel@tonic-gate sasl_gss_free_context_contents(text); 1822*7c478bd9Sstevel@tonic-gate return SASL_FAIL; 1823*7c478bd9Sstevel@tonic-gate } 1824*7c478bd9Sstevel@tonic-gate 1825*7c478bd9Sstevel@tonic-gate *clientoutlen = output_token->length; 1826*7c478bd9Sstevel@tonic-gate 1827*7c478bd9Sstevel@tonic-gate if (output_token->value) { 1828*7c478bd9Sstevel@tonic-gate if (clientout) { 1829*7c478bd9Sstevel@tonic-gate ret = _plug_buf_alloc(text->utils, &(text->out_buf), 1830*7c478bd9Sstevel@tonic-gate &(text->out_buf_len), *clientoutlen); 1831*7c478bd9Sstevel@tonic-gate if(ret != SASL_OK) { 1832*7c478bd9Sstevel@tonic-gate gss_release_buffer(&min_stat, output_token); 1833*7c478bd9Sstevel@tonic-gate return ret; 1834*7c478bd9Sstevel@tonic-gate } 1835*7c478bd9Sstevel@tonic-gate memcpy(text->out_buf, output_token->value, *clientoutlen); 1836*7c478bd9Sstevel@tonic-gate *clientout = text->out_buf; 1837*7c478bd9Sstevel@tonic-gate } 1838*7c478bd9Sstevel@tonic-gate 1839*7c478bd9Sstevel@tonic-gate gss_release_buffer(&min_stat, output_token); 1840*7c478bd9Sstevel@tonic-gate } 1841*7c478bd9Sstevel@tonic-gate 1842*7c478bd9Sstevel@tonic-gate if (maj_stat == GSS_S_COMPLETE) { 1843*7c478bd9Sstevel@tonic-gate maj_stat = gss_inquire_context(&min_stat, 1844*7c478bd9Sstevel@tonic-gate text->gss_ctx, 1845*7c478bd9Sstevel@tonic-gate &text->client_name, 1846*7c478bd9Sstevel@tonic-gate NULL, /* targ_name */ 1847*7c478bd9Sstevel@tonic-gate NULL, /* lifetime */ 1848*7c478bd9Sstevel@tonic-gate NULL, /* mech */ 1849*7c478bd9Sstevel@tonic-gate NULL, /* flags */ 1850*7c478bd9Sstevel@tonic-gate NULL, /* local init */ 1851*7c478bd9Sstevel@tonic-gate NULL); /* open */ 1852*7c478bd9Sstevel@tonic-gate 1853*7c478bd9Sstevel@tonic-gate if (GSS_ERROR(maj_stat)) { 1854*7c478bd9Sstevel@tonic-gate sasl_gss_seterror(text->utils, maj_stat, min_stat); 1855*7c478bd9Sstevel@tonic-gate sasl_gss_free_context_contents(text); 1856*7c478bd9Sstevel@tonic-gate return SASL_FAIL; 1857*7c478bd9Sstevel@tonic-gate } 1858*7c478bd9Sstevel@tonic-gate 1859*7c478bd9Sstevel@tonic-gate name_token.length = 0; 1860*7c478bd9Sstevel@tonic-gate maj_stat = gss_display_name(&min_stat, 1861*7c478bd9Sstevel@tonic-gate text->client_name, 1862*7c478bd9Sstevel@tonic-gate &name_token, 1863*7c478bd9Sstevel@tonic-gate NULL); 1864*7c478bd9Sstevel@tonic-gate 1865*7c478bd9Sstevel@tonic-gate if (GSS_ERROR(maj_stat)) { 1866*7c478bd9Sstevel@tonic-gate if (name_token.value) 1867*7c478bd9Sstevel@tonic-gate gss_release_buffer(&min_stat, &name_token); 1868*7c478bd9Sstevel@tonic-gate #ifdef _INTEGRATED_SOLARIS_ 1869*7c478bd9Sstevel@tonic-gate SETERROR(text->utils, gettext("GSSAPI Failure")); 1870*7c478bd9Sstevel@tonic-gate #else 1871*7c478bd9Sstevel@tonic-gate SETERROR(text->utils, "GSSAPI Failure"); 1872*7c478bd9Sstevel@tonic-gate #endif /* _INTEGRATED_SOLARIS_ */ 1873*7c478bd9Sstevel@tonic-gate sasl_gss_free_context_contents(text); 1874*7c478bd9Sstevel@tonic-gate return SASL_FAIL; 1875*7c478bd9Sstevel@tonic-gate } 1876*7c478bd9Sstevel@tonic-gate 1877*7c478bd9Sstevel@tonic-gate if (text->user && text->user[0]) { 1878*7c478bd9Sstevel@tonic-gate ret = params->canon_user(params->utils->conn, 1879*7c478bd9Sstevel@tonic-gate text->user, 0, 1880*7c478bd9Sstevel@tonic-gate SASL_CU_AUTHZID, oparams); 1881*7c478bd9Sstevel@tonic-gate if (ret == SASL_OK) 1882*7c478bd9Sstevel@tonic-gate ret = params->canon_user(params->utils->conn, 1883*7c478bd9Sstevel@tonic-gate name_token.value, 0, 1884*7c478bd9Sstevel@tonic-gate SASL_CU_AUTHID, oparams); 1885*7c478bd9Sstevel@tonic-gate } else { 1886*7c478bd9Sstevel@tonic-gate ret = params->canon_user(params->utils->conn, 1887*7c478bd9Sstevel@tonic-gate name_token.value, 0, 1888*7c478bd9Sstevel@tonic-gate SASL_CU_AUTHID | SASL_CU_AUTHZID, 1889*7c478bd9Sstevel@tonic-gate oparams); 1890*7c478bd9Sstevel@tonic-gate } 1891*7c478bd9Sstevel@tonic-gate gss_release_buffer(&min_stat, &name_token); 1892*7c478bd9Sstevel@tonic-gate 1893*7c478bd9Sstevel@tonic-gate if (ret != SASL_OK) return ret; 1894*7c478bd9Sstevel@tonic-gate 1895*7c478bd9Sstevel@tonic-gate /* Switch to ssf negotiation */ 1896*7c478bd9Sstevel@tonic-gate text->state = SASL_GSSAPI_STATE_SSFCAP; 1897*7c478bd9Sstevel@tonic-gate } 1898*7c478bd9Sstevel@tonic-gate 1899*7c478bd9Sstevel@tonic-gate return SASL_CONTINUE; 1900*7c478bd9Sstevel@tonic-gate 1901*7c478bd9Sstevel@tonic-gate case SASL_GSSAPI_STATE_SSFCAP: { 1902*7c478bd9Sstevel@tonic-gate sasl_security_properties_t *secprops = &(params->props); 1903*7c478bd9Sstevel@tonic-gate unsigned int alen, external = params->external_ssf; 1904*7c478bd9Sstevel@tonic-gate sasl_ssf_t need, allowed; 1905*7c478bd9Sstevel@tonic-gate char serverhas, mychoice; 1906*7c478bd9Sstevel@tonic-gate 1907*7c478bd9Sstevel@tonic-gate real_input_token.value = (void *) serverin; 1908*7c478bd9Sstevel@tonic-gate real_input_token.length = serverinlen; 1909*7c478bd9Sstevel@tonic-gate 1910*7c478bd9Sstevel@tonic-gate maj_stat = gss_unwrap(&min_stat, 1911*7c478bd9Sstevel@tonic-gate text->gss_ctx, 1912*7c478bd9Sstevel@tonic-gate input_token, 1913*7c478bd9Sstevel@tonic-gate output_token, 1914*7c478bd9Sstevel@tonic-gate NULL, 1915*7c478bd9Sstevel@tonic-gate NULL); 1916*7c478bd9Sstevel@tonic-gate 1917*7c478bd9Sstevel@tonic-gate if (GSS_ERROR(maj_stat)) { 1918*7c478bd9Sstevel@tonic-gate sasl_gss_seterror(text->utils, maj_stat, min_stat); 1919*7c478bd9Sstevel@tonic-gate sasl_gss_free_context_contents(text); 1920*7c478bd9Sstevel@tonic-gate if (output_token->value) 1921*7c478bd9Sstevel@tonic-gate gss_release_buffer(&min_stat, output_token); 1922*7c478bd9Sstevel@tonic-gate return SASL_FAIL; 1923*7c478bd9Sstevel@tonic-gate } 1924*7c478bd9Sstevel@tonic-gate 1925*7c478bd9Sstevel@tonic-gate /* taken from kerberos.c */ 1926*7c478bd9Sstevel@tonic-gate if (secprops->min_ssf > (56 + external)) { 1927*7c478bd9Sstevel@tonic-gate return SASL_TOOWEAK; 1928*7c478bd9Sstevel@tonic-gate } else if (secprops->min_ssf > secprops->max_ssf) { 1929*7c478bd9Sstevel@tonic-gate return SASL_BADPARAM; 1930*7c478bd9Sstevel@tonic-gate } 1931*7c478bd9Sstevel@tonic-gate 1932*7c478bd9Sstevel@tonic-gate /* need bits of layer -- sasl_ssf_t is unsigned so be careful */ 1933*7c478bd9Sstevel@tonic-gate if (secprops->max_ssf >= external) { 1934*7c478bd9Sstevel@tonic-gate allowed = secprops->max_ssf - external; 1935*7c478bd9Sstevel@tonic-gate } else { 1936*7c478bd9Sstevel@tonic-gate allowed = 0; 1937*7c478bd9Sstevel@tonic-gate } 1938*7c478bd9Sstevel@tonic-gate if (secprops->min_ssf >= external) { 1939*7c478bd9Sstevel@tonic-gate need = secprops->min_ssf - external; 1940*7c478bd9Sstevel@tonic-gate } else { 1941*7c478bd9Sstevel@tonic-gate /* good to go */ 1942*7c478bd9Sstevel@tonic-gate need = 0; 1943*7c478bd9Sstevel@tonic-gate } 1944*7c478bd9Sstevel@tonic-gate 1945*7c478bd9Sstevel@tonic-gate /* bit mask of server support */ 1946*7c478bd9Sstevel@tonic-gate serverhas = ((char *)output_token->value)[0]; 1947*7c478bd9Sstevel@tonic-gate 1948*7c478bd9Sstevel@tonic-gate /* if client didn't set use strongest layer available */ 1949*7c478bd9Sstevel@tonic-gate if (allowed >= 56 && need <= 56 && (serverhas & 4)) { 1950*7c478bd9Sstevel@tonic-gate /* encryption */ 1951*7c478bd9Sstevel@tonic-gate oparams->encode = &gssapi_privacy_encode; 1952*7c478bd9Sstevel@tonic-gate oparams->decode = &gssapi_decode; 1953*7c478bd9Sstevel@tonic-gate oparams->mech_ssf = 56; 1954*7c478bd9Sstevel@tonic-gate mychoice = 4; 1955*7c478bd9Sstevel@tonic-gate } else if (allowed >= 1 && need <= 1 && (serverhas & 2)) { 1956*7c478bd9Sstevel@tonic-gate /* integrity */ 1957*7c478bd9Sstevel@tonic-gate oparams->encode = &gssapi_integrity_encode; 1958*7c478bd9Sstevel@tonic-gate oparams->decode = &gssapi_decode; 1959*7c478bd9Sstevel@tonic-gate oparams->mech_ssf = 1; 1960*7c478bd9Sstevel@tonic-gate mychoice = 2; 1961*7c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_ 1962*7c478bd9Sstevel@tonic-gate } else if (need == 0 && (serverhas & 1)) { 1963*7c478bd9Sstevel@tonic-gate #else 1964*7c478bd9Sstevel@tonic-gate } else if (need <= 0 && (serverhas & 1)) { 1965*7c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */ 1966*7c478bd9Sstevel@tonic-gate /* no layer */ 1967*7c478bd9Sstevel@tonic-gate oparams->encode = NULL; 1968*7c478bd9Sstevel@tonic-gate oparams->decode = NULL; 1969*7c478bd9Sstevel@tonic-gate oparams->mech_ssf = 0; 1970*7c478bd9Sstevel@tonic-gate mychoice = 1; 1971*7c478bd9Sstevel@tonic-gate } else { 1972*7c478bd9Sstevel@tonic-gate /* there's no appropriate layering for us! */ 1973*7c478bd9Sstevel@tonic-gate sasl_gss_free_context_contents(text); 1974*7c478bd9Sstevel@tonic-gate return SASL_TOOWEAK; 1975*7c478bd9Sstevel@tonic-gate } 1976*7c478bd9Sstevel@tonic-gate 1977*7c478bd9Sstevel@tonic-gate oparams->maxoutbuf = 1978*7c478bd9Sstevel@tonic-gate (((unsigned char *) output_token->value)[1] << 16) | 1979*7c478bd9Sstevel@tonic-gate (((unsigned char *) output_token->value)[2] << 8) | 1980*7c478bd9Sstevel@tonic-gate (((unsigned char *) output_token->value)[3] << 0); 1981*7c478bd9Sstevel@tonic-gate 1982*7c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_ 1983*7c478bd9Sstevel@tonic-gate if (oparams->mech_ssf > 0) { 1984*7c478bd9Sstevel@tonic-gate oparams->maxoutbuf -= 4; /* Space for 4 byte length header */ 1985*7c478bd9Sstevel@tonic-gate maj_stat = gss_wrap_size_limit(&min_stat, 1986*7c478bd9Sstevel@tonic-gate text->gss_ctx, 1987*7c478bd9Sstevel@tonic-gate oparams->mech_ssf > 1, 1988*7c478bd9Sstevel@tonic-gate GSS_C_QOP_DEFAULT, 1989*7c478bd9Sstevel@tonic-gate oparams->maxoutbuf, 1990*7c478bd9Sstevel@tonic-gate &max_input_size); 1991*7c478bd9Sstevel@tonic-gate if (GSS_ERROR(maj_stat)) { 1992*7c478bd9Sstevel@tonic-gate sasl_gss_seterror(text->utils, maj_stat, min_stat); 1993*7c478bd9Sstevel@tonic-gate (void) gss_release_buffer(&min_stat, output_token); 1994*7c478bd9Sstevel@tonic-gate sasl_gss_free_context_contents(text); 1995*7c478bd9Sstevel@tonic-gate return (SASL_FAIL); 1996*7c478bd9Sstevel@tonic-gate } 1997*7c478bd9Sstevel@tonic-gate 1998*7c478bd9Sstevel@tonic-gate /* 1999*7c478bd9Sstevel@tonic-gate * This is a workaround for a Solaris bug where 2000*7c478bd9Sstevel@tonic-gate * gss_wrap_size_limit may return very big sizes for 2001*7c478bd9Sstevel@tonic-gate * small input values 2002*7c478bd9Sstevel@tonic-gate */ 2003*7c478bd9Sstevel@tonic-gate if (max_input_size < oparams->maxoutbuf) 2004*7c478bd9Sstevel@tonic-gate oparams->maxoutbuf = max_input_size; 2005*7c478bd9Sstevel@tonic-gate else { 2006*7c478bd9Sstevel@tonic-gate oparams->maxoutbuf = 0; 2007*7c478bd9Sstevel@tonic-gate } 2008*7c478bd9Sstevel@tonic-gate } 2009*7c478bd9Sstevel@tonic-gate #else 2010*7c478bd9Sstevel@tonic-gate if(oparams->mech_ssf) { 2011*7c478bd9Sstevel@tonic-gate /* xxx probably too large */ 2012*7c478bd9Sstevel@tonic-gate oparams->maxoutbuf -= 50; 2013*7c478bd9Sstevel@tonic-gate } 2014*7c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */ 2015*7c478bd9Sstevel@tonic-gate 2016*7c478bd9Sstevel@tonic-gate gss_release_buffer(&min_stat, output_token); 2017*7c478bd9Sstevel@tonic-gate 2018*7c478bd9Sstevel@tonic-gate /* oparams->user is always set, due to canon_user requirements. 2019*7c478bd9Sstevel@tonic-gate * Make sure the client actually requested it though, by checking 2020*7c478bd9Sstevel@tonic-gate * if our context was set. 2021*7c478bd9Sstevel@tonic-gate */ 2022*7c478bd9Sstevel@tonic-gate if (text->user && text->user[0]) 2023*7c478bd9Sstevel@tonic-gate alen = strlen(oparams->user); 2024*7c478bd9Sstevel@tonic-gate else 2025*7c478bd9Sstevel@tonic-gate alen = 0; 2026*7c478bd9Sstevel@tonic-gate 2027*7c478bd9Sstevel@tonic-gate input_token->length = 4 + alen; 2028*7c478bd9Sstevel@tonic-gate input_token->value = 2029*7c478bd9Sstevel@tonic-gate (char *)params->utils->malloc((input_token->length + 1)*sizeof(char)); 2030*7c478bd9Sstevel@tonic-gate if (input_token->value == NULL) { 2031*7c478bd9Sstevel@tonic-gate sasl_gss_free_context_contents(text); 2032*7c478bd9Sstevel@tonic-gate return SASL_NOMEM; 2033*7c478bd9Sstevel@tonic-gate } 2034*7c478bd9Sstevel@tonic-gate 2035*7c478bd9Sstevel@tonic-gate if (alen) 2036*7c478bd9Sstevel@tonic-gate memcpy((char *)input_token->value+4,oparams->user,alen); 2037*7c478bd9Sstevel@tonic-gate 2038*7c478bd9Sstevel@tonic-gate /* build up our security properties token */ 2039*7c478bd9Sstevel@tonic-gate if (params->props.maxbufsize > 0xFFFFFF) { 2040*7c478bd9Sstevel@tonic-gate /* make sure maxbufsize isn't too large */ 2041*7c478bd9Sstevel@tonic-gate /* maxbufsize = 0xFFFFFF */ 2042*7c478bd9Sstevel@tonic-gate ((unsigned char *)input_token->value)[1] = 0xFF; 2043*7c478bd9Sstevel@tonic-gate ((unsigned char *)input_token->value)[2] = 0xFF; 2044*7c478bd9Sstevel@tonic-gate ((unsigned char *)input_token->value)[3] = 0xFF; 2045*7c478bd9Sstevel@tonic-gate } else { 2046*7c478bd9Sstevel@tonic-gate ((unsigned char *)input_token->value)[1] = 2047*7c478bd9Sstevel@tonic-gate (params->props.maxbufsize >> 16) & 0xFF; 2048*7c478bd9Sstevel@tonic-gate ((unsigned char *)input_token->value)[2] = 2049*7c478bd9Sstevel@tonic-gate (params->props.maxbufsize >> 8) & 0xFF; 2050*7c478bd9Sstevel@tonic-gate ((unsigned char *)input_token->value)[3] = 2051*7c478bd9Sstevel@tonic-gate (params->props.maxbufsize >> 0) & 0xFF; 2052*7c478bd9Sstevel@tonic-gate } 2053*7c478bd9Sstevel@tonic-gate ((unsigned char *)input_token->value)[0] = mychoice; 2054*7c478bd9Sstevel@tonic-gate 2055*7c478bd9Sstevel@tonic-gate maj_stat = gss_wrap (&min_stat, 2056*7c478bd9Sstevel@tonic-gate text->gss_ctx, 2057*7c478bd9Sstevel@tonic-gate 0, /* Just integrity checking here */ 2058*7c478bd9Sstevel@tonic-gate GSS_C_QOP_DEFAULT, 2059*7c478bd9Sstevel@tonic-gate input_token, 2060*7c478bd9Sstevel@tonic-gate NULL, 2061*7c478bd9Sstevel@tonic-gate output_token); 2062*7c478bd9Sstevel@tonic-gate 2063*7c478bd9Sstevel@tonic-gate params->utils->free(input_token->value); 2064*7c478bd9Sstevel@tonic-gate input_token->value = NULL; 2065*7c478bd9Sstevel@tonic-gate 2066*7c478bd9Sstevel@tonic-gate if (GSS_ERROR(maj_stat)) { 2067*7c478bd9Sstevel@tonic-gate sasl_gss_seterror(text->utils, maj_stat, min_stat); 2068*7c478bd9Sstevel@tonic-gate if (output_token->value) 2069*7c478bd9Sstevel@tonic-gate gss_release_buffer(&min_stat, output_token); 2070*7c478bd9Sstevel@tonic-gate sasl_gss_free_context_contents(text); 2071*7c478bd9Sstevel@tonic-gate return SASL_FAIL; 2072*7c478bd9Sstevel@tonic-gate } 2073*7c478bd9Sstevel@tonic-gate 2074*7c478bd9Sstevel@tonic-gate if (clientoutlen) 2075*7c478bd9Sstevel@tonic-gate *clientoutlen = output_token->length; 2076*7c478bd9Sstevel@tonic-gate if (output_token->value) { 2077*7c478bd9Sstevel@tonic-gate if (clientout) { 2078*7c478bd9Sstevel@tonic-gate ret = _plug_buf_alloc(text->utils, &(text->out_buf), 2079*7c478bd9Sstevel@tonic-gate &(text->out_buf_len), *clientoutlen); 2080*7c478bd9Sstevel@tonic-gate if (ret != SASL_OK) { 2081*7c478bd9Sstevel@tonic-gate gss_release_buffer(&min_stat, output_token); 2082*7c478bd9Sstevel@tonic-gate return ret; 2083*7c478bd9Sstevel@tonic-gate } 2084*7c478bd9Sstevel@tonic-gate memcpy(text->out_buf, output_token->value, *clientoutlen); 2085*7c478bd9Sstevel@tonic-gate *clientout = text->out_buf; 2086*7c478bd9Sstevel@tonic-gate } 2087*7c478bd9Sstevel@tonic-gate 2088*7c478bd9Sstevel@tonic-gate gss_release_buffer(&min_stat, output_token); 2089*7c478bd9Sstevel@tonic-gate } 2090*7c478bd9Sstevel@tonic-gate 2091*7c478bd9Sstevel@tonic-gate text->state = SASL_GSSAPI_STATE_AUTHENTICATED; 2092*7c478bd9Sstevel@tonic-gate 2093*7c478bd9Sstevel@tonic-gate oparams->doneflag = 1; 2094*7c478bd9Sstevel@tonic-gate 2095*7c478bd9Sstevel@tonic-gate return SASL_OK; 2096*7c478bd9Sstevel@tonic-gate } 2097*7c478bd9Sstevel@tonic-gate 2098*7c478bd9Sstevel@tonic-gate default: 2099*7c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_ 2100*7c478bd9Sstevel@tonic-gate params->utils->log(params->utils->conn, SASL_LOG_ERR, 2101*7c478bd9Sstevel@tonic-gate "Invalid GSSAPI client step %d", text->state); 2102*7c478bd9Sstevel@tonic-gate #else 2103*7c478bd9Sstevel@tonic-gate params->utils->log(NULL, SASL_LOG_ERR, 2104*7c478bd9Sstevel@tonic-gate "Invalid GSSAPI client step %d\n", text->state); 2105*7c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */ 2106*7c478bd9Sstevel@tonic-gate return SASL_FAIL; 2107*7c478bd9Sstevel@tonic-gate } 2108*7c478bd9Sstevel@tonic-gate 2109*7c478bd9Sstevel@tonic-gate #ifndef _SUN_SDK_ 2110*7c478bd9Sstevel@tonic-gate return SASL_FAIL; /* should never get here */ 2111*7c478bd9Sstevel@tonic-gate #endif /* !_SUN_SDK_ */ 2112*7c478bd9Sstevel@tonic-gate } 2113*7c478bd9Sstevel@tonic-gate 2114*7c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_ 2115*7c478bd9Sstevel@tonic-gate static const unsigned long gssapi_required_prompts[] = { 2116*7c478bd9Sstevel@tonic-gate #else 2117*7c478bd9Sstevel@tonic-gate static const long gssapi_required_prompts[] = { 2118*7c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */ 2119*7c478bd9Sstevel@tonic-gate SASL_CB_LIST_END 2120*7c478bd9Sstevel@tonic-gate }; 2121*7c478bd9Sstevel@tonic-gate 2122*7c478bd9Sstevel@tonic-gate #if defined _SUN_SDK_ && defined GSSAPI_PROTECT 2123*7c478bd9Sstevel@tonic-gate static int _gssapi_client_mech_step(void *conn_context, 2124*7c478bd9Sstevel@tonic-gate sasl_client_params_t *params, 2125*7c478bd9Sstevel@tonic-gate const char *serverin, 2126*7c478bd9Sstevel@tonic-gate unsigned serverinlen, 2127*7c478bd9Sstevel@tonic-gate sasl_interact_t **prompt_need, 2128*7c478bd9Sstevel@tonic-gate const char **clientout, 2129*7c478bd9Sstevel@tonic-gate unsigned *clientoutlen, 2130*7c478bd9Sstevel@tonic-gate sasl_out_params_t *oparams) 2131*7c478bd9Sstevel@tonic-gate { 2132*7c478bd9Sstevel@tonic-gate int ret; 2133*7c478bd9Sstevel@tonic-gate 2134*7c478bd9Sstevel@tonic-gate if (LOCK_MUTEX(&global_mutex) < 0) 2135*7c478bd9Sstevel@tonic-gate return (SASL_FAIL); 2136*7c478bd9Sstevel@tonic-gate 2137*7c478bd9Sstevel@tonic-gate ret = gssapi_client_mech_step(conn_context, params, serverin, serverinlen, 2138*7c478bd9Sstevel@tonic-gate prompt_need, clientout, clientoutlen, oparams); 2139*7c478bd9Sstevel@tonic-gate 2140*7c478bd9Sstevel@tonic-gate UNLOCK_MUTEX(&global_mutex); 2141*7c478bd9Sstevel@tonic-gate return (ret); 2142*7c478bd9Sstevel@tonic-gate } 2143*7c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ && GSSAPI_PROTECT */ 2144*7c478bd9Sstevel@tonic-gate 2145*7c478bd9Sstevel@tonic-gate static sasl_client_plug_t gssapi_client_plugins[] = 2146*7c478bd9Sstevel@tonic-gate { 2147*7c478bd9Sstevel@tonic-gate { 2148*7c478bd9Sstevel@tonic-gate "GSSAPI", /* mech_name */ 2149*7c478bd9Sstevel@tonic-gate 56, /* max_ssf */ 2150*7c478bd9Sstevel@tonic-gate SASL_SEC_NOPLAINTEXT 2151*7c478bd9Sstevel@tonic-gate | SASL_SEC_NOACTIVE 2152*7c478bd9Sstevel@tonic-gate | SASL_SEC_NOANONYMOUS 2153*7c478bd9Sstevel@tonic-gate | SASL_SEC_MUTUAL_AUTH, /* security_flags */ 2154*7c478bd9Sstevel@tonic-gate SASL_FEAT_WANT_CLIENT_FIRST 2155*7c478bd9Sstevel@tonic-gate | SASL_FEAT_ALLOWS_PROXY, /* features */ 2156*7c478bd9Sstevel@tonic-gate gssapi_required_prompts, /* required_prompts */ 2157*7c478bd9Sstevel@tonic-gate NULL, /* glob_context */ 2158*7c478bd9Sstevel@tonic-gate &gssapi_client_mech_new, /* mech_new */ 2159*7c478bd9Sstevel@tonic-gate #if defined _SUN_SDK_ && defined GSSAPI_PROTECT 2160*7c478bd9Sstevel@tonic-gate &_gssapi_client_mech_step, /* mech_step */ 2161*7c478bd9Sstevel@tonic-gate #else 2162*7c478bd9Sstevel@tonic-gate &gssapi_client_mech_step, /* mech_step */ 2163*7c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ && GSSAPI_PROTECT */ 2164*7c478bd9Sstevel@tonic-gate &gssapi_common_mech_dispose, /* mech_dispose */ 2165*7c478bd9Sstevel@tonic-gate NULL, /* mech_free */ 2166*7c478bd9Sstevel@tonic-gate NULL, /* idle */ 2167*7c478bd9Sstevel@tonic-gate NULL, /* spare */ 2168*7c478bd9Sstevel@tonic-gate NULL /* spare */ 2169*7c478bd9Sstevel@tonic-gate } 2170*7c478bd9Sstevel@tonic-gate }; 2171*7c478bd9Sstevel@tonic-gate 2172*7c478bd9Sstevel@tonic-gate int gssapiv2_client_plug_init(const sasl_utils_t *utils __attribute__((unused)), 2173*7c478bd9Sstevel@tonic-gate int maxversion, 2174*7c478bd9Sstevel@tonic-gate int *out_version, 2175*7c478bd9Sstevel@tonic-gate sasl_client_plug_t **pluglist, 2176*7c478bd9Sstevel@tonic-gate int *plugcount) 2177*7c478bd9Sstevel@tonic-gate { 2178*7c478bd9Sstevel@tonic-gate if (maxversion < SASL_CLIENT_PLUG_VERSION) { 2179*7c478bd9Sstevel@tonic-gate SETERROR(utils, "Version mismatch in GSSAPI"); 2180*7c478bd9Sstevel@tonic-gate return SASL_BADVERS; 2181*7c478bd9Sstevel@tonic-gate } 2182*7c478bd9Sstevel@tonic-gate 2183*7c478bd9Sstevel@tonic-gate #ifdef _INTEGRATED_SOLARIS_ 2184*7c478bd9Sstevel@tonic-gate /* 2185*7c478bd9Sstevel@tonic-gate * Let libsasl know that we are a "Sun" plugin so that privacy 2186*7c478bd9Sstevel@tonic-gate * and integrity will be allowed. 2187*7c478bd9Sstevel@tonic-gate */ 2188*7c478bd9Sstevel@tonic-gate REG_PLUG("GSSAPI", gssapi_client_plugins); 2189*7c478bd9Sstevel@tonic-gate #endif /* _INTEGRATED_SOLARIS_ */ 2190*7c478bd9Sstevel@tonic-gate 2191*7c478bd9Sstevel@tonic-gate *out_version = SASL_CLIENT_PLUG_VERSION; 2192*7c478bd9Sstevel@tonic-gate *pluglist = gssapi_client_plugins; 2193*7c478bd9Sstevel@tonic-gate *plugcount = 1; 2194*7c478bd9Sstevel@tonic-gate 2195*7c478bd9Sstevel@tonic-gate return SASL_OK; 2196*7c478bd9Sstevel@tonic-gate } 2197