/*
*/
/* GSSAPI SASL plugin
* Leif Johansson
* Rob Siemborski (SASL v2 Conversion)
* $Id: gssapi.c,v 1.75 2003/07/02 13:13:42 rjs3 Exp $
*/
/*
* Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* distribution.
*
* 3. The name "Carnegie Mellon University" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For permission or any other legal
* details, please contact
* Office of Technology Transfer
* Carnegie Mellon University
* 5000 Forbes Avenue
* Pittsburgh, PA 15213-3890
* (412) 268-4387, fax: (412) 268-7395
* tech-transfer@andrew.cmu.edu
*
* 4. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by Computing Services
* at Carnegie Mellon University (http://www.cmu.edu/computing/)."
*
* CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
* THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
* FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <config.h>
#ifdef HAVE_GSSAPI_H
#include <gssapi.h>
#else
#endif
#ifdef WIN32
# include <winsock.h>
# ifndef R_OK
# endif
/* we also need io.h for access() prototype */
# include <io.h>
#else
# include <netdb.h>
#endif /* WIN32 */
#include <fcntl.h>
#include <stdio.h>
#include <sasl.h>
#include <saslutil.h>
#include <saslplug.h>
#include "plugin_common.h"
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <errno.h>
#ifdef WIN32
/* This must be after sasl.h */
# include "saslgssapi.h"
#endif /* WIN32 */
/***************************** Common Section *****************************/
#ifndef _SUN_SDK_
#endif /* !_SUN_SDK_ */
#ifndef HAVE_GSS_C_NT_HOSTBASED_SERVICE
extern gss_OID gss_nt_service_name;
#endif
#ifdef _SUN_SDK_
static int
#ifdef GSSAPI_PROTECT
#endif /* GSSAPI_PROTECT */
#endif /* _SUN_SDK_ */
/* GSSAPI SASL Mechanism by Leif Johansson <leifj@matematik.su.se>
* inspired by the kerberos mechanism and the gssapi_server and
* gssapi_client from the heimdal distribution by Assar Westerlund
* <assar@sics.se> and Johan Danielsson <joda@pdc.kth.se>.
* See the configure.in file for details on dependencies.
* Heimdal can be obtained from http://www.pdc.kth.se/heimdal
*
* Important contributions from Sam Hartman <hartmans@fundsxpress.com>.
*/
typedef struct context {
int state;
server */
#ifdef _SUN_SDK_
int use_authid;
#endif /* _SUN_SDK_ */
/* layers buffering */
char *buffer;
#ifdef _SUN_SDK_
unsigned bufsize;
#else
int bufsize;
#endif /* _SUN_SDK_ */
#ifdef _SUN_SDK_
unsigned cursize;
unsigned size;
#else
int cursize;
int size;
#endif /* _SUN_SDK_ */
unsigned needsize;
char *decode_buf;
char *decode_once_buf;
unsigned encode_buf_len;
unsigned decode_buf_len;
unsigned decode_once_buf_len;
unsigned out_buf_len;
#ifdef _SUN_SDK_
const char *client_authid;
#endif /* _SUN_SDK_ */
#ifdef _INTEGRATED_SOLARIS_
void *h;
#endif /* _INTEGRATED_SOLARIS_ */
} context_t;
enum {
};
#ifdef _SUN_SDK_
/* sasl_gss_log only logs gss_display_status() error string */
static void
int logonly)
#else
static void
#endif /* _SUN_SDK_ */
{
int ret;
#ifdef _SUN_SDK_
#else
#endif /* _SUN_SDK_ */
if(!utils) return;
msg_ctx = 0;
while (1) {
#ifdef _SUN_SDK_
#else
#endif /* _SUN_SDK_ */
#ifdef _SUN_SDK_
if (logonly) {
"GSSAPI Failure: (could not get major error message)");
} else {
#endif /* _SUN_SDK_ */
#ifdef _INTEGRATED_SOLARIS_
gettext("GSSAPI Failure "
"(could not get major error message)"));
#ifdef _SUN_SDK_
}
#endif /* _SUN_SDK_ */
#else
"GSSAPI Failure "
"(could not get major error message)");
#ifdef _SUN_SDK_
}
#endif /* _SUN_SDK_ */
#endif /* _INTEGRATED_SOLARIS_ */
return;
}
return;
}
if (!msg_ctx)
break;
}
/* Now get the minor status */
len += 2;
return;
}
msg_ctx = 0;
while (1) {
#ifdef _SUN_SDK_
#else
#endif /* _SUN_SDK_ */
#ifdef _SUN_SDK_
if (logonly) {
"GSSAPI Failure: (could not get minor error message)");
} else {
#endif /* _SUN_SDK_ */
#ifdef _INTEGRATED_SOLARIS_
gettext("GSSAPI Failure "
"(could not get minor error message)"));
#ifdef _SUN_SDK_
}
#endif /* _SUN_SDK_ */
#else
"GSSAPI Failure "
"(could not get minor error message)");
#ifdef _SUN_SDK_
}
#endif /* _SUN_SDK_ */
#endif /* _INTEGRATED_SOLARIS_ */
return;
}
return;
}
if (!msg_ctx)
break;
}
len += 1;
return;
}
#ifdef _SUN_SDK_
if (logonly) {
} else {
}
#else
#endif /* _SUN_SDK_ */
}
static int
{
int ret;
if(!output) return SASL_BADPARAM;
if(numiov > 1) {
} else {
}
output_token->length = 0;
#if defined _SUN_SDK_ && defined GSSAPI_PROTECT
if (LOCK_MUTEX(&global_mutex) < 0)
return (SASL_FAIL);
#endif /* _SUN_SDK_ && GSSAPI_PROTECT */
NULL,
{
if (output_token->value)
#if defined _SUN_SDK_ && defined GSSAPI_PROTECT
#endif /* _SUN_SDK_ && GSSAPI_PROTECT */
return SASL_FAIL;
}
int len;
#if defined _SUN_SDK_ && defined GSSAPI_PROTECT
#endif /* _SUN_SDK_ && GSSAPI_PROTECT */
return ret;
}
}
if (outputlen) {
}
if (output_token->value)
#if defined _SUN_SDK_ && defined GSSAPI_PROTECT
#endif /* _SUN_SDK_ && GSSAPI_PROTECT */
return SASL_OK;
}
unsigned *outputlen)
{
}
unsigned *outputlen)
{
}
#define myMIN(a,b) (((a) < (b)) ? (a) : (b))
{
int result;
unsigned diff;
#ifdef _INTEGRATED_SOLARIS_
#else
#endif /* _INTEGRATED_SOLARIS_ */
return SASL_NOTDONE;
}
/* first we need to extract a packet */
/* how long is it? */
/* got the entire size */
#ifdef _SUN_SDK_
"Illegal size in sasl_gss_decode_once");
#else
#endif /* _SUN_SDK_ */
return SASL_FAIL;
}
}
}
if (*inputlen == 0) {
/* need more data ! */
*outputlen = 0;
return SASL_OK;
}
}
/* ok, let's queue it up; not enough data */
*inputlen = 0;
*outputlen = 0;
return SASL_OK;
} else {
}
output_token->length = 0;
#if defined _SUN_SDK_ && defined GSSAPI_PROTECT
if (LOCK_MUTEX(&global_mutex) < 0)
return (SASL_FAIL);
#endif /* _SUN_SDK_ && GSSAPI_PROTECT */
NULL,
NULL);
if (maj_stat != GSS_S_COMPLETE)
{
#if defined _SUN_SDK_ && defined GSSAPI_PROTECT
#endif /* _SUN_SDK_ && GSSAPI_PROTECT */
return SASL_FAIL;
}
if (outputlen)
if (output_token->value) {
if (output) {
*outputlen);
#if defined _SUN_SDK_ && defined GSSAPI_PROTECT
#endif /* _SUN_SDK_ && GSSAPI_PROTECT */
return result;
}
}
}
#if defined _SUN_SDK_ && defined GSSAPI_PROTECT
#endif /* _SUN_SDK_ && GSSAPI_PROTECT */
/* reset for the next packet */
#ifndef _SUN_SDK_
#endif /* !_SUN_SDK_ */
return SASL_OK;
}
{
int ret;
return ret;
}
{
#ifdef _SUN_SDK_
return (NULL);
}
#endif /* _SUN_SDK_ */
return ret;
}
{
if (!text) return;
}
}
}
}
#ifdef _SUN_SDK_
}
/*
* Note that the oid returned by rpc_gss_mech_to_oid should not
* be released
*/
#endif /* _SUN_SDK_ */
}
if (text->encode_buf) {
}
if (text->decode_buf) {
}
if (text->decode_once_buf) {
}
if (text->enc_in_buf) {
}
}
}
}
#ifdef _SUN_SDK_
#ifdef HAVE_RPC_GSS_MECH_TO_OID
#include <rpc/rpcsec_gss.h>
#endif /* HAVE_RPC_GSS_MECH_TO_OID */
static int
{
#ifdef HAVE_RPC_GSS_MECH_TO_OID
{9, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x02"};
/* 1.2.840.113554.1.2.2 */
#endif /* HAVE_RPC_GSS_MECH_TO_OID */
return (SASL_OK);
}
static int
{
return SASL_FAIL;
}
return SASL_FAIL;
}
return SASL_OK;
}
#endif /* _SUN_SDK_ */
const sasl_utils_t *utils)
{
#ifdef _SUN_SDK_
if (conn_context == NULL)
return;
#ifdef _INTEGRATED_SOLARIS_
#endif /* _INTEGRATED_SOLARIS_ */
#endif /* _SUN_SDK_ */
#if defined _SUN_SDK_ && defined GSSAPI_PROTECT
(void) LOCK_MUTEX(&global_mutex);
#endif /* _SUN_SDK_ && GSSAPI_PROTECT */
#if defined _SUN_SDK_ && defined GSSAPI_PROTECT
#endif /* _SUN_SDK_ && GSSAPI_PROTECT */
}
/***************************** Server Section *****************************/
static int
void **conn_context)
{
#if defined _SUN_SDK_ && defined GSSAPI_PROTECT
if (LOCK_MUTEX(&global_mutex) < 0)
return (SASL_FAIL);
#endif /* _SUN_SDK_ && GSSAPI_PROTECT */
#if defined _SUN_SDK_ && defined GSSAPI_PROTECT
#endif /* _SUN_SDK_ && GSSAPI_PROTECT */
#ifndef _SUN_SDK_
#endif /* !_SUN_SDK_ */
return SASL_NOMEM;
}
*conn_context = text;
return SASL_OK;
}
static int
const char *clientin,
unsigned clientinlen,
const char **serverout,
unsigned *serveroutlen,
{
#ifdef _SUN_SDK_
#endif /* _SUN_SDK_ */
int ret;
if(!serverout) {
return SASL_BADPARAM;
}
*serveroutlen = 0;
return SASL_NOMEM;
}
#ifdef _SUN_SDK_
#else
#endif /* _SUN_SDK_ */
&text->server_name);
return SASL_FAIL;
}
}
#ifdef _SUN_SDK_
return (ret);
}
#endif /* _SUN_SDK_ */
#ifdef _SUN_SDK_
#else
#endif /* _SUN_SDK_ */
&text->server_creds,
NULL,
NULL);
#ifdef _SUN_SDK_
if (desired_mechs != GSS_C_NULL_OID_SET) {
}
#endif /* _SUN_SDK_ */
return SASL_FAIL;
}
}
if (clientinlen) {
}
maj_stat =
&text->client_name,
NULL,
NULL,
NULL,
NULL);
#ifdef _SUN_SDK_
/* log the local error info, set a more generic error */
gettext("GSSAPI Failure: accept security context error"));
if (output_token->value) {
}
#else
if (output_token->value) {
}
#endif /* _SUN_SDK_ */
return SASL_BADAUTH;
}
if (serveroutlen)
if (output_token->value) {
if (serverout) {
return ret;
}
}
} else {
/* No output token, send an empty string */
#ifndef _SUN_SDK_
serveroutlen = 0;
#endif /* !_SUN_SDK_ */
}
if (maj_stat == GSS_S_COMPLETE) {
/* Switch to ssf negotiation */
}
return SASL_CONTINUE;
case SASL_GSSAPI_STATE_SSFCAP: {
#ifndef _SUN_SDK_
int equal;
#endif /* !_SUN_SDK_ */
#ifndef _SUN_SDK_
#endif /* !_SUN_SDK_ */
/* We ignore whatever the client sent us at this stage */
NULL);
#ifndef _SUN_SDK_
if (name_without_realm.value)
#endif /* !_SUN_SDK_ */
if (name_token.value)
#ifndef _SUN_SDK_
if (without)
#endif /* !_SUN_SDK_ */
#ifdef _INTEGRATED_SOLARIS_
#else
#endif /* _INTEGRATED_SOLARIS_ */
return SASL_BADAUTH;
}
#ifndef _SUN_SDK_
/* If the id contains a realm get the identifier for the user
without the realm and see if it's the same id (i.e.
tmartin == tmartin@ANDREW.CMU.EDU. If this is the case we just want
to return the id (i.e. just "tmartin" */
/* NOTE: libc malloc, as it is freed below by a gssapi internal
* function! */
return SASL_NOMEM;
}
/* cut off string at '@' */
/* Solaris 8/9 gss_import_name doesn't accept GSS_C_NULL_OID here,
so use GSS_C_NT_USER_NAME instead if available. */
#ifdef HAVE_GSS_C_NT_USER_NAME
#else
#endif
&without);
if (name_token.value)
if (without)
return SASL_BADAUTH;
}
&equal);
if (name_token.value)
if (without)
return SASL_BADAUTH;
}
} else {
equal = 0;
}
if (equal) {
return SASL_NOMEM;
}
} else {
return SASL_NOMEM;
}
}
#else
{
}
#endif /* _SUN_SDK_ */
if (name_token.value)
#ifdef _SUN_SDK_
return (ret);
#else
if (name_without_realm.value)
#endif /* _SUN_SDK_ */
/* we have to decide what sort of encryption/integrity/etc.,
we support */
} else {
}
text->requiressf = 0;
} else {
}
/* build up our security properties token */
/* make sure maxbufsize isn't too large */
/* maxbufsize = 0xFFFFFF */
} else {
}
sasldata[0] = 0;
#ifdef _SUN_SDK_
"GSSAPI needs a security layer but one is forbidden");
#else
"GSSAPI needs a security layer but one is forbidden");
#endif /* _SUN_SDK_ */
return SASL_TOOWEAK;
}
if (text->requiressf == 0) {
}
sasldata[0] |= 2;
}
sasldata[0] |= 4;
}
0, /* Just integrity checking here */
NULL,
if (output_token->value)
return SASL_FAIL;
}
if (serveroutlen)
if (output_token->value) {
if (serverout) {
return ret;
}
}
}
/* Wait for ssf request and authid */
return SASL_CONTINUE;
}
case SASL_GSSAPI_STATE_SSFREQ: {
int layerchoice;
NULL,
NULL);
if (maj_stat != GSS_S_COMPLETE) {
return SASL_FAIL;
}
} else {
/* not a supported encryption layer */
#ifdef _SUN_SDK_
"protocol violation: client requested invalid layer");
#else
"protocol violation: client requested invalid layer");
#endif /* _SUN_SDK_ */
/* Mark that we attempted negotiation */
if (output_token->value)
return SASL_FAIL;
}
int ret;
return ret;
}
0, /* strlen(text->authid) */
return ret;
}
/* null authzid */
int ret;
0, /* strlen(text->authid) */
oparams);
return ret;
}
} else {
#ifdef _SUN_SDK_
"token too short");
#else
"token too short");
#endif /* _SUN_SDK_ */
return SASL_FAIL;
}
/* No matter what, set the rest of the oparams */
#ifdef _SUN_SDK_
return (SASL_FAIL);
}
/*
* gss_wrap_size_limit will return very big sizes for
* small input values
*/
else {
}
}
#else
/* xxx this is probably too big */
}
#endif /* _SUN_SDK_ */
return SASL_OK;
}
default:
#ifdef _SUN_SDK_
#else
#endif /* _SUN_SDK_ */
return SASL_FAIL;
}
#ifndef _SUN_SDK_
return SASL_FAIL; /* should never get here */
#endif /* !_SUN_SDK_ */
}
#if defined _SUN_SDK_ && defined GSSAPI_PROTECT
static int
const char *clientin,
unsigned clientinlen,
const char **serverout,
unsigned *serveroutlen,
{
int ret;
if (LOCK_MUTEX(&global_mutex) < 0)
return (SASL_FAIL);
return (ret);
}
#endif /* _SUN_SDK_ && GSSAPI_PROTECT */
{
{
"GSSAPI", /* mech_name */
56, /* max_ssf */
| SASL_SEC_MUTUAL_AUTH, /* security_flags */
| SASL_FEAT_ALLOWS_PROXY, /* features */
NULL, /* glob_context */
&gssapi_server_mech_new, /* mech_new */
#if defined _SUN_SDK_ && defined GSSAPI_PROTECT
&_gssapi_server_mech_step, /* mech_step */
#else
&gssapi_server_mech_step, /* mech_step */
#endif /* _SUN_SDK_ && GSSAPI_PROTECT */
&gssapi_common_mech_dispose, /* mech_dispose */
NULL, /* mech_free */
NULL, /* setpass */
NULL, /* user_query */
NULL, /* idle */
NULL, /* mech_avail */
NULL /* spare */
}
};
#else
const sasl_utils_t *utils,
#endif
int maxversion,
int *out_version,
int *plugcount)
{
unsigned int rl;
#endif
if (maxversion < SASL_SERVER_PLUG_VERSION) {
return SASL_BADVERS;
}
#ifndef _SUN_SDK_
/* unfortunately, we don't check for readability of keytab if it's
the standard one, since we don't know where it is */
/* FIXME: This code is broken */
"Could not find keytab file: %s: %m",
return SASL_FAIL;
}
"path to keytab is > 1024 characters");
return SASL_BUFOVER;
}
}
#endif
#endif /* !_SUN_SDK_ */
/* EXPORT DELETE START */
/* CRYPT DELETE START */
#ifdef _INTEGRATED_SOLARIS_
/*
* Let libsasl know that we are a "Sun" plugin so that privacy
* and integrity will be allowed.
*/
#endif /* _INTEGRATED_SOLARIS_ */
/* CRYPT DELETE END */
/* EXPORT DELETE END */
*plugcount = 1;
return SASL_OK;
}
/***************************** Client Section *****************************/
void **conn_context)
{
#ifdef _SUN_SDK_
#endif /* _SUN_SDK_ */
/* holds state are in */
#if defined _SUN_SDK_ && defined GSSAPI_PROTECT
if (LOCK_MUTEX(&global_mutex) < 0)
return (SASL_FAIL);
#endif /* _SUN_SDK_ && GSSAPI_PROTECT */
#if defined _SUN_SDK_ && defined GSSAPI_PROTECT
#endif /* _SUN_SDK_ && GSSAPI_PROTECT */
#ifndef _SUN_SDK_
#endif /* !_SUN_SDK_ */
return SASL_NOMEM;
}
#ifdef _SUN_SDK_
#endif /* _SUN_SDK_ */
*conn_context = text;
return SASL_OK;
}
const char *serverin,
unsigned serverinlen,
const char **clientout,
unsigned *clientoutlen,
{
#ifdef _SUN_SDK_
#endif /* _SUN_SDK_ */
int ret;
input_token->length = 0;
*clientoutlen = 0;
/* try to get the userid */
#ifdef _SUN_SDK_
if ((auth_result != SASL_OK) &&
(auth_result != SASL_INTERACT)) {
return auth_result;
}
}
if ((user_result != SASL_OK) &&
(user_result != SASL_INTERACT)) {
return user_result;
}
}
#else
int user_result = SASL_OK;
return user_result;
}
#endif /* _SUN_SDK_ */
/* free prompts we got */
if (prompt_need && *prompt_need) {
*prompt_need = NULL;
}
/* if there are prompts not filled in */
#ifdef _SUN_SDK_
if ((user_result == SASL_INTERACT) ||
(auth_result == SASL_INTERACT)) {
/* make the prompt list */
#ifdef _INTEGRATED_SOLARIS_
user_result == SASL_INTERACT ?
gettext("Please enter your authorization name"))
auth_result == SASL_INTERACT ?
gettext("Please enter your authentication name"))
#else
user_result == SASL_INTERACT ?
"Please enter your authorization name"
auth_result == SASL_INTERACT ?
"Please enter your authentication name"
#endif /* _INTEGRATED_SOLARIS_ */
return SASL_INTERACT;
}
#else
if (user_result == SASL_INTERACT) {
/* make the prompt list */
int result =
user_result == SASL_INTERACT ?
return SASL_INTERACT;
}
#endif /* _SUN_SDK_ */
}
return SASL_NOMEM;
}
#ifdef _SUN_SDK_
"GSSAPI Failure: no serverFQDN");
#else
#endif /* _SUN_SDK_ */
return SASL_FAIL;
}
#ifdef _SUN_SDK_
#else
#endif /* _SUN_SDK_ */
&text->server_name);
return SASL_FAIL;
}
}
if (serverinlen == 0)
if (serverinlen) {
}
/* This can't happen under GSSAPI: we have a non-null context
* and no input from the server. However, thanks to Imap,
* which discards our first output, this happens all the time.
* Throw away the context and try again. */
}
/* Setup req_flags properly */
/* We are requesting a security layer */
/* We want to try for privacy */
}
}
#ifdef _SUN_SDK_
#ifdef HAVE_GSS_C_NT_USER_NAME
#else
#endif
&text->client_name);
return SASL_FAIL;
}
return (ret);
}
&text->client_creds,
NULL,
NULL);
if (desired_mechs != GSS_C_NULL_OID_SET) {
}
return SASL_FAIL;
}
}
#endif /* _SUN_SDK_ */
#ifdef _SUN_SDK_
#else
#endif /* _SUN_SDK_ */
#ifdef _SUN_SDK_
#else
#endif /* _SUN_SDK_ */
0,
NULL,
NULL);
if (output_token->value)
return SASL_FAIL;
}
if (output_token->value) {
if (clientout) {
return ret;
}
}
}
if (maj_stat == GSS_S_COMPLETE) {
&text->client_name,
NULL, /* targ_name */
NULL, /* lifetime */
NULL, /* mech */
NULL, /* flags */
NULL, /* local init */
NULL); /* open */
return SASL_FAIL;
}
name_token.length = 0;
NULL);
if (name_token.value)
#ifdef _INTEGRATED_SOLARIS_
#else
#endif /* _INTEGRATED_SOLARIS_ */
return SASL_FAIL;
}
name_token.value, 0,
} else {
name_token.value, 0,
oparams);
}
/* Switch to ssf negotiation */
}
return SASL_CONTINUE;
case SASL_GSSAPI_STATE_SSFCAP: {
NULL,
NULL);
if (maj_stat != GSS_S_COMPLETE) {
return SASL_FAIL;
}
/* taken from kerberos.c */
return SASL_TOOWEAK;
return SASL_BADPARAM;
}
/* need bits of layer -- sasl_ssf_t is unsigned so be careful */
} else {
allowed = 0;
}
} else {
/* good to go */
need = 0;
}
/* bit mask of server support */
/* if client didn't set use strongest layer available */
/* encryption */
mychoice = 4;
/* integrity */
mychoice = 2;
#ifdef _SUN_SDK_
#else
#endif /* _SUN_SDK_ */
/* no layer */
mychoice = 1;
} else {
/* there's no appropriate layering for us! */
return SASL_TOOWEAK;
}
#ifdef _SUN_SDK_
return (SASL_FAIL);
}
/*
* This is a workaround for a Solaris bug where
* gss_wrap_size_limit may return very big sizes for
* small input values
*/
else {
}
}
#else
/* xxx probably too large */
}
#endif /* _SUN_SDK_ */
/* oparams->user is always set, due to canon_user requirements.
* Make sure the client actually requested it though, by checking
* if our context was set.
*/
else
alen = 0;
input_token->value =
return SASL_NOMEM;
}
if (alen)
/* build up our security properties token */
/* make sure maxbufsize isn't too large */
/* maxbufsize = 0xFFFFFF */
} else {
}
0, /* Just integrity checking here */
NULL,
if (output_token->value)
return SASL_FAIL;
}
if (clientoutlen)
if (output_token->value) {
if (clientout) {
return ret;
}
}
}
return SASL_OK;
}
default:
#ifdef _SUN_SDK_
#else
#endif /* _SUN_SDK_ */
return SASL_FAIL;
}
#ifndef _SUN_SDK_
return SASL_FAIL; /* should never get here */
#endif /* !_SUN_SDK_ */
}
#ifdef _SUN_SDK_
static const unsigned long gssapi_required_prompts[] = {
#else
static const long gssapi_required_prompts[] = {
#endif /* _SUN_SDK_ */
};
#if defined _SUN_SDK_ && defined GSSAPI_PROTECT
const char *serverin,
unsigned serverinlen,
const char **clientout,
unsigned *clientoutlen,
{
int ret;
if (LOCK_MUTEX(&global_mutex) < 0)
return (SASL_FAIL);
return (ret);
}
#endif /* _SUN_SDK_ && GSSAPI_PROTECT */
{
{
"GSSAPI", /* mech_name */
56, /* max_ssf */
| SASL_SEC_MUTUAL_AUTH, /* security_flags */
| SASL_FEAT_ALLOWS_PROXY, /* features */
gssapi_required_prompts, /* required_prompts */
NULL, /* glob_context */
&gssapi_client_mech_new, /* mech_new */
#if defined _SUN_SDK_ && defined GSSAPI_PROTECT
&_gssapi_client_mech_step, /* mech_step */
#else
&gssapi_client_mech_step, /* mech_step */
#endif /* _SUN_SDK_ && GSSAPI_PROTECT */
&gssapi_common_mech_dispose, /* mech_dispose */
NULL, /* mech_free */
NULL, /* idle */
NULL, /* spare */
NULL /* spare */
}
};
int maxversion,
int *out_version,
int *plugcount)
{
if (maxversion < SASL_CLIENT_PLUG_VERSION) {
return SASL_BADVERS;
}
/* EXPORT DELETE START */
/* CRYPT DELETE START */
#ifdef _INTEGRATED_SOLARIS_
/*
* Let libsasl know that we are a "Sun" plugin so that privacy
* and integrity will be allowed.
*/
#endif /* _INTEGRATED_SOLARIS_ */
/* CRYPT DELETE END */
/* EXPORT DELETE END */
*plugcount = 1;
return SASL_OK;
}