Logo Search packages:      
Sourcecode: unbound version File versions  Download package

static int processInit ( struct module_qstate qstate,
struct val_qstate vq,
struct val_env ve,
int  id 
) [static]

Process init state for validator. Process the INIT state. First tier responses start in the INIT state. This is where they are vetted for validation suitability, and the initial key search is done.

Currently, events the come through this routine will be either promoted to FINISHED/CNAME_RESP (no validation needed), FINDKEY (next step to validation), or will be (temporarily) retired and a new priming request event will be generated.

Parameters:
qstate,: query state.
vq,: validator query state.
ve,: validator shared global environment.
id,: module id.
Returns:
true if the event should be processed further on return, false if not.

Definition at line 1087 of file validator.c.

References module_env::anchors, anchors_lookup(), val_qstate::chase_reply, dname_remove_label(), dname_strict_subdomain_c(), val_qstate::ds_rrset, val_qstate::empty_DS_name, module_qstate::env, packed_rrset_key::flags, val_env::kcache, key_cache_obtain(), val_qstate::key_entry, key_entry_isnull(), log_dns_msg(), log_nametypeclass(), key_entry_key::name, trust_anchor::name, module_env::now, val_qstate::orig_msg, PACKED_RRSET_NSEC_AT_APEX, trust_anchor::parent, prime_trust_anchor(), val_qstate::qchase, query_info::qclass, module_qstate::qinfo, query_info::qname, query_info::qname_len, query_info::qtype, module_qstate::query_flags, module_qstate::region, dns_msg::rep, ub_packed_rrset_key::rk, module_env::rrset_cache, reply_info::rrset_count, val_qstate::rrset_skip, reply_info::rrsets, sec_status_indeterminate, sec_status_insecure, reply_info::security, val_qstate::signer_len, val_qstate::signer_name, val_qstate::state, val_qstate::trust_anchor, VAL_CLASS_CNAME, VAL_CLASS_NAMEERROR, VAL_CLASS_REFERRAL, val_classification_to_string(), val_classify_response(), val_error(), val_fill_reply(), val_find_signer(), VAL_FINDKEY_STATE, VAL_FINISHED_STATE, val_mark_indeterminate(), val_mark_insecure(), VERB_ALGO, VERB_DETAIL, VERB_QUERY, verbose(), and verbosity.

Referenced by val_handle().

{
      uint8_t* lookup_name;
      size_t lookup_len;
      enum val_classification subtype = val_classify_response(
            qstate->query_flags, &qstate->qinfo, &vq->qchase, 
            vq->orig_msg->rep, vq->rrset_skip);
      verbose(VERB_ALGO, "validator classification %s", 
            val_classification_to_string(subtype));
      if(subtype == VAL_CLASS_REFERRAL && 
            vq->rrset_skip < vq->orig_msg->rep->rrset_count) {
            /* referral uses the rrset name as qchase, to find keys for
             * that rrset */
            vq->qchase.qname = vq->orig_msg->rep->
                  rrsets[vq->rrset_skip]->rk.dname;
            vq->qchase.qname_len = vq->orig_msg->rep->
                  rrsets[vq->rrset_skip]->rk.dname_len;
            vq->qchase.qtype = ntohs(vq->orig_msg->rep->
                  rrsets[vq->rrset_skip]->rk.type);
            vq->qchase.qclass = ntohs(vq->orig_msg->rep->
                  rrsets[vq->rrset_skip]->rk.rrset_class);
            /* for type DS look at the parent side for keys/trustanchor */
            /* also for NSEC not at apex */
            if(vq->qchase.qtype == LDNS_RR_TYPE_DS ||
                  (vq->qchase.qtype == LDNS_RR_TYPE_NSEC && 
                   !(vq->orig_msg->rep->rrsets[vq->rrset_skip]->
                   rk.flags&PACKED_RRSET_NSEC_AT_APEX))) {
                  dname_remove_label(&vq->qchase.qname, 
                        &vq->qchase.qname_len);
            }
      }

      val_mark_indeterminate(vq->chase_reply, qstate->env->anchors, 
            qstate->env->rrset_cache, qstate->env);
      vq->key_entry = NULL;
      vq->empty_DS_name = NULL;
      vq->ds_rrset = 0;
      vq->trust_anchor = anchors_lookup(qstate->env->anchors, 
            vq->qchase.qname, vq->qchase.qname_len, vq->qchase.qclass);
      if(vq->trust_anchor == NULL) {
            /*response isn't under a trust anchor, so we cannot validate.*/
            vq->chase_reply->security = sec_status_indeterminate;
            /* go to finished state to cache this result */
            vq->state = VAL_FINISHED_STATE;
            return 1;
      }

      /* Determine the signer/lookup name */
      val_find_signer(subtype, &vq->qchase, vq->orig_msg->rep, 
            vq->rrset_skip, &vq->signer_name, &vq->signer_len);
      if(vq->signer_name == NULL) {
            lookup_name = vq->qchase.qname;
            lookup_len = vq->qchase.qname_len;
            log_nametypeclass(VERB_ALGO, "no signer, using", lookup_name,
                  0, 0);
      } else {
            lookup_name = vq->signer_name;
            lookup_len = vq->signer_len;
            log_nametypeclass(VERB_ALGO, "signer is", lookup_name, 0, 0);
      }

      /* for NXDOMAIN it could be signed by a parent of the trust anchor */
      if(subtype == VAL_CLASS_NAMEERROR && vq->signer_name &&
            dname_strict_subdomain_c(vq->trust_anchor->name, lookup_name)){
            while(vq->trust_anchor && dname_strict_subdomain_c(
                  vq->trust_anchor->name, lookup_name)) {
                  vq->trust_anchor = vq->trust_anchor->parent;
            }
            if(!vq->trust_anchor) { /* unsigned parent denies anchor*/
                  verbose(VERB_QUERY, "unsigned parent zone denies"
                        " trust anchor, indeterminate");
                  vq->chase_reply->security = sec_status_indeterminate;
                  vq->state = VAL_FINISHED_STATE;
                  return 1;
            }
            verbose(VERB_ALGO, "trust anchor NXDOMAIN by signed parent");
      }

      if(vq->rrset_skip > 0 || subtype == VAL_CLASS_CNAME ||
            subtype == VAL_CLASS_REFERRAL) {
            /* extract this part of orig_msg into chase_reply for
             * the eventual VALIDATE stage */
            val_fill_reply(vq->chase_reply, vq->orig_msg->rep, 
                  vq->rrset_skip, lookup_name, lookup_len, 
                  vq->signer_name);
            if(verbosity >= VERB_ALGO)
                  log_dns_msg("chased extract", &vq->qchase, 
                        vq->chase_reply);
      }

      vq->key_entry = key_cache_obtain(ve->kcache, lookup_name, lookup_len,
            vq->qchase.qclass, qstate->region, *qstate->env->now);
      
      /* if not key, or if keyentry is *above* the trustanchor, i.e.
       * the keyentry is based on another (higher) trustanchor */
      if(vq->key_entry == NULL || dname_strict_subdomain_c(
            vq->trust_anchor->name, vq->key_entry->name)) {
            /* fire off a trust anchor priming query. */
            verbose(VERB_DETAIL, "prime trust anchor");
            if(!prime_trust_anchor(qstate, vq, id, vq->trust_anchor))
                  return val_error(qstate, id);
            /* and otherwise, don't continue processing this event.
             * (it will be reactivated when the priming query returns). */
            vq->state = VAL_FINDKEY_STATE;
            return 0;
      } else if(key_entry_isnull(vq->key_entry)) {
            /* response is under a null key, so we cannot validate
             * However, we do set the status to INSECURE, since it is 
             * essentially proven insecure. */
            vq->chase_reply->security = sec_status_insecure;
            val_mark_insecure(vq->chase_reply, vq->key_entry, 
                  qstate->env->rrset_cache, qstate->env);
            /* go to finished state to cache this result */
            vq->state = VAL_FINISHED_STATE;
            return 1;
      }

      /* otherwise, we have our "closest" cached key -- continue 
       * processing in the next state. */
      vq->state = VAL_FINDKEY_STATE;
      return 1;
}


Generated by  Doxygen 1.6.0   Back to index