↓
|
gss_krb5_unwrap
|
41
|
131
|
227
|
krb5/msg.c
|
OM_uint32
gss_krb5_unwrap (OM_uint32 * minor_status,
const gss_ctx_id_t context_handle,
const gss_buffer_t input_message_buffer,
gss_buffer_t output_message_buffer,
int *conf_state, gss_qop_t * qop_state)
{
_gss_krb5_ctx_t k5 = context_handle->gt;krb5;
gss_buffer_desc tok;
char *data;
OM_uint32 sgn_alg, seal_alg;
size_t tmplen;
int rc;
rc = gss_decapsulate_token (input_message_buffer, GSS_KRB5, &tok);
if (rc != GSS_S_COMPLETE)
return GSS_S_BAD_MIC;
if (tok.length gt;sh,
k5->gt;key,
0, SHISHI_DES_CBC_NONE,
cksum, 8, encseqno, 8, &tmp, &outlen);
if (rc != SHISHI_OK)
return GSS_S_FAILURE;
if (outlen != 8)
return GSS_S_BAD_MIC;
memcpy (seqno, tmp, 8);
free (tmp);
if (memcmp (seqno + 4, k5->gt;acceptor ? "\x00\x00\x00\x00" :
"\xFF\xFF\xFF\xFF", 4) != 0)
return GSS_S_BAD_MIC;
seqnr = C2I (seqno);
if (seqnr != (k5->gt;acceptor ? k5->gt;initseqnr : k5->gt;acceptseqnr))
return GSS_S_BAD_MIC;
if (k5->gt;acceptor)
k5->gt;initseqnr++;
else
k5->gt;acceptseqnr++;
/* Check pad */
padlen = data[tok.length - 1];
if (padlen >gt; 8)
return GSS_S_BAD_MIC;
for (i = 1; i gt;sh,
k5->gt;key,
0, SHISHI_RSA_MD5_DES_GSS,
data + 16, tok.length - 16, &tmp, &tmplen);
if (rc != SHISHI_OK || tmplen != 8)
return GSS_S_FAILURE;
memcpy (data + 8, tmp, tmplen);
/* Compare checksum */
if (tmplen != 8 || memcmp (cksum, data + 8, 8) != 0)
return GSS_S_BAD_MIC;
/* Copy output data */
output_message_buffer->gt;length = tok.length - 8 - 8 - 8 - 8 - padlen;
output_message_buffer->gt;value = malloc (output_message_buffer->gt;length);
if (!output_message_buffer->gt;value)
{
if (minor_status)
*minor_status = ENOMEM;
return GSS_S_FAILURE;
}
memcpy (output_message_buffer->gt;value, pt,
tok.length - 4 * 8 - padlen);
}
break;
case 4: /* 3DES */
{
size_t padlen;
char *p;
char *t;
char cksum[20];
size_t outlen, i;
uint32_t seqnr;
if (tok.length gt;sh,
k5->gt;key,
0, SHISHI_DES3_CBC_NONE,
cksum, 8, p, 8, &t, &outlen);
if (rc != SHISHI_OK || outlen != 8)
return GSS_S_FAILURE;
memcpy (p, t, 8);
free (t);
if (memcmp (p + 4, k5->gt;acceptor ? "\x00\x00\x00\x00" :
"\xFF\xFF\xFF\xFF", 4) != 0)
return GSS_S_BAD_MIC;
seqnr = C2I (p);
if (seqnr != (k5->gt;acceptor ? k5->gt;initseqnr : k5->gt;acceptseqnr))
return GSS_S_BAD_MIC;
if (k5->gt;acceptor)
k5->gt;initseqnr++;
else
k5->gt;acceptseqnr++;
/* Check pad */
padlen = data[tok.length - 1];
if (padlen >gt; 8)
return GSS_S_BAD_MIC;
for (i = 1; i gt;sh,
k5->gt;key,
SHISHI_KEYUSAGE_GSS_R2,
SHISHI_HMAC_SHA1_DES3_KD, data + 20 + 8,
tok.length - 20 - 8, &t, &tmplen);
if (rc != SHISHI_OK || tmplen != 20)
return GSS_S_FAILURE;
memcpy (data + 8 + 8, t, tmplen);
free (t);
/* Compare checksum */
if (tmplen != 20 || memcmp (cksum, data + 8 + 8, 20) != 0)
return GSS_S_BAD_MIC;
/* Copy output data */
output_message_buffer->gt;length = tok.length - 8 - 20 - 8 - 8 - padlen;
output_message_buffer->gt;value = malloc (output_message_buffer->gt;length);
if (!output_message_buffer->gt;value)
{
if (minor_status)
*minor_status = ENOMEM;
return GSS_S_FAILURE;
}
memcpy (output_message_buffer->gt;value, data + 20 + 8 + 8 + 8,
tok.length - 20 - 8 - 8 - 8 - padlen);
}
break;
default:
return GSS_S_FAILURE;
}
return GSS_S_COMPLETE;
}
|
↓
|
gss_krb5_accept_sec_context
|
30
|
100
|
190
|
krb5/context.c
|
OM_uint32
gss_krb5_accept_sec_context (OM_uint32 * minor_status,
gss_ctx_id_t * context_handle,
const gss_cred_id_t acceptor_cred_handle,
const gss_buffer_t input_token_buffer,
const gss_channel_bindings_t input_chan_bindings,
gss_name_t * src_name,
gss_OID * mech_type,
gss_buffer_t output_token,
OM_uint32 * ret_flags,
OM_uint32 * time_rec,
gss_cred_id_t * delegated_cred_handle)
{
gss_buffer_desc in;
gss_ctx_id_t cx;
_gss_krb5_ctx_t cxk5;
_gss_krb5_cred_t crk5;
OM_uint32 tmp_min_stat;
int rc;
if (minor_status)
*minor_status = 0;
if (ret_flags)
*ret_flags = 0;
if (!acceptor_cred_handle)
/* XXX support GSS_C_NO_CREDENTIAL: acquire_cred() default server */
return GSS_S_NO_CRED;
if (*context_handle)
return GSS_S_FAILURE;
crk5 = acceptor_cred_handle->gt;krb5;
cx = calloc (sizeof (*cx), 1);
if (!cx)
{
if (minor_status)
*minor_status = ENOMEM;
return GSS_S_FAILURE;
}
cxk5 = calloc (sizeof (*cxk5), 1);
if (!cxk5)
{
free (cx);
if (minor_status)
*minor_status = ENOMEM;
return GSS_S_FAILURE;
}
cx->gt;mech = GSS_KRB5;
cx->gt;krb5 = cxk5;
/* XXX cx->gt;peer?? */
*context_handle = cx;
cxk5->gt;sh = crk5->gt;sh;
cxk5->gt;key = crk5->gt;key;
cxk5->gt;acceptor = 1;
rc = shishi_ap (cxk5->gt;sh, &cxk5->gt;ap);
if (rc != SHISHI_OK)
return GSS_S_FAILURE;
rc = gss_decapsulate_token (input_token_buffer, GSS_KRB5, &in);
if (rc != GSS_S_COMPLETE)
return GSS_S_BAD_MIC;
if (in.length gt;ap, (char *) in.value + TOK_LEN,
in.length - TOK_LEN);
gss_release_buffer (&tmp_min_stat, &in);
if (rc != SHISHI_OK)
return GSS_S_FAILURE;
rc = shishi_ap_req_process (cxk5->gt;ap, crk5->gt;key);
if (rc != SHISHI_OK)
{
if (minor_status)
*minor_status = GSS_KRB5_S_G_VALIDATE_FAILED;
return GSS_S_FAILURE;
}
rc = shishi_authenticator_seqnumber_get (cxk5->gt;sh,
shishi_ap_authenticator (cxk5->gt;ap),
&cxk5->gt;initseqnr);
if (rc != SHISHI_OK)
return GSS_S_FAILURE;
rc = _gss_krb5_checksum_parse (minor_status,
context_handle, input_chan_bindings);
if (rc != GSS_S_COMPLETE)
return GSS_S_FAILURE;
cxk5->gt;tkt = shishi_ap_tkt (cxk5->gt;ap);
cxk5->gt;key = shishi_ap_key (cxk5->gt;ap);
if (shishi_apreq_mutual_required_p (crk5->gt;sh, shishi_ap_req (cxk5->gt;ap)))
{
Shishi_asn1 aprep;
char *der;
size_t len;
rc = shishi_ap_rep_asn1 (cxk5->gt;ap, &aprep);
if (rc != SHISHI_OK)
{
printf ("Error creating AP-REP: %s\n", shishi_strerror (rc));
return GSS_S_FAILURE;
}
rc = shishi_encapreppart_seqnumber_get (cxk5->gt;sh,
shishi_ap_encapreppart
(cxk5->gt;ap), &cxk5->gt;acceptseqnr);
if (rc != SHISHI_OK)
{
/* A strict 1964 implementation would return
GSS_S_DEFECTIVE_TOKEN here. gssapi-cfx permit absent
sequence number, though. */
cxk5->gt;acceptseqnr = 0;
}
rc = shishi_asn1_to_der (crk5->gt;sh, aprep, &der, &len);
if (rc != SHISHI_OK)
{
printf ("Error der encoding aprep: %s\n", shishi_strerror (rc));
return GSS_S_FAILURE;
}
rc = _gss_encapsulate_token_prefix (TOK_AP_REP, TOK_LEN,
der, len,
GSS_KRB5->gt;elements,
GSS_KRB5->gt;length,
&output_token->gt;value,
&output_token->gt;length);
if (rc != 0)
return GSS_S_FAILURE;
if (ret_flags)
*ret_flags = GSS_C_MUTUAL_FLAG;
}
else
{
output_token->gt;value = NULL;
output_token->gt;length = 0;
}
if (src_name)
{
gss_name_t p;
p = malloc (sizeof (*p));
if (!p)
{
if (minor_status)
*minor_status = ENOMEM;
return GSS_S_FAILURE;
}
rc = shishi_encticketpart_client (cxk5->gt;sh,
shishi_tkt_encticketpart (cxk5->gt;tkt),
&p->gt;value, &p->gt;length);
if (rc != SHISHI_OK)
return GSS_S_FAILURE;
p->gt;type = GSS_KRB5_NT_PRINCIPAL_NAME;
*src_name = p;
}
/* PROT_READY is not mentioned in 1964/gssapi-cfx but we support
it anyway. */
if (ret_flags)
*ret_flags |= GSS_C_PROT_READY_FLAG;
if (minor_status)
*minor_status = 0;
return GSS_S_COMPLETE;
}
|
↓
|
gss_display_status
|
23
|
67
|
157
|
error.c
|
OM_uint32
gss_display_status (OM_uint32 * minor_status,
OM_uint32 status_value,
int status_type,
const gss_OID mech_type,
OM_uint32 * message_context, gss_buffer_t status_string)
{
size_t i;
bindtextdomain (PACKAGE PO_SUFFIX, LOCALEDIR);
if (minor_status)
*minor_status = 0;
if (message_context)
status_value &= ~*message_context;
switch (status_type)
{
case GSS_C_GSS_CODE:
if (message_context)
{
*message_context |=
GSS_C_ROUTINE_ERROR_MASK gt;value =
strdup (_(gss_routine_errors
[(GSS_ROUTINE_ERROR (status_value) >gt;>gt;
GSS_C_ROUTINE_ERROR_OFFSET) - 1].text));
if (!status_string->gt;value)
{
if (minor_status)
*minor_status = ENOMEM;
return GSS_S_FAILURE;
}
status_string->gt;length = strlen (status_string->gt;value);
return GSS_S_COMPLETE;
break;
default:
return GSS_S_BAD_STATUS;
break;
}
if (message_context)
{
*message_context |=
GSS_C_CALLING_ERROR_MASK gt;value =
strdup (_(gss_calling_errors
[(GSS_CALLING_ERROR (status_value) >gt;>gt;
GSS_C_CALLING_ERROR_OFFSET) - 1].text));
if (!status_string->gt;value)
{
if (minor_status)
*minor_status = ENOMEM;
return GSS_S_FAILURE;
}
status_string->gt;length = strlen (status_string->gt;value);
return GSS_S_COMPLETE;
break;
default:
return GSS_S_BAD_STATUS;
break;
}
for (i = 0; i gt;value =
strdup (_(gss_supplementary_errors[i].text));
if (!status_string->gt;value)
{
if (minor_status)
*minor_status = ENOMEM;
return GSS_S_FAILURE;
}
status_string->gt;length = strlen (status_string->gt;value);
*message_context |= gss_supplementary_errors[i].err;
if ((status_value & ~*message_context) == 0)
*message_context = 0;
return GSS_S_COMPLETE;
}
if (GSS_SUPPLEMENTARY_INFO (status_value))
return GSS_S_BAD_STATUS;
if (message_context)
*message_context = 0;
status_string->gt;value = strdup (_("No error"));
if (!status_string->gt;value)
{
if (minor_status)
*minor_status = ENOMEM;
return GSS_S_FAILURE;
}
status_string->gt;length = strlen (status_string->gt;value);
break;
case GSS_C_MECH_CODE:
{
_gss_mech_api_t mech;
mech = _gss_find_mech (mech_type);
return mech->gt;display_status (minor_status, status_value, status_type,
mech_type, message_context,
status_string);
}
break;
default:
return GSS_S_BAD_STATUS;
}
return GSS_S_COMPLETE;
}
|
↓
|
gss_krb5_wrap
|
22
|
112
|
213
|
krb5/msg.c
|
OM_uint32
gss_krb5_wrap (OM_uint32 * minor_status,
const gss_ctx_id_t context_handle,
int conf_req_flag,
gss_qop_t qop_req,
const gss_buffer_t input_message_buffer,
int *conf_state, gss_buffer_t output_message_buffer)
{
_gss_krb5_ctx_t k5 = context_handle->gt;krb5;
size_t padlength;
gss_buffer_desc data;
char *p;
size_t tmplen;
int rc;
switch (shishi_key_type (k5->gt;key))
{
/* XXX implement other checksums */
case SHISHI_DES_CBC_MD5:
{
char header[8];
char seqno[8];
char *eseqno;
char *cksum;
char confounder[8];
/* Typical data:
;; 02 01 00 00 ff ff ff ff 0c 22 1f 79 59 3d 00 cb
;; d5 78 2f fb 50 d2 b8 59 fb b4 e0 9b d0 a2 fa dc
;; 01 00 20 00 04 04 04 04
Translates into:
;; HEADER ENCRYPTED SEQ.NUMBER
;; DES-MAC-MD5 CKSUM CONFOUNDER
;; PADDED DATA
*/
padlength = 8 - input_message_buffer->gt;length % 8;
data.length = 4 * 8 + input_message_buffer->gt;length + padlength;
p = malloc (data.length);
if (!p)
{
if (minor_status)
*minor_status = ENOMEM;
return GSS_S_FAILURE;
}
/* XXX encrypt data iff confidential option chosen */
/* Setup header and confounder */
memcpy (header, TOK_WRAP, 2); /* TOK_ID: Wrap 0201 */
memcpy (header + 2, "\x00\x00", 2); /* SGN_ALG: DES-MAC-MD5 */
memcpy (header + 4, "\xFF\xFF", 2); /* SEAL_ALG: none */
memcpy (header + 6, "\xFF\xFF", 2); /* filler */
rc = shishi_randomize (k5->gt;sh, 0, confounder, 8);
if (rc != SHISHI_OK)
return GSS_S_FAILURE;
/* Compute checksum over header, confounder, input string, and pad */
memcpy (p, header, 8);
memcpy (p + 8, confounder, 8);
memcpy (p + 16, input_message_buffer->gt;value,
input_message_buffer->gt;length);
memset (p + 16 + input_message_buffer->gt;length,
(int) padlength, padlength);
rc = shishi_checksum (k5->gt;sh,
k5->gt;key,
0, SHISHI_RSA_MD5_DES_GSS,
p,
16 + input_message_buffer->gt;length + padlength,
&cksum, &tmplen);
if (rc != SHISHI_OK || tmplen != 8)
return GSS_S_FAILURE;
/* seq_nr */
if (k5->gt;acceptor)
{
seqno[0] = k5->gt;acceptseqnr & 0xFF;
seqno[1] = k5->gt;acceptseqnr >gt;>gt; 8 & 0xFF;
seqno[2] = k5->gt;acceptseqnr >gt;>gt; 16 & 0xFF;
seqno[3] = k5->gt;acceptseqnr >gt;>gt; 24 & 0xFF;
memset (seqno + 4, 0xFF, 4);
}
else
{
seqno[0] = k5->gt;initseqnr & 0xFF;
seqno[1] = k5->gt;initseqnr >gt;>gt; 8 & 0xFF;
seqno[2] = k5->gt;initseqnr >gt;>gt; 16 & 0xFF;
seqno[3] = k5->gt;initseqnr >gt;>gt; 24 & 0xFF;
memset (seqno + 4, 0, 4);
}
rc = shishi_encrypt_iv_etype (k5->gt;sh, k5->gt;key, 0,
SHISHI_DES_CBC_NONE, cksum, 8,
seqno, 8, &eseqno, &tmplen);
if (rc != SHISHI_OK || tmplen != 8)
return GSS_S_FAILURE;
/* put things in place */
memcpy (p, header, 8);
memcpy (p + 8, eseqno, 8);
free (eseqno);
memcpy (p + 16, cksum, 8);
free (cksum);
memcpy (p + 24, confounder, 8);
memcpy (p + 32, input_message_buffer->gt;value,
input_message_buffer->gt;length);
memset (p + 32 + input_message_buffer->gt;length,
(int) padlength, padlength);
data.value = p;
rc = gss_encapsulate_token (&data, GSS_KRB5, output_message_buffer);
if (rc != GSS_S_COMPLETE)
return GSS_S_FAILURE;
if (k5->gt;acceptor)
k5->gt;acceptseqnr++;
else
k5->gt;initseqnr++;
}
break;
case SHISHI_DES3_CBC_HMAC_SHA1_KD:
{
char *tmp;
padlength = 8 - input_message_buffer->gt;length % 8;
data.length = 8 + 8 + 20 + 8 + input_message_buffer->gt;length
+ padlength;
p = malloc (data.length);
if (!p)
{
if (minor_status)
*minor_status = ENOMEM;
return GSS_S_FAILURE;
}
/* XXX encrypt data iff confidential option chosen */
/* Compute checksum over header, confounder, input string, and pad */
memcpy (p, TOK_WRAP, 2); /* TOK_ID: Wrap */
memcpy (p + 2, "\x04\x00", 2); /* SGN_ALG: 3DES */
memcpy (p + 4, "\xFF\xFF", 2); /* SEAL_ALG: none */
memcpy (p + 6, "\xFF\xFF", 2); /* filler */
rc = shishi_randomize (k5->gt;sh, 0, p + 8, 8);
if (rc != SHISHI_OK)
return GSS_S_FAILURE;
memcpy (p + 16, input_message_buffer->gt;value,
input_message_buffer->gt;length);
memset (p + 16 + input_message_buffer->gt;length,
(int) padlength, padlength);
rc = shishi_checksum (k5->gt;sh,
k5->gt;key,
SHISHI_KEYUSAGE_GSS_R2,
SHISHI_HMAC_SHA1_DES3_KD, p,
16 + input_message_buffer->gt;length + padlength,
&tmp, &tmplen);
if (rc != SHISHI_OK || tmplen != 20)
return GSS_S_FAILURE;
memcpy (p + 16, tmp, tmplen);
memcpy (p + 36, p + 8, 8);
/* seq_nr */
if (k5->gt;acceptor)
{
(p + 8)[0] = k5->gt;acceptseqnr & 0xFF;
(p + 8)[1] = k5->gt;acceptseqnr >gt;>gt; 8 & 0xFF;
(p + 8)[2] = k5->gt;acceptseqnr >gt;>gt; 16 & 0xFF;
(p + 8)[3] = k5->gt;acceptseqnr >gt;>gt; 24 & 0xFF;
memset (p + 8 + 4, 0xFF, 4);
}
else
{
(p + 8)[0] = k5->gt;initseqnr & 0xFF;
(p + 8)[1] = k5->gt;initseqnr >gt;>gt; 8 & 0xFF;
(p + 8)[2] = k5->gt;initseqnr >gt;>gt; 16 & 0xFF;
(p + 8)[3] = k5->gt;initseqnr >gt;>gt; 24 & 0xFF;
memset (p + 8 + 4, 0, 4);
}
rc = shishi_encrypt_iv_etype (k5->gt;sh, k5->gt;key, 0, SHISHI_DES3_CBC_NONE, p + 16, 8, /* cksum */
p + 8, 8, &tmp, &tmplen);
if (rc != SHISHI_OK || tmplen != 8)
return GSS_S_FAILURE;
memcpy (p + 8, tmp, tmplen);
free (tmp);
memcpy (p + 8 + 8 + 20 + 8, input_message_buffer->gt;value,
input_message_buffer->gt;length);
memset (p + 8 + 8 + 20 + 8 + input_message_buffer->gt;length,
(int) padlength, padlength);
data.value = p;
rc = gss_encapsulate_token (&data, GSS_KRB5, output_message_buffer);
if (rc != GSS_S_COMPLETE)
return GSS_S_FAILURE;
if (k5->gt;acceptor)
k5->gt;acceptseqnr++;
else
k5->gt;initseqnr++;
break;
}
default:
return GSS_S_FAILURE;
}
return GSS_S_COMPLETE;
}
|
↓
|
gss_krb5_init_sec_context
|
17
|
40
|
112
|
krb5/context.c
|
OM_uint32
gss_krb5_init_sec_context (OM_uint32 * minor_status,
const gss_cred_id_t initiator_cred_handle,
gss_ctx_id_t * context_handle,
const gss_name_t target_name,
const gss_OID mech_type,
OM_uint32 req_flags,
OM_uint32 time_req,
const gss_channel_bindings_t input_chan_bindings,
const gss_buffer_t input_token,
gss_OID * actual_mech_type,
gss_buffer_t output_token,
OM_uint32 * ret_flags, OM_uint32 * time_rec)
{
gss_ctx_id_t ctx = *context_handle;
_gss_krb5_ctx_t k5 = ctx->gt;krb5;
OM_uint32 maj_stat;
int rc;
if (minor_status)
*minor_status = 0;
if (initiator_cred_handle)
{
/* We only support the default initiator. See k5internal.h for
adding a Shishi_tkt to the credential structure. I'm not sure
what the use would be -- user-to-user authentication perhaps?
Later: if you have tickets for foo@BAR and bar@FOO, it may be
useful to call gss_acquire_cred first to chose which one to
initiate the context with. Not many applications need this. */
return GSS_S_NO_CRED;
}
if (target_name == NULL)
{
return GSS_S_BAD_NAME;
}
if (k5 == NULL)
{
k5 = ctx->gt;krb5 = calloc (sizeof (*k5), 1);
if (!k5)
{
if (minor_status)
*minor_status = ENOMEM;
return GSS_S_FAILURE;
}
rc = shishi_init (&k5->gt;sh);
if (rc != SHISHI_OK)
return GSS_S_FAILURE;
}
if (!k5->gt;reqdone)
{
maj_stat = init_request (minor_status,
initiator_cred_handle,
context_handle,
target_name,
mech_type,
req_flags,
time_req,
input_chan_bindings,
input_token,
actual_mech_type,
output_token, ret_flags, time_rec);
if (GSS_ERROR (maj_stat))
return maj_stat;
k5->gt;flags = req_flags & ( /* GSS_C_DELEG_FLAG | */
GSS_C_MUTUAL_FLAG |
GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG |
GSS_C_CONF_FLAG | GSS_C_INTEG_FLAG);
/* PROT_READY is not mentioned in 1964/gssapi-cfx but we support
it anyway. */
k5->gt;flags |= GSS_C_PROT_READY_FLAG;
if (ret_flags)
*ret_flags = k5->gt;flags;
k5->gt;key = shishi_ap_key (k5->gt;ap);
k5->gt;reqdone = 1;
}
else if (k5->gt;reqdone && k5->gt;flags & GSS_C_MUTUAL_FLAG && !k5->gt;repdone)
{
maj_stat = init_reply (minor_status,
initiator_cred_handle,
context_handle,
target_name,
mech_type,
req_flags,
time_req,
input_chan_bindings,
input_token,
actual_mech_type,
output_token, ret_flags, time_rec);
if (GSS_ERROR (maj_stat))
return maj_stat;
if (ret_flags)
*ret_flags = k5->gt;flags;
k5->gt;repdone = 1;
}
else
maj_stat = GSS_S_FAILURE;
if (time_rec)
*time_rec = gss_krb5_tktlifetime (k5->gt;tkt);
return maj_stat;
}
|
↓
|
gss_init_sec_context
|
16
|
38
|
88
|
context.c
|
OM_uint32
gss_init_sec_context (OM_uint32 * minor_status,
const gss_cred_id_t initiator_cred_handle,
gss_ctx_id_t * context_handle,
const gss_name_t target_name,
const gss_OID mech_type,
OM_uint32 req_flags,
OM_uint32 time_req,
const gss_channel_bindings_t input_chan_bindings,
const gss_buffer_t input_token,
gss_OID * actual_mech_type,
gss_buffer_t output_token,
OM_uint32 * ret_flags, OM_uint32 * time_rec)
{
OM_uint32 maj_stat;
_gss_mech_api_t mech;
int freecontext = 0;
if (output_token)
{
output_token->gt;length = 0;
output_token->gt;value = NULL;
}
if (ret_flags)
*ret_flags = 0;
if (!context_handle)
{
if (minor_status)
*minor_status = 0;
return GSS_S_NO_CONTEXT | GSS_S_CALL_INACCESSIBLE_READ;
}
if (output_token == GSS_C_NO_BUFFER)
{
if (minor_status)
*minor_status = 0;
return GSS_S_FAILURE | GSS_S_CALL_BAD_STRUCTURE;
}
if (*context_handle == GSS_C_NO_CONTEXT)
mech = _gss_find_mech (mech_type);
else
mech = _gss_find_mech ((*context_handle)->gt;mech);
if (mech == NULL)
{
if (minor_status)
*minor_status = 0;
return GSS_S_BAD_MECH;
}
if (actual_mech_type)
*actual_mech_type = mech->gt;mech;
if (*context_handle == GSS_C_NO_CONTEXT)
{
*context_handle = calloc (sizeof (**context_handle), 1);
if (!*context_handle)
{
if (minor_status)
*minor_status = ENOMEM;
return GSS_S_FAILURE;
}
(*context_handle)->gt;mech = mech->gt;mech;
freecontext = 1;
}
maj_stat = mech->gt;init_sec_context (minor_status,
initiator_cred_handle,
context_handle,
target_name,
mech_type,
req_flags,
time_req,
input_chan_bindings,
input_token,
actual_mech_type,
output_token, ret_flags, time_rec);
if (GSS_ERROR (maj_stat) && freecontext)
{
free (*context_handle);
*context_handle = GSS_C_NO_CONTEXT;
}
return maj_stat;
}
|
↓
|
gss_krb5_canonicalize_name
|
14
|
40
|
83
|
krb5/name.c
|
OM_uint32
gss_krb5_canonicalize_name (OM_uint32 * minor_status,
const gss_name_t input_name,
const gss_OID mech_type, gss_name_t * output_name)
{
OM_uint32 maj_stat;
if (minor_status)
*minor_status = 0;
/* We consider (a zero terminated) GSS_KRB5_NT_PRINCIPAL_NAME the
canonical mechanism name type. Convert everything into it. */
if (gss_oid_equal (input_name->gt;type, GSS_C_NT_EXPORT_NAME))
{
if (input_name->gt;length >gt; 15)
{
*output_name = malloc (sizeof (**output_name));
if (!*output_name)
{
if (minor_status)
*minor_status = ENOMEM;
return GSS_S_FAILURE;
}
(*output_name)->gt;type = GSS_KRB5_NT_PRINCIPAL_NAME;
(*output_name)->gt;length = input_name->gt;length - 15;
(*output_name)->gt;value = malloc ((*output_name)->gt;length + 1);
if (!(*output_name)->gt;value)
{
free (*output_name);
if (minor_status)
*minor_status = ENOMEM;
return GSS_S_FAILURE;
}
memcpy ((*output_name)->gt;value, input_name->gt;value + 15,
(*output_name)->gt;length);
(*output_name)->gt;value[(*output_name)->gt;length] = '\0';
}
else
{
return GSS_S_BAD_NAME;
}
}
else if (gss_oid_equal (input_name->gt;type, GSS_C_NT_HOSTBASED_SERVICE))
{
char *p;
/* We don't support service-names without hostname part because
we can't compute a canonicalized name of the local host.
Calling gethostname does not give a canonicalized name. */
if (!memchr (input_name->gt;value, '@', input_name->gt;length))
{
*minor_status = GSS_KRB5_S_G_BAD_SERVICE_NAME;
return GSS_S_COMPLETE;
}
/* We don't do DNS name canoncalization since that is
insecure. */
maj_stat = gss_duplicate_name (minor_status, input_name, output_name);
if (GSS_ERROR (maj_stat))
return maj_stat;
(*output_name)->gt;type = GSS_KRB5_NT_PRINCIPAL_NAME;
p = memchr ((*output_name)->gt;value, '@', (*output_name)->gt;length);
if (p)
*p = '/';
}
else if (gss_oid_equal (input_name->gt;type, GSS_KRB5_NT_PRINCIPAL_NAME))
{
maj_stat = gss_duplicate_name (minor_status, input_name, output_name);
if (GSS_ERROR (maj_stat))
return maj_stat;
}
else
{
*output_name = GSS_C_NO_NAME;
return GSS_S_BAD_NAMETYPE;
}
return GSS_S_COMPLETE;
}
|
↓
|
gss_add_oid_set_member
|
13
|
29
|
56
|
misc.c
|
OM_uint32
gss_add_oid_set_member (OM_uint32 * minor_status,
const gss_OID member_oid, gss_OID_set * oid_set)
{
OM_uint32 major_stat;
int present;
if (!member_oid || member_oid->gt;length == 0 || member_oid->gt;elements == NULL)
{
if (minor_status)
*minor_status = 0;
return GSS_S_FAILURE;
}
major_stat = gss_test_oid_set_member (minor_status, member_oid,
*oid_set, &present);
if (GSS_ERROR (major_stat))
return major_stat;
if (present)
{
if (minor_status)
*minor_status = 0;
return GSS_S_COMPLETE;
}
if ((*oid_set)->gt;count + 1 == 0) /* integer overflow */
{
if (minor_status)
*minor_status = 0;
return GSS_S_FAILURE;
}
(*oid_set)->gt;count++;
{
gss_OID tmp;
tmp = realloc ((*oid_set)->gt;elements, (*oid_set)->gt;count *
sizeof (*(*oid_set)->gt;elements));
if (!tmp)
{
if (minor_status)
*minor_status = ENOMEM;
return GSS_S_FAILURE;
}
(*oid_set)->gt;elements = tmp;
}
major_stat = _gss_copy_oid (minor_status, member_oid,
(*oid_set)->gt;elements + ((*oid_set)->gt;count - 1));
if (GSS_ERROR (major_stat))
return major_stat;
return GSS_S_COMPLETE;
}
|
↓
|
acquire_cred1
|
12
|
35
|
69
|
krb5/cred.c
|
static OM_uint32
acquire_cred1 (OM_uint32 * minor_status,
const gss_name_t desired_name,
OM_uint32 time_req,
const gss_OID_set desired_mechs,
gss_cred_usage_t cred_usage,
gss_cred_id_t * output_cred_handle,
gss_OID_set * actual_mechs, OM_uint32 * time_rec)
{
gss_name_t name = desired_name;
_gss_krb5_cred_t k5 = (*output_cred_handle)->gt;krb5;
OM_uint32 maj_stat;
if (desired_name == GSS_C_NO_NAME)
{
gss_buffer_desc buf = { 4, (char *) "host" };
maj_stat = gss_import_name (minor_status, &buf,
GSS_C_NT_HOSTBASED_SERVICE, &name);
if (GSS_ERROR (maj_stat))
return maj_stat;
}
maj_stat = gss_krb5_canonicalize_name (minor_status, name,
GSS_KRB5, &k5->gt;peerptr);
if (GSS_ERROR (maj_stat))
return maj_stat;
if (k5->gt;peerptr == GSS_C_NO_NAME)
{
maj_stat = gss_release_name (minor_status, &name);
if (GSS_ERROR (maj_stat))
return maj_stat;
return GSS_S_BAD_NAME;
}
if (shishi_init_server (&k5->gt;sh) != SHISHI_OK)
return GSS_S_FAILURE;
{
char *p;
p = malloc (k5->gt;peerptr->gt;length + 1);
if (!p)
{
if (minor_status)
*minor_status = ENOMEM;
return GSS_S_FAILURE;
}
memcpy (p, k5->gt;peerptr->gt;value, k5->gt;peerptr->gt;length);
p[k5->gt;peerptr->gt;length] = 0;
k5->gt;key = shishi_hostkeys_for_serverrealm (k5->gt;sh, p, NULL);
free (p);
}
if (!k5->gt;key)
{
if (minor_status)
*minor_status = GSS_KRB5_S_KG_KEYTAB_NOMATCH;
return GSS_S_NO_CRED;
}
if (time_rec)
*time_rec = GSS_C_INDEFINITE;
return GSS_S_COMPLETE;
}
|
↓
|
_gss_krb5_checksum_parse
|
11
|
39
|
72
|
krb5/checksum.c
|
OM_uint32
_gss_krb5_checksum_parse (OM_uint32 * minor_status,
gss_ctx_id_t * context_handle,
const gss_channel_bindings_t input_chan_bindings)
{
gss_ctx_id_t ctx = *context_handle;
_gss_krb5_ctx_t k5 = ctx->gt;krb5;
char *out = NULL;
size_t len = 0;
int rc;
char *md5hash;
if (shishi_ap_authenticator_cksumtype (k5->gt;ap) != 0x8003)
{
if (minor_status)
*minor_status = GSS_KRB5_S_G_VALIDATE_FAILED;
return GSS_S_FAILURE;
}
rc = shishi_ap_authenticator_cksumdata (k5->gt;ap, out, &len);
if (rc != SHISHI_TOO_SMALL_BUFFER)
return GSS_S_FAILURE;
out = malloc (len);
if (!out)
{
if (minor_status)
*minor_status = ENOMEM;
return GSS_S_FAILURE;
}
rc = shishi_ap_authenticator_cksumdata (k5->gt;ap, out, &len);
if (rc != SHISHI_OK)
{
free (out);
return GSS_S_FAILURE;
}
if (memcmp (out, "\x10\x00\x00\x00", 4) != 0)
{
free (out);
return GSS_S_DEFECTIVE_TOKEN;
}
if (input_chan_bindings != GSS_C_NO_CHANNEL_BINDINGS)
{
rc = hash_cb (minor_status, context_handle,
input_chan_bindings, &md5hash);
if (rc != GSS_S_COMPLETE)
{
free (out);
return GSS_S_DEFECTIVE_TOKEN;
}
rc = memcmp (&out[4], md5hash, 16);
free (md5hash);
}
else
{
char zeros[16];
memset (&zeros[0], 0, sizeof zeros);
rc = memcmp (&out[4], zeros, 16);
}
free (out);
if (rc != 0)
return GSS_S_DEFECTIVE_TOKEN;
return GSS_S_COMPLETE;
}
|
↓
|
_gss_decapsulate_token
|
11
|
35
|
53
|
asn1.c
|
int
_gss_decapsulate_token (const char *in, size_t inlen,
char **oid, size_t * oidlen,
char **out, size_t * outlen)
{
size_t i;
size_t asn1lenlen;
if (inlen-- == 0)
return -1;
if (*in++ != '\x60')
return -1;
i = inlen;
asn1lenlen = _gss_asn1_get_length_der (in, inlen, &i);
if (inlen
|
↓
|
gss_inquire_saslname_for_mech
|
11
|
24
|
47
|
saslname.c
|
OM_uint32
gss_inquire_saslname_for_mech (OM_uint32 * minor_status,
const gss_OID desired_mech,
gss_buffer_t sasl_mech_name,
gss_buffer_t mech_name,
gss_buffer_t mech_description)
{
_gss_mech_api_t m;
if (!desired_mech)
{
if (minor_status)
*minor_status = 0;
return GSS_S_CALL_INACCESSIBLE_READ;
}
m = _gss_find_mech_no_default (desired_mech);
if (!m)
{
if (minor_status)
*minor_status = 0;
return GSS_S_BAD_MECH;
}
bindtextdomain (PACKAGE PO_SUFFIX, LOCALEDIR);
if (dup_data (minor_status, sasl_mech_name,
m->gt;sasl_name, 0) != GSS_S_COMPLETE)
return GSS_S_FAILURE;
if (dup_data (minor_status, mech_name, m->gt;mech_name, 0) != GSS_S_COMPLETE)
{
if (sasl_mech_name)
free (sasl_mech_name->gt;value);
return GSS_S_FAILURE;
}
if (dup_data (minor_status, mech_description,
m->gt;mech_description, 1) != GSS_S_COMPLETE)
{
if (sasl_mech_name)
free (sasl_mech_name->gt;value);
if (mech_name)
free (mech_name->gt;value);
return GSS_S_FAILURE;
}
return GSS_S_COMPLETE;
}
|
|
init_request
|
10
|
38
|
81
|
krb5/context.c
|
|
hash_cb
|
10
|
36
|
61
|
krb5/checksum.c
|
|
gss_acquire_cred
|
10
|
27
|
63
|
cred.c
|
|
gss_duplicate_name
|
10
|
26
|
42
|
name.c
|
|
inquire_cred
|
10
|
21
|
40
|
krb5/cred.c
|
|
gss_accept_sec_context
|
9
|
26
|
67
|
context.c
|
|
gss_krb5_acquire_cred
|
9
|
25
|
53
|
krb5/cred.c
|
|
gss_krb5_display_status
|
9
|
24
|
68
|
krb5/error.c
|
|
gss_delete_sec_context
|
8
|
22
|
43
|
context.c
|
|
gss_import_name
|
8
|
21
|
37
|
name.c
|
|
gss_release_cred
|
8
|
21
|
36
|
cred.c
|
|
gss_inquire_cred_by_mech
|
8
|
20
|
51
|
cred.c
|
|
gss_display_name
|
8
|
17
|
30
|
name.c
|
|
gss_compare_name
|
7
|
9
|
20
|
name.c
|
|
_gss_find_mech_by_saslname
|
7
|
9
|
17
|
meta.c
|
|
init_reply
|
7
|
24
|
58
|
krb5/context.c
|
|
gss_decapsulate_token
|
7
|
21
|
36
|
asn1.c
|
|
_gss_asn1_get_length_der
|
7
|
20
|
43
|
asn1.c
|
|
_gss_copy_oid
|
7
|
14
|
25
|
misc.c
|
|
_gss_krb5_checksum_pack
|
6
|
25
|
124
|
krb5/checksum.c
|
|
_gss_inquire_mechs_for_name3
|
6
|
17
|
30
|
name.c
|
|
gss_export_name
|
6
|
16
|
33
|
name.c
|
|
gss_inquire_cred
|
6
|
16
|
36
|
cred.c
|
|
gss_inquire_mechs_for_name
|
6
|
15
|
30
|
name.c
|
|
_gss_asn1_length_der
|
6
|
15
|
32
|
asn1.c
|
|
gss_test_oid_set_member
|
6
|
14
|
28
|
misc.c
|
|
gss_inquire_mech_for_saslname
|
6
|
13
|
27
|
saslname.c
|
|
gss_inquire_names_for_mech
|
5
|
17
|
29
|
name.c
|
|
gss_release_oid_set
|
5
|
14
|
20
|
misc.c
|
|
gss_context_time
|
5
|
11
|
23
|
context.c
|
|
gss_get_mic
|
5
|
11
|
26
|
msg.c
|
|
gss_krb5_delete_sec_context
|
5
|
11
|
21
|
krb5/context.c
|
|
gss_unwrap
|
5
|
11
|
27
|
msg.c
|
|
dup_data
|
5
|
11
|
21
|
saslname.c
|
|
gss_wrap
|
5
|
11
|
28
|
msg.c
|
|
gss_encapsulate_token
|
5
|
11
|
26
|
asn1.c
|
|
gss_verify_mic
|
5
|
11
|
26
|
msg.c
|
|
gss_krb5_context_time
|
5
|
10
|
23
|
krb5/context.c
|
|
gss_release_name
|
5
|
10
|
20
|
name.c
|
|
_gss_encapsulate_token_prefix
|
4
|
25
|
39
|
asn1.c
|
|
gss_krb5_export_name
|
4
|
20
|
32
|
krb5/name.c
|
|
_gss_inquire_mechs_for_name1
|
4
|
12
|
22
|
name.c
|
|
_gss_inquire_mechs_for_name2
|
4
|
11
|
22
|
name.c
|
|
gss_indicate_mechs
|
4
|
11
|
20
|
misc.c
|
|
_gss_indicate_mechs1
|
4
|
11
|
18
|
meta.c
|
|
gss_create_empty_oid_set
|
4
|
10
|
18
|
misc.c
|
|
gss_oid_equal
|
4
|
1
|
8
|
oid.c
|
|
gss_krb5_release_cred
|
3
|
9
|
16
|
krb5/cred.c
|
|
gss_krb5_tktlifetime
|
3
|
8
|
16
|
krb5/utils.c
|
|
_gss_find_mech_no_default
|
3
|
7
|
11
|
meta.c
|
|
gss_canonicalize_name
|
3
|
7
|
18
|
name.c
|
|
gss_release_buffer
|
3
|
7
|
15
|
misc.c
|
|
_gss_find_mech
|
3
|
4
|
12
|
meta.c
|
|
gss_check_version
|
3
|
3
|
8
|
version.c
|
|
gss_krb5_inquire_cred_by_mech
|
2
|
5
|
19
|
krb5/cred.c
|
|
gss_userok
|
2
|
1
|
7
|
ext.c
|
|
pack_uint32
|
1
|
4
|
8
|
krb5/checksum.c
|
|
gss_process_context_token
|
1
|
1
|
7
|
context.c
|
|
gss_unseal
|
1
|
1
|
11
|
obsolete.c
|
|
gss_seal
|
1
|
1
|
12
|
obsolete.c
|
|
gss_krb5_verify_mic
|
1
|
1
|
8
|
krb5/msg.c
|
|
gss_verify
|
1
|
1
|
9
|
obsolete.c
|
|
gss_krb5_get_mic
|
1
|
1
|
9
|
krb5/msg.c
|
|
gss_add_cred
|
1
|
1
|
14
|
cred.c
|
|
gss_sign
|
1
|
1
|
9
|
obsolete.c
|
|
gss_krb5_inquire_cred
|
1
|
1
|
11
|
krb5/cred.c
|
|
gss_import_sec_context
|
1
|
1
|
7
|
context.c
|
|
gss_export_sec_context
|
1
|
1
|
7
|
context.c
|
|
gss_wrap_size_limit
|
1
|
1
|
9
|
context.c
|
|
gss_inquire_context
|
1
|
1
|
11
|
context.c
|