Use ASN.1 encoder functions to encode CHOICE structure now that we can handle it.
git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@19048 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
@@ -35,102 +35,32 @@
|
|||||||
|
|
||||||
RCSID("$Id$");
|
RCSID("$Id$");
|
||||||
|
|
||||||
OM_uint32
|
|
||||||
_gss_spnego_encode_response(OM_uint32 *minor_status,
|
|
||||||
const NegTokenResp *resp,
|
|
||||||
gss_buffer_t data,
|
|
||||||
u_char **ret_buf)
|
|
||||||
{
|
|
||||||
OM_uint32 ret;
|
|
||||||
u_char *buf;
|
|
||||||
size_t buf_size, buf_len;
|
|
||||||
|
|
||||||
buf_size = 1024;
|
|
||||||
buf = malloc(buf_size);
|
|
||||||
if (buf == NULL) {
|
|
||||||
*minor_status = ENOMEM;
|
|
||||||
return GSS_S_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
do {
|
|
||||||
ret = encode_NegTokenResp(buf + buf_size - 1,
|
|
||||||
buf_size,
|
|
||||||
resp, &buf_len);
|
|
||||||
if (ret == 0) {
|
|
||||||
size_t tmp;
|
|
||||||
|
|
||||||
ret = der_put_length_and_tag(buf + buf_size - buf_len - 1,
|
|
||||||
buf_size - buf_len,
|
|
||||||
buf_len,
|
|
||||||
ASN1_C_CONTEXT,
|
|
||||||
CONS,
|
|
||||||
1,
|
|
||||||
&tmp);
|
|
||||||
if (ret == 0)
|
|
||||||
buf_len += tmp;
|
|
||||||
}
|
|
||||||
if (ret) {
|
|
||||||
if (ret == ASN1_OVERFLOW) {
|
|
||||||
u_char *tmp;
|
|
||||||
|
|
||||||
buf_size *= 2;
|
|
||||||
tmp = realloc (buf, buf_size);
|
|
||||||
if (tmp == NULL) {
|
|
||||||
*minor_status = ENOMEM;
|
|
||||||
free(buf);
|
|
||||||
return GSS_S_FAILURE;
|
|
||||||
}
|
|
||||||
buf = tmp;
|
|
||||||
} else {
|
|
||||||
*minor_status = ret;
|
|
||||||
free(buf);
|
|
||||||
return GSS_S_FAILURE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} while (ret == ASN1_OVERFLOW);
|
|
||||||
|
|
||||||
data->value = buf + buf_size - buf_len;
|
|
||||||
data->length = buf_len;
|
|
||||||
*ret_buf = buf;
|
|
||||||
|
|
||||||
return GSS_S_COMPLETE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static OM_uint32
|
static OM_uint32
|
||||||
send_reject (OM_uint32 *minor_status,
|
send_reject (OM_uint32 *minor_status,
|
||||||
gss_buffer_t output_token)
|
gss_buffer_t output_token)
|
||||||
{
|
{
|
||||||
NegTokenResp resp;
|
NegotiationToken nt;
|
||||||
gss_buffer_desc data;
|
size_t size;
|
||||||
u_char *buf;
|
|
||||||
OM_uint32 ret;
|
|
||||||
|
|
||||||
ALLOC(resp.negResult, 1);
|
nt.element = choice_NegotiationToken_negTokenResp;
|
||||||
if (resp.negResult == NULL) {
|
|
||||||
|
ALLOC(nt.u.negTokenResp.negResult, 1);
|
||||||
|
if (nt.u.negTokenResp.negResult == NULL) {
|
||||||
*minor_status = ENOMEM;
|
*minor_status = ENOMEM;
|
||||||
return GSS_S_FAILURE;
|
return GSS_S_FAILURE;
|
||||||
}
|
}
|
||||||
*(resp.negResult) = reject;
|
*(nt.u.negTokenResp.negResult) = reject;
|
||||||
resp.supportedMech = NULL;
|
nt.u.negTokenResp.supportedMech = NULL;
|
||||||
resp.responseToken = NULL;
|
nt.u.negTokenResp.responseToken = NULL;
|
||||||
resp.mechListMIC = NULL;
|
nt.u.negTokenResp.mechListMIC = NULL;
|
||||||
|
|
||||||
ret = _gss_spnego_encode_response (minor_status, &resp, &data, &buf);
|
ASN1_MALLOC_ENCODE(NegotiationToken,
|
||||||
free_NegTokenResp(&resp);
|
output_token->value, output_token->length, &nt,
|
||||||
if (ret != GSS_S_COMPLETE)
|
&size, *minor_status);
|
||||||
return ret;
|
free_NegotiationToken(&nt);
|
||||||
|
if (*minor_status != 0)
|
||||||
|
return GSS_S_FAILURE;
|
||||||
|
|
||||||
output_token->value = malloc(data.length);
|
|
||||||
if (output_token->value == NULL) {
|
|
||||||
*minor_status = ENOMEM;
|
|
||||||
ret = GSS_S_FAILURE;
|
|
||||||
} else {
|
|
||||||
output_token->length = data.length;
|
|
||||||
memcpy(output_token->value, data.value, output_token->length);
|
|
||||||
}
|
|
||||||
free(buf);
|
|
||||||
if (ret != GSS_S_COMPLETE)
|
|
||||||
return ret;
|
|
||||||
return GSS_S_BAD_MECH;
|
return GSS_S_BAD_MECH;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -345,16 +275,17 @@ send_accept (OM_uint32 *minor_status,
|
|||||||
gss_buffer_t mech_buf,
|
gss_buffer_t mech_buf,
|
||||||
gss_buffer_t output_token)
|
gss_buffer_t output_token)
|
||||||
{
|
{
|
||||||
NegTokenResp resp;
|
NegotiationToken nt;
|
||||||
gss_buffer_desc data;
|
|
||||||
u_char *buf;
|
|
||||||
OM_uint32 ret;
|
OM_uint32 ret;
|
||||||
gss_buffer_desc mech_mic_buf;
|
gss_buffer_desc mech_mic_buf;
|
||||||
|
size_t size;
|
||||||
|
|
||||||
memset(&resp, 0, sizeof(resp));
|
memset(&nt, 0, sizeof(nt));
|
||||||
|
|
||||||
ALLOC(resp.negResult, 1);
|
nt.element = choice_NegotiationToken_negTokenResp;
|
||||||
if (resp.negResult == NULL) {
|
|
||||||
|
ALLOC(nt.u.negTokenResp.negResult, 1);
|
||||||
|
if (nt.u.negTokenResp.negResult == NULL) {
|
||||||
*minor_status = ENOMEM;
|
*minor_status = ENOMEM;
|
||||||
return GSS_S_FAILURE;
|
return GSS_S_FAILURE;
|
||||||
}
|
}
|
||||||
@@ -363,56 +294,56 @@ send_accept (OM_uint32 *minor_status,
|
|||||||
if (mech_token != GSS_C_NO_BUFFER
|
if (mech_token != GSS_C_NO_BUFFER
|
||||||
&& mech_token->length != 0
|
&& mech_token->length != 0
|
||||||
&& mech_buf != GSS_C_NO_BUFFER)
|
&& mech_buf != GSS_C_NO_BUFFER)
|
||||||
*(resp.negResult) = accept_incomplete;
|
*(nt.u.negTokenResp.negResult) = accept_incomplete;
|
||||||
else
|
else
|
||||||
*(resp.negResult) = accept_completed;
|
*(nt.u.negTokenResp.negResult) = accept_completed;
|
||||||
} else {
|
} else {
|
||||||
if (initial_response && context_handle->require_mic)
|
if (initial_response && context_handle->require_mic)
|
||||||
*(resp.negResult) = request_mic;
|
*(nt.u.negTokenResp.negResult) = request_mic;
|
||||||
else
|
else
|
||||||
*(resp.negResult) = accept_incomplete;
|
*(nt.u.negTokenResp.negResult) = accept_incomplete;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (initial_response) {
|
if (initial_response) {
|
||||||
ALLOC(resp.supportedMech, 1);
|
ALLOC(nt.u.negTokenResp.supportedMech, 1);
|
||||||
if (resp.supportedMech == NULL) {
|
if (nt.u.negTokenResp.supportedMech == NULL) {
|
||||||
free_NegTokenResp(&resp);
|
free_NegotiationToken(&nt);
|
||||||
*minor_status = ENOMEM;
|
*minor_status = ENOMEM;
|
||||||
return GSS_S_FAILURE;
|
return GSS_S_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = der_get_oid(context_handle->preferred_mech_type->elements,
|
ret = der_get_oid(context_handle->preferred_mech_type->elements,
|
||||||
context_handle->preferred_mech_type->length,
|
context_handle->preferred_mech_type->length,
|
||||||
resp.supportedMech,
|
nt.u.negTokenResp.supportedMech,
|
||||||
NULL);
|
NULL);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
free_NegTokenResp(&resp);
|
free_NegotiationToken(&nt);
|
||||||
*minor_status = ENOMEM;
|
*minor_status = ENOMEM;
|
||||||
return GSS_S_FAILURE;
|
return GSS_S_FAILURE;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
resp.supportedMech = NULL;
|
nt.u.negTokenResp.supportedMech = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mech_token != GSS_C_NO_BUFFER && mech_token->length != 0) {
|
if (mech_token != GSS_C_NO_BUFFER && mech_token->length != 0) {
|
||||||
ALLOC(resp.responseToken, 1);
|
ALLOC(nt.u.negTokenResp.responseToken, 1);
|
||||||
if (resp.responseToken == NULL) {
|
if (nt.u.negTokenResp.responseToken == NULL) {
|
||||||
free_NegTokenResp(&resp);
|
free_NegotiationToken(&nt);
|
||||||
*minor_status = ENOMEM;
|
*minor_status = ENOMEM;
|
||||||
return GSS_S_FAILURE;
|
return GSS_S_FAILURE;
|
||||||
}
|
}
|
||||||
resp.responseToken->length = mech_token->length;
|
nt.u.negTokenResp.responseToken->length = mech_token->length;
|
||||||
resp.responseToken->data = mech_token->value;
|
nt.u.negTokenResp.responseToken->data = mech_token->value;
|
||||||
mech_token->length = 0;
|
mech_token->length = 0;
|
||||||
mech_token->value = NULL;
|
mech_token->value = NULL;
|
||||||
} else {
|
} else {
|
||||||
resp.responseToken = NULL;
|
nt.u.negTokenResp.responseToken = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mech_buf != GSS_C_NO_BUFFER) {
|
if (mech_buf != GSS_C_NO_BUFFER) {
|
||||||
ALLOC(resp.mechListMIC, 1);
|
ALLOC(nt.u.negTokenResp.mechListMIC, 1);
|
||||||
if (resp.mechListMIC == NULL) {
|
if (nt.u.negTokenResp.mechListMIC == NULL) {
|
||||||
free_NegTokenResp(&resp);
|
free_NegotiationToken(&nt);
|
||||||
*minor_status = ENOMEM;
|
*minor_status = ENOMEM;
|
||||||
return GSS_S_FAILURE;
|
return GSS_S_FAILURE;
|
||||||
}
|
}
|
||||||
@@ -423,19 +354,22 @@ send_accept (OM_uint32 *minor_status,
|
|||||||
mech_buf,
|
mech_buf,
|
||||||
&mech_mic_buf);
|
&mech_mic_buf);
|
||||||
if (ret != GSS_S_COMPLETE) {
|
if (ret != GSS_S_COMPLETE) {
|
||||||
free_NegTokenResp(&resp);
|
free_NegotiationToken(&nt);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
resp.mechListMIC->length = mech_mic_buf.length;
|
nt.u.negTokenResp.mechListMIC->length = mech_mic_buf.length;
|
||||||
resp.mechListMIC->data = mech_mic_buf.value;
|
nt.u.negTokenResp.mechListMIC->data = mech_mic_buf.value;
|
||||||
} else
|
} else
|
||||||
resp.mechListMIC = NULL;
|
nt.u.negTokenResp.mechListMIC = NULL;
|
||||||
|
|
||||||
ret = _gss_spnego_encode_response (minor_status, &resp, &data, &buf);
|
ASN1_MALLOC_ENCODE(NegotiationToken,
|
||||||
if (ret != GSS_S_COMPLETE) {
|
output_token->value, output_token->length,
|
||||||
free_NegTokenResp(&resp);
|
&nt, &size, ret);
|
||||||
return ret;
|
if (ret) {
|
||||||
|
free_NegotiationToken(&nt);
|
||||||
|
*minor_status = ret;
|
||||||
|
return GSS_S_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -443,23 +377,12 @@ send_accept (OM_uint32 *minor_status,
|
|||||||
* it is a SubsequentContextToken (note though RFC 1964
|
* it is a SubsequentContextToken (note though RFC 1964
|
||||||
* specifies encapsulation for all _Kerberos_ tokens).
|
* specifies encapsulation for all _Kerberos_ tokens).
|
||||||
*/
|
*/
|
||||||
output_token->value = malloc(data.length);
|
|
||||||
if (output_token->value == NULL) {
|
|
||||||
*minor_status = ENOMEM;
|
|
||||||
ret = GSS_S_FAILURE;
|
|
||||||
} else {
|
|
||||||
output_token->length = data.length;
|
|
||||||
memcpy(output_token->value, data.value, output_token->length);
|
|
||||||
}
|
|
||||||
free(buf);
|
|
||||||
if (ret != GSS_S_COMPLETE) {
|
|
||||||
free_NegTokenResp(&resp);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = (*(resp.negResult) == accept_completed) ? GSS_S_COMPLETE :
|
if (*(nt.u.negTokenResp.negResult) == accept_completed)
|
||||||
GSS_S_CONTINUE_NEEDED;
|
ret = GSS_S_COMPLETE;
|
||||||
free_NegTokenResp(&resp);
|
else
|
||||||
|
ret = GSS_S_CONTINUE_NEEDED;
|
||||||
|
free_NegotiationToken(&nt);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -785,7 +708,7 @@ _gss_spnego_accept_sec_context
|
|||||||
*/
|
*/
|
||||||
if ((mech_output_token != GSS_C_NO_BUFFER &&
|
if ((mech_output_token != GSS_C_NO_BUFFER &&
|
||||||
mech_output_token->length != 0)
|
mech_output_token->length != 0)
|
||||||
|| ctx->open
|
|| (ctx->open && negResult == accept_incomplete)
|
||||||
|| require_response
|
|| require_response
|
||||||
|| get_mic) {
|
|| get_mic) {
|
||||||
ret2 = send_accept (minor_status,
|
ret2 = send_accept (minor_status,
|
||||||
|
@@ -50,11 +50,10 @@ spnego_reply_internal(OM_uint32 *minor_status,
|
|||||||
gss_buffer_t mech_token,
|
gss_buffer_t mech_token,
|
||||||
gss_buffer_t output_token)
|
gss_buffer_t output_token)
|
||||||
{
|
{
|
||||||
NegTokenResp resp;
|
NegotiationToken nt;
|
||||||
gss_buffer_desc mic_buf;
|
gss_buffer_desc mic_buf;
|
||||||
OM_uint32 ret;
|
OM_uint32 ret;
|
||||||
gss_buffer_desc data;
|
size_t size;
|
||||||
u_char *buf;
|
|
||||||
|
|
||||||
if (mech_buf == GSS_C_NO_BUFFER && mech_token->length == 0) {
|
if (mech_buf == GSS_C_NO_BUFFER && mech_token->length == 0) {
|
||||||
output_token->length = 0;
|
output_token->length = 0;
|
||||||
@@ -63,41 +62,43 @@ spnego_reply_internal(OM_uint32 *minor_status,
|
|||||||
return context_handle->open ? GSS_S_COMPLETE : GSS_S_FAILURE;
|
return context_handle->open ? GSS_S_COMPLETE : GSS_S_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(&resp, 0, sizeof(resp));
|
memset(&nt, 0, sizeof(nt));
|
||||||
|
|
||||||
ALLOC(resp.negResult, 1);
|
nt.element = choice_NegotiationToken_negTokenResp;
|
||||||
if (resp.negResult == NULL) {
|
|
||||||
|
ALLOC(nt.u.negTokenResp.negResult, 1);
|
||||||
|
if (nt.u.negTokenResp.negResult == NULL) {
|
||||||
*minor_status = ENOMEM;
|
*minor_status = ENOMEM;
|
||||||
return GSS_S_FAILURE;
|
return GSS_S_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
resp.supportedMech = NULL;
|
nt.u.negTokenResp.supportedMech = NULL;
|
||||||
|
|
||||||
output_token->length = 0;
|
output_token->length = 0;
|
||||||
output_token->value = NULL;
|
output_token->value = NULL;
|
||||||
|
|
||||||
if (mech_token->length == 0) {
|
if (mech_token->length == 0) {
|
||||||
resp.responseToken = NULL;
|
nt.u.negTokenResp.responseToken = NULL;
|
||||||
*(resp.negResult) = accept_completed;
|
*(nt.u.negTokenResp.negResult) = accept_completed;
|
||||||
} else {
|
} else {
|
||||||
ALLOC(resp.responseToken, 1);
|
ALLOC(nt.u.negTokenResp.responseToken, 1);
|
||||||
if (resp.responseToken == NULL) {
|
if (nt.u.negTokenResp.responseToken == NULL) {
|
||||||
free_NegTokenResp(&resp);
|
free_NegotiationToken(&nt);
|
||||||
*minor_status = ENOMEM;
|
*minor_status = ENOMEM;
|
||||||
return GSS_S_FAILURE;
|
return GSS_S_FAILURE;
|
||||||
}
|
}
|
||||||
resp.responseToken->length = mech_token->length;
|
nt.u.negTokenResp.responseToken->length = mech_token->length;
|
||||||
resp.responseToken->data = mech_token->value;
|
nt.u.negTokenResp.responseToken->data = mech_token->value;
|
||||||
mech_token->length = 0;
|
mech_token->length = 0;
|
||||||
mech_token->value = NULL;
|
mech_token->value = NULL;
|
||||||
|
|
||||||
*(resp.negResult) = accept_incomplete;
|
*(nt.u.negTokenResp.negResult) = accept_incomplete;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mech_buf != GSS_C_NO_BUFFER) {
|
if (mech_buf != GSS_C_NO_BUFFER) {
|
||||||
ALLOC(resp.mechListMIC, 1);
|
ALLOC(nt.u.negTokenResp.mechListMIC, 1);
|
||||||
if (resp.mechListMIC == NULL) {
|
if (nt.u.negTokenResp.mechListMIC == NULL) {
|
||||||
free_NegTokenResp(&resp);
|
free_NegotiationToken(&nt);
|
||||||
*minor_status = ENOMEM;
|
*minor_status = ENOMEM;
|
||||||
return GSS_S_FAILURE;
|
return GSS_S_FAILURE;
|
||||||
}
|
}
|
||||||
@@ -108,40 +109,32 @@ spnego_reply_internal(OM_uint32 *minor_status,
|
|||||||
mech_buf,
|
mech_buf,
|
||||||
&mic_buf);
|
&mic_buf);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
free_NegTokenResp(&resp);
|
free_NegotiationToken(&nt);
|
||||||
*minor_status = ENOMEM;
|
*minor_status = ENOMEM;
|
||||||
return GSS_S_FAILURE;
|
return GSS_S_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
resp.mechListMIC->length = mic_buf.length;
|
nt.u.negTokenResp.mechListMIC->length = mic_buf.length;
|
||||||
resp.mechListMIC->data = mic_buf.value;
|
nt.u.negTokenResp.mechListMIC->data = mic_buf.value;
|
||||||
} else {
|
} else {
|
||||||
resp.mechListMIC = NULL;
|
nt.u.negTokenResp.mechListMIC = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = _gss_spnego_encode_response (minor_status, &resp,
|
ASN1_MALLOC_ENCODE(NegotiationToken,
|
||||||
&data, &buf);
|
output_token->value, output_token->length,
|
||||||
|
&nt, &size, ret);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
free_NegTokenResp(&resp);
|
free_NegotiationToken(&nt);
|
||||||
return ret;
|
*minor_status = ret;
|
||||||
|
return GSS_S_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
output_token->value = malloc(data.length);
|
if (*(nt.u.negTokenResp.negResult) == accept_completed)
|
||||||
if (output_token->value == NULL) {
|
|
||||||
*minor_status = ENOMEM;
|
|
||||||
ret = GSS_S_FAILURE;
|
|
||||||
} else {
|
|
||||||
output_token->length = data.length;
|
|
||||||
memcpy(output_token->value, data.value, output_token->length);
|
|
||||||
}
|
|
||||||
free(buf);
|
|
||||||
|
|
||||||
if (*(resp.negResult) == accept_completed)
|
|
||||||
ret = GSS_S_COMPLETE;
|
ret = GSS_S_COMPLETE;
|
||||||
else
|
else
|
||||||
ret = GSS_S_CONTINUE_NEEDED;
|
ret = GSS_S_CONTINUE_NEEDED;
|
||||||
|
|
||||||
free_NegTokenResp(&resp);
|
free_NegotiationToken(&nt);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user