Report generated at: Sat Aug 6 15:19:59 CEST 2022
Total number of functions | 82 |
Number of low risk functions | 70 |
Number of moderate risk functions | 8 |
Number of high risk functions | 4 |
Number of untestable functions | 0 |
Cyclomatic Complexity | Risk Evaluation | |
0 - 10 | Simple module, without much risk | |
11 - 20 | More complex module, moderate risk | |
21 - 50 | Complex module, high risk | |
greater than 50 | Untestable module, very high risk |
Function Name | Modified Cyclo |
Number of
Statements |
Number of
Lines |
Source File | |
↓ | gss_krb5_unwrap | 41 | 132 | 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->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 < 8) return GSS_S_BAD_MIC; if (memcmp (tok.value, TOK_WRAP, TOK_LEN) != 0) return GSS_S_BAD_MIC; data = tok.value; sgn_alg = data[2] & 0xFF; sgn_alg |= data[3] << 8 & 0xFF00; seal_alg = data[4] & 0xFF; seal_alg |= data[5] << 8 & 0xFF00; if (conf_state != NULL) *conf_state = seal_alg == 0xFFFF; if (memcmp (data + 6, "\xFF\xFF", 2) != 0) return GSS_S_BAD_MIC; switch (sgn_alg) { /* XXX implement other checksums */ case 0: /* DES-MD5 */ { size_t padlen; char *pt; char header[8]; char encseqno[8]; char seqno[8]; char cksum[8]; char confounder[8]; char *tmp; uint32_t seqnr; size_t outlen, i; /* 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 */ if (tok.length < 5 * 8) return GSS_S_BAD_MIC; memcpy (header, data, 8); memcpy (encseqno, data + 8, 8); memcpy (cksum, data + 16, 8); memcpy (confounder, data + 24, 8); pt = data + 32; /* XXX decrypt data iff confidential option chosen */ rc = shishi_decrypt_iv_etype (k5->sh, k5->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->acceptor ? "\x00\x00\x00\x00" : "\xFF\xFF\xFF\xFF", 4) != 0) return GSS_S_BAD_MIC; seqnr = C2I (seqno); if (seqnr != (k5->acceptor ? k5->initseqnr : k5->acceptseqnr)) return GSS_S_BAD_MIC; if (k5->acceptor) k5->initseqnr++; else k5->acceptseqnr++; /* Check pad */ padlen = data[tok.length - 1]; if (padlen > 8) return GSS_S_BAD_MIC; for (i = 1; i <= padlen; i++) if (data[tok.length - i] != (int) padlen) return GSS_S_BAD_MIC; /* Write header and confounder next to data */ memcpy (data + 16, header, 8); memcpy (data + 24, confounder, 8); /* Checksum header + confounder + data + pad */ rc = shishi_checksum (k5->sh, k5->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->length = tok.length - 8 - 8 - 8 - 8 - padlen; output_message_buffer->value = malloc (output_message_buffer->length); if (!output_message_buffer->value) { if (minor_status) *minor_status = ENOMEM; return GSS_S_FAILURE; } memcpy (output_message_buffer->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 < 8 + 8 + 20 + 8 + 8) return GSS_S_BAD_MIC; memcpy (cksum, data + 8 + 8, 20); /* XXX decrypt data iff confidential option chosen */ p = data + 8; rc = shishi_decrypt_iv_etype (k5->sh, k5->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->acceptor ? "\x00\x00\x00\x00" : "\xFF\xFF\xFF\xFF", 4) != 0) return GSS_S_BAD_MIC; seqnr = C2I (p); if (seqnr != (k5->acceptor ? k5->initseqnr : k5->acceptseqnr)) return GSS_S_BAD_MIC; if (k5->acceptor) k5->initseqnr++; else k5->acceptseqnr++; /* Check pad */ padlen = data[tok.length - 1]; if (padlen > 8) return GSS_S_BAD_MIC; for (i = 1; i <= padlen; i++) if (data[tok.length - i] != (int) padlen) return GSS_S_BAD_MIC; /* Write header next to confounder */ memcpy (data + 8 + 20, data, 8); /* Checksum header + confounder + data + pad */ rc = shishi_checksum (k5->sh, k5->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->length = tok.length - 8 - 20 - 8 - 8 - padlen; output_message_buffer->value = malloc (output_message_buffer->length); if (!output_message_buffer->value) { if (minor_status) *minor_status = ENOMEM; return GSS_S_FAILURE; } memcpy (output_message_buffer->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->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->mech = GSS_KRB5; cx->krb5 = cxk5; /* XXX cx->peer?? */ *context_handle = cx; cxk5->sh = crk5->sh; cxk5->key = crk5->key; cxk5->acceptor = 1; rc = shishi_ap (cxk5->sh, &cxk5->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 < TOK_LEN) { gss_release_buffer (&tmp_min_stat, &in); return GSS_S_BAD_MIC; } if (memcmp (in.value, TOK_AP_REQ, TOK_LEN) != 0) { gss_release_buffer (&tmp_min_stat, &in); return GSS_S_BAD_MIC; } rc = shishi_ap_req_der_set (cxk5->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->ap, crk5->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->sh, shishi_ap_authenticator (cxk5->ap), &cxk5->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->tkt = shishi_ap_tkt (cxk5->ap); cxk5->key = shishi_ap_key (cxk5->ap); if (shishi_apreq_mutual_required_p (crk5->sh, shishi_ap_req (cxk5->ap))) { Shishi_asn1 aprep; char *der; size_t len; rc = shishi_ap_rep_asn1 (cxk5->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->sh, shishi_ap_encapreppart (cxk5->ap), &cxk5->acceptseqnr); if (rc != SHISHI_OK) { /* A strict 1964 implementation would return GSS_S_DEFECTIVE_TOKEN here. gssapi-cfx permit absent sequence number, though. */ cxk5->acceptseqnr = 0; } rc = shishi_asn1_to_der (crk5->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->elements, GSS_KRB5->length, &output_token->value, &output_token->length); if (rc != 0) return GSS_S_FAILURE; if (ret_flags) *ret_flags = GSS_C_MUTUAL_FLAG; } else { output_token->value = NULL; output_token->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->sh, shishi_tkt_encticketpart (cxk5->tkt), &p->value, &p->length); if (rc != SHISHI_OK) return GSS_S_FAILURE; p->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 | 70 | 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 << GSS_C_ROUTINE_ERROR_OFFSET; if ((status_value & ~*message_context) == 0) *message_context = 0; } switch (GSS_ROUTINE_ERROR (status_value)) { case 0: break; case GSS_S_BAD_MECH: case GSS_S_BAD_NAME: case GSS_S_BAD_NAMETYPE: case GSS_S_BAD_BINDINGS: case GSS_S_BAD_STATUS: case GSS_S_BAD_SIG: case GSS_S_NO_CRED: case GSS_S_NO_CONTEXT: case GSS_S_DEFECTIVE_TOKEN: case GSS_S_DEFECTIVE_CREDENTIAL: case GSS_S_CREDENTIALS_EXPIRED: case GSS_S_CONTEXT_EXPIRED: case GSS_S_FAILURE: case GSS_S_BAD_QOP: case GSS_S_UNAUTHORIZED: case GSS_S_UNAVAILABLE: case GSS_S_DUPLICATE_ELEMENT: case GSS_S_NAME_NOT_MN: status_string->value = strdup (_(gss_routine_errors [(GSS_ROUTINE_ERROR (status_value) >> GSS_C_ROUTINE_ERROR_OFFSET) - 1].text)); if (!status_string->value) { if (minor_status) *minor_status = ENOMEM; return GSS_S_FAILURE; } status_string->length = strlen (status_string->value); return GSS_S_COMPLETE; break; default: return GSS_S_BAD_STATUS; break; } if (message_context) { *message_context |= GSS_C_CALLING_ERROR_MASK << GSS_C_CALLING_ERROR_OFFSET; if ((status_value & ~*message_context) == 0) *message_context = 0; } switch (GSS_CALLING_ERROR (status_value)) { case 0: break; case GSS_S_CALL_INACCESSIBLE_READ: case GSS_S_CALL_INACCESSIBLE_WRITE: case GSS_S_CALL_BAD_STRUCTURE: status_string->value = strdup (_(gss_calling_errors [(GSS_CALLING_ERROR (status_value) >> GSS_C_CALLING_ERROR_OFFSET) - 1].text)); if (!status_string->value) { if (minor_status) *minor_status = ENOMEM; return GSS_S_FAILURE; } status_string->length = strlen (status_string->value); return GSS_S_COMPLETE; break; default: return GSS_S_BAD_STATUS; break; } for (i = 0; i < sizeof (gss_supplementary_errors) / sizeof (gss_supplementary_errors[0]); i++) if (gss_supplementary_errors[i].err & GSS_SUPPLEMENTARY_INFO (status_value)) { status_string->value = strdup (_(gss_supplementary_errors[i].text)); if (!status_string->value) { if (minor_status) *minor_status = ENOMEM; return GSS_S_FAILURE; } status_string->length = strlen (status_string->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->value = strdup (_("No error")); if (!status_string->value) { if (minor_status) *minor_status = ENOMEM; return GSS_S_FAILURE; } status_string->length = strlen (status_string->value); break; case GSS_C_MECH_CODE: { _gss_mech_api_t mech; mech = _gss_find_mech (mech_type); return mech->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 | 113 | 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->krb5; size_t padlength; gss_buffer_desc data; char *p; size_t tmplen; int rc; switch (shishi_key_type (k5->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->length % 8; data.length = 4 * 8 + input_message_buffer->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->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->value, input_message_buffer->length); memset (p + 16 + input_message_buffer->length, (int) padlength, padlength); rc = shishi_checksum (k5->sh, k5->key, 0, SHISHI_RSA_MD5_DES_GSS, p, 16 + input_message_buffer->length + padlength, &cksum, &tmplen); if (rc != SHISHI_OK || tmplen != 8) return GSS_S_FAILURE; /* seq_nr */ if (k5->acceptor) { seqno[0] = k5->acceptseqnr & 0xFF; seqno[1] = k5->acceptseqnr >> 8 & 0xFF; seqno[2] = k5->acceptseqnr >> 16 & 0xFF; seqno[3] = k5->acceptseqnr >> 24 & 0xFF; memset (seqno + 4, 0xFF, 4); } else { seqno[0] = k5->initseqnr & 0xFF; seqno[1] = k5->initseqnr >> 8 & 0xFF; seqno[2] = k5->initseqnr >> 16 & 0xFF; seqno[3] = k5->initseqnr >> 24 & 0xFF; memset (seqno + 4, 0, 4); } rc = shishi_encrypt_iv_etype (k5->sh, k5->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->value, input_message_buffer->length); memset (p + 32 + input_message_buffer->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->acceptor) k5->acceptseqnr++; else k5->initseqnr++; } break; case SHISHI_DES3_CBC_HMAC_SHA1_KD: { char *tmp; padlength = 8 - input_message_buffer->length % 8; data.length = 8 + 8 + 20 + 8 + input_message_buffer->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->sh, 0, p + 8, 8); if (rc != SHISHI_OK) return GSS_S_FAILURE; memcpy (p + 16, input_message_buffer->value, input_message_buffer->length); memset (p + 16 + input_message_buffer->length, (int) padlength, padlength); rc = shishi_checksum (k5->sh, k5->key, SHISHI_KEYUSAGE_GSS_R2, SHISHI_HMAC_SHA1_DES3_KD, p, 16 + input_message_buffer->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->acceptor) { (p + 8)[0] = k5->acceptseqnr & 0xFF; (p + 8)[1] = k5->acceptseqnr >> 8 & 0xFF; (p + 8)[2] = k5->acceptseqnr >> 16 & 0xFF; (p + 8)[3] = k5->acceptseqnr >> 24 & 0xFF; memset (p + 8 + 4, 0xFF, 4); } else { (p + 8)[0] = k5->initseqnr & 0xFF; (p + 8)[1] = k5->initseqnr >> 8 & 0xFF; (p + 8)[2] = k5->initseqnr >> 16 & 0xFF; (p + 8)[3] = k5->initseqnr >> 24 & 0xFF; memset (p + 8 + 4, 0, 4); } rc = shishi_encrypt_iv_etype (k5->sh, k5->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->value, input_message_buffer->length); memset (p + 8 + 8 + 20 + 8 + input_message_buffer->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->acceptor) k5->acceptseqnr++; else k5->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->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->krb5 = calloc (sizeof (*k5), 1); if (!k5) { if (minor_status) *minor_status = ENOMEM; return GSS_S_FAILURE; } rc = shishi_init (&k5->sh); if (rc != SHISHI_OK) return GSS_S_FAILURE; } if (!k5->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->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->flags |= GSS_C_PROT_READY_FLAG; if (ret_flags) *ret_flags = k5->flags; k5->key = shishi_ap_key (k5->ap); k5->reqdone = 1; } else if (k5->reqdone && k5->flags & GSS_C_MUTUAL_FLAG && !k5->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->flags; k5->repdone = 1; } else maj_stat = GSS_S_FAILURE; if (time_rec) *time_rec = gss_krb5_tktlifetime (k5->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->length = 0; output_token->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)->mech); if (mech == NULL) { if (minor_status) *minor_status = 0; return GSS_S_BAD_MECH; } if (actual_mech_type) *actual_mech_type = mech->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)->mech = mech->mech; freecontext = 1; } maj_stat = mech->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->type, GSS_C_NT_EXPORT_NAME)) { if (input_name->length > 15) { *output_name = malloc (sizeof (**output_name)); if (!*output_name) { if (minor_status) *minor_status = ENOMEM; return GSS_S_FAILURE; } (*output_name)->type = GSS_KRB5_NT_PRINCIPAL_NAME; (*output_name)->length = input_name->length - 15; (*output_name)->value = malloc ((*output_name)->length + 1); if (!(*output_name)->value) { free (*output_name); if (minor_status) *minor_status = ENOMEM; return GSS_S_FAILURE; } memcpy ((*output_name)->value, input_name->value + 15, (*output_name)->length); (*output_name)->value[(*output_name)->length] = '\0'; } else { return GSS_S_BAD_NAME; } } else if (gss_oid_equal (input_name->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->value, '@', input_name->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)->type = GSS_KRB5_NT_PRINCIPAL_NAME; p = memchr ((*output_name)->value, '@', (*output_name)->length); if (p) *p = '/'; } else if (gss_oid_equal (input_name->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->length == 0 || member_oid->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)->count + 1 == 0) /* integer overflow */ { if (minor_status) *minor_status = 0; return GSS_S_FAILURE; } (*oid_set)->count++; { gss_OID tmp; tmp = realloc ((*oid_set)->elements, (*oid_set)->count * sizeof (*(*oid_set)->elements)); if (!tmp) { if (minor_status) *minor_status = ENOMEM; return GSS_S_FAILURE; } (*oid_set)->elements = tmp; } major_stat = _gss_copy_oid (minor_status, member_oid, (*oid_set)->elements + ((*oid_set)->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)->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->peerptr); if (GSS_ERROR (maj_stat)) return maj_stat; if (k5->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->sh) != SHISHI_OK) return GSS_S_FAILURE; { char *p; p = malloc (k5->peerptr->length + 1); if (!p) { if (minor_status) *minor_status = ENOMEM; return GSS_S_FAILURE; } memcpy (p, k5->peerptr->value, k5->peerptr->length); p[k5->peerptr->length] = 0; k5->key = shishi_hostkeys_for_serverrealm (k5->sh, p, NULL); free (p); } if (!k5->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->krb5; char *out = NULL; size_t len = 0; int rc; char *md5hash; if (shishi_ap_authenticator_cksumtype (k5->ap) != 0x8003) { if (minor_status) *minor_status = GSS_KRB5_S_G_VALIDATE_FAILED; return GSS_S_FAILURE; } rc = shishi_ap_authenticator_cksumdata (k5->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->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 < i) return -1; inlen -= i; in += i; if (inlen != asn1lenlen) return -1; if (inlen-- == 0) return -1; if (*in++ != '\x06') return -1; i = inlen; asn1lenlen = _gss_asn1_get_length_der (in, inlen, &i); if (inlen < i) return -1; inlen -= i; in += i; if (inlen < asn1lenlen) return -1; *oidlen = asn1lenlen; *oid = (char *) in; inlen -= asn1lenlen; in += asn1lenlen; if (outlen) *outlen = inlen; if (out) *out = (char *) in; return 0; } |
|||||
↓ | 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->sasl_name, 0) != GSS_S_COMPLETE) return GSS_S_FAILURE; if (dup_data (minor_status, mech_name, m->mech_name, 0) != GSS_S_COMPLETE) { if (sasl_mech_name) free (sasl_mech_name->value); return GSS_S_FAILURE; } if (dup_data (minor_status, mech_description, m->mech_description, 1) != GSS_S_COMPLETE) { if (sasl_mech_name) free (sasl_mech_name->value); if (mech_name) free (mech_name->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 | 25 | 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_inquire_cred | 8 | 20 | 43 | 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 | 35 | 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_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 | |
dup_data | 5 | 11 | 21 | saslname.c | |
gss_unwrap | 5 | 11 | 27 | msg.c | |
gss_wrap | 5 | 11 | 28 | msg.c | |
gss_encapsulate_token | 5 | 11 | 25 | 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_sign | 1 | 1 | 9 | obsolete.c | |
gss_add_cred | 1 | 1 | 14 | cred.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 |