# spnego.cnf # spnego conformation file #.EXPORTS #.PDU #.NO_EMIT ONLY_VALS NegotiationToken #.FN_BODY NegotiationToken/negTokenInit gboolean is_response = actx->pinfo->ptype == PT_TCP && actx->pinfo->srcport < 1024; /* * We decode as negTokenInit2 or negTokenInit depending on whether or not * we are in a response or a request. That is essentially what MS-SPNG * says. */ if (is_response) { return dissect_spnego_NegTokenInit2(%(IMPLICIT_TAG)s, %(TVB)s, %(OFFSET)s, %(ACTX)s, %(TREE)s, %(HF_INDEX)s); } else { return dissect_spnego_NegTokenInit(%(IMPLICIT_TAG)s, %(TVB)s, %(OFFSET)s, %(ACTX)s, %(TREE)s, %(HF_INDEX)s); } #.FN_PARS MechType FN_VARIANT = _str VAL_PTR = &MechType_oid #.FN_BODY MechType gssapi_oid_value *value; %(DEFAULT_BODY)s value = gssapi_lookup_oid_str(MechType_oid); /* * Tell our caller the first mechanism we see, so that if * this is a negTokenInit with a mechToken, it can interpret * the mechToken according to the first mechType. (There * might not have been any indication of the mechType * in prior frames, so we can't necessarily use the * mechanism from the conversation; i.e., a negTokenInit * can contain the initial security token for the desired * mechanism of the initiator - that's the first mechanism * in the list.) */ if (!saw_mechanism) { if (value) next_level_value = value; saw_mechanism = TRUE; } #.FN_BODY InnerContextToken gssapi_oid_value *next_level_value_lcl; proto_item *item; proto_tree *subtree; tvbuff_t *token_tvb; int len; /* * XXX - what should we do if this OID doesn't match the value * attached to the frame or conversation? (That would be * bogus, but that's not impossible - some broken implementation * might negotiate some security mechanism but put the OID * for some other security mechanism in GSS_Wrap tokens.) * Does it matter? */ next_level_value_lcl = gssapi_lookup_oid_str(MechType_oid); /* * Now dissect the GSS_Wrap token; it's assumed to be in the * rest of the tvbuff. */ item = proto_tree_add_item(tree, hf_spnego_wraptoken, tvb, offset, -1, ENC_NA); subtree = proto_item_add_subtree(item, ett_spnego_wraptoken); /* * Now, we should be able to dispatch after creating a new TVB. * The subdissector must return the length of the part of the * token it dissected, so we can return the length of the part * we (and it) dissected. */ token_tvb = tvb_new_subset_remaining(tvb, offset); if (next_level_value_lcl && next_level_value_lcl->wrap_handle) { len = call_dissector(next_level_value_lcl->wrap_handle, token_tvb, actx->pinfo, subtree); if (len == 0) offset = tvb_length(tvb); else offset = offset + len; } else offset = tvb_length(tvb); #.FN_BODY MechTypeList conversation_t *conversation; saw_mechanism = FALSE; %(DEFAULT_BODY)s /* * If we saw a mechType we need to store it in case the negTokenTarg * does not provide a supportedMech. */ if(saw_mechanism){ conversation = find_or_create_conversation(actx->pinfo); conversation_add_proto_data(conversation, proto_spnego, next_level_value); } #.FN_PARS NegTokenInit/mechToken VAL_PTR = &mechToken_tvb #.FN_BODY NegTokenInit/mechToken tvbuff_t *mechToken_tvb = NULL; %(DEFAULT_BODY)s /* * Now, we should be able to dispatch, if we've gotten a tvbuff for * the token and we have information on how to dissect its contents. */ if (mechToken_tvb && next_level_value) call_dissector(next_level_value->handle, mechToken_tvb, actx->pinfo, tree); #.FN_BODY NegTokenTarg/supportedMech conversation_t *conversation; saw_mechanism = FALSE; %(DEFAULT_BODY)s /* * If we saw an explicit mechType we store this in the conversation so that * it will override any mechType we might have picked up from the * negTokenInit. */ if(saw_mechanism){ conversation = find_or_create_conversation(actx->pinfo); conversation_add_proto_data(conversation, proto_spnego, next_level_value); } #.FN_PARS NegTokenTarg/responseToken VAL_PTR = &responseToken_tvb #.FN_BODY NegTokenTarg/responseToken tvbuff_t *responseToken_tvb; %(DEFAULT_BODY)s /* * Now, we should be able to dispatch, if we've gotten a tvbuff for * the token and we have information on how to dissect its contents. * However, we should make sure that there is something in the * response token ... */ if (responseToken_tvb && (tvb_reported_length(responseToken_tvb) > 0) ){ gssapi_oid_value *value=next_level_value; if(value){ call_dissector(value->handle, responseToken_tvb, actx->pinfo, tree); } } #.END