コード例 #1
0
ファイル: rblcheck.c プロジェクト: asyr625/mini_sip
static void a4cb(struct dns_ctx *ctx, struct dns_rr_a4 *r, void *data) {
  struct rblookup *ipl = data;
  if (r) {
    ipl->addr = r;
    ++listed;
    if (do_txt) {
      if (dns_submit_a4dnsbl_txt(0, &ipl->key, ipl->zone, txtcb, ipl))
        return;
      dnserror(ipl, "submit DNSBL TXT record");
    }
    ++ipl->parent->listed;
  }
  else if (dns_status(ctx) != DNS_E_NXDOMAIN)
    dnserror(ipl, "lookup DNSBL A record");
  else
    ipl->addr = notlisted;
}
コード例 #2
0
ファイル: rblcheck.c プロジェクト: asyr625/mini_sip
static void txtcb(struct dns_ctx *ctx, struct dns_rr_txt *r, void *data) {
  struct rblookup *ipl = data;
  if (r) {
    ipl->txt = r;
    ++ipl->parent->listed;
  }
  else if (dns_status(ctx) != DNS_E_NXDOMAIN)
    dnserror(ipl, "lookup DNSBL TXT record");
}
コード例 #3
0
ファイル: socket.c プロジェクト: kvirund/mmc
static void sockerrmsg(const char *m,int dns) {
    char	buf[2048];
    const char	*se;
    size_t	i;

    i=strlen(m);
    if (i>sizeof(buf)-3)
      return;
    strncpy(buf,m,i);
    buf[i]='\0';
    strcat(buf,": ");
    if ((se=dns ? dnserror() : sockerror()))
	if (strlen(se)+i<sizeof(buf))
	  strcat(buf,se);
    clwarnx(buf);
}
コード例 #4
0
ファイル: axfr.c プロジェクト: corretgecom/mydns-ng
/**************************************************************************************************
	CHECK_XFER
	If the "xfer" column exists in the soa table, it should contain a list of wildcards separated
	by commas.  In order for this zone transfer to continue, one of the wildcards must match
	the client's IP address.
**************************************************************************************************/
static void
check_xfer(TASK *t, MYDNS_SOA *soa) {
  SQL_RES	*res = NULL;
  SQL_ROW	row = NULL;
  char		ip[256];
  char		*query = NULL;
  size_t	querylen = 0;
  int		ok = 0;

  memset(&ip, 0, sizeof(ip));

  if (!mydns_soa_use_xfer)
    return;

  strncpy(ip, clientaddr(t), sizeof(ip)-1);

  querylen = sql_build_query(&query, "SELECT xfer FROM %s WHERE id=%u%s%s%s;",
			     mydns_soa_table_name, soa->id,
			     (mydns_rr_use_active)? " AND active='" : "",
			     (mydns_rr_use_active)? mydns_rr_active_types[0] : "",
			     (mydns_rr_use_active)? "'" : "");

  res = sql_query(sql, query, querylen);
  RELEASE(query);
  if (!res) {
    ErrSQL(sql, "%s: %s", desctask(t), _("error loading zone transfer access rules"));
  }

  if ((row = sql_getrow(res, NULL))) {
    char *wild = NULL, *r = NULL;

    for (r = row[0]; !ok && (wild = strsep(&r, ",")); )	{
      if (strchr(wild, '/')) {
	if (t->family == AF_INET)
	  ok = in_cidr(wild, t->addr4.sin_addr);
      }	else if (wildcard_match(wild, ip))
	ok = 1;
    }
  }
  sql_free(res);

  if (!ok) {
    dnserror(t, DNS_RCODE_REFUSED, ERR_NO_AXFR);
    axfr_reply(t);
    axfr_error(t, _("access denied"));
  }
}
コード例 #5
0
ファイル: axfr.c プロジェクト: corretgecom/mydns-ng
/**************************************************************************************************
	AXFR_GET_SOA
	Attempt to find a SOA record.  If SOA id is 0, we made it up.
**************************************************************************************************/
static MYDNS_SOA *
axfr_get_soa(TASK *t) {
  MYDNS_SOA *soa = NULL;

  /* Try to load SOA */
  if (mydns_soa_load(sql, &soa, t->qname) < 0)
    ErrSQL(sql, "%s: %s", desctask(t), _("error loading zone"));
  if (soa) {
    return (soa);
	}

  /* STILL no SOA?  We aren't authoritative */
  dnserror(t, DNS_RCODE_REFUSED, ERR_ZONE_NOT_FOUND);
  axfr_reply(t);
  axfr_error(t, _("unknown zone"));
  /* NOTREACHED */
  return (NULL);
}
コード例 #6
0
ファイル: rblcheck.c プロジェクト: asyr625/mini_sip
static int
submit_a_queries(struct ipcheck *ipc,
                 int naddr, const struct in_addr *addr) {
  int z, a;
  struct rblookup *rl = ecalloc(sizeof(*rl), nzones * naddr);
  ipc->lookup = rl;
  ipc->naddr = naddr;
  for(a = 0; a < naddr; ++a) {
    for(z = 0; z < nzones; ++z) {
      rl->key = addr[a];
      rl->zone = zones[z];
      rl->parent = ipc;
      if (!dns_submit_a4dnsbl(0, &rl->key, rl->zone, a4cb, rl))
        dnserror(rl, "submit DNSBL A query");
      ++rl;
    }
  }
  return 0;
}
コード例 #7
0
ファイル: ixfr.c プロジェクト: corretgecom/mydns-ng
taskexec_t
ixfr(TASK * t, datasection_t section, dns_qtype_t qtype, char *fqdn, int truncateonly) {
  MYDNS_SOA	*soa = NULL;
  uchar		*query = (uchar*)t->query;
  int		querylen = t->len;
  uchar		*src = query + DNS_HEADERSIZE;
  IQ		*q = NULL;
  task_error_t	errcode = 0;

#if DEBUG_ENABLED && DEBUG_IXFR
  DebugX("ixfr", 1, "%s: ixfr(%s, %s, \"%s\", %d)", desctask(t),
	 resolve_datasection_str[section], mydns_qtype_str(qtype), fqdn, truncateonly);
#endif

  if (!dns_ixfr_enabled) {
    dnserror(t, DNS_RCODE_REFUSED, ERR_IXFR_NOT_ENABLED);
    return (TASK_FAILED);
  }

  /*
   * Authority section contains the SOA record for the client's version of the zone
   * only trust the serial number.
   */

  if (mydns_soa_load(sql, &soa, fqdn) < 0) {
    dnserror(t, DNS_RCODE_SERVFAIL, ERR_DB_ERROR);
    return (TASK_FAILED);
  }

  if (!soa) {
    dnserror(t, DNS_RCODE_REFUSED, ERR_ZONE_NOT_FOUND);
    return (TASK_FAILED);
  }

#if DEBUG_ENABLED && DEBUG_IXFR
  DebugX("ixfr", 1, _("%s: DNS IXFR: SOA id %u"), desctask(t), soa->id);
  DebugX("ixfr", 1, _("%s: DNS IXFR: QDCOUNT=%d (Query)"), desctask(t), t->qdcount);
  DebugX("ixfr", 1, _("%s: DNS IXFR: ANCOUNT=%d (Answer)"), desctask(t), t->ancount);
  DebugX("ixfr", 1, _("%s: DNS IXFR: AUCOUNT=%d (Authority)"), desctask(t), t->nscount);
  DebugX("ixfr", 1, _("%s: DNS IXFR: ADCOUNT=%d (Additional data)"), desctask(t), t->arcount);
#endif
  if (!t->nscount)
    return formerr(t, DNS_RCODE_FORMERR, ERR_NO_AUTHORITY,
		   _("ixfr query contains no authority data"));

  if (t->nscount != 1)
    return formerr(t, DNS_RCODE_FORMERR, ERR_MULTI_AUTHORITY,
		   _("ixfr query contains multiple authority records"));

  if (!t->qdcount)
    return formerr(t, DNS_RCODE_FORMERR, ERR_NO_QUESTION,
		   _("ixfr query does not contain question"));

  if (t->qdcount != 1)
    return formerr(t, DNS_RCODE_FORMERR, ERR_MULTI_QUESTIONS,
		   _("ixfr query contains multiple questions"));

  if (t->ancount || t->arcount)
    return formerr(t, DNS_RCODE_FORMERR, ERR_MALFORMED_REQUEST,
		   _("ixfr query has answer or additional data"));

  q = allocate_iq();

  if (!(IQ_NAME(q) = name_unencode2(query, querylen, &src, &errcode))) {
    free_iq(q);
    return formerr(t, DNS_RCODE_FORMERR, errcode, NULL);
  }

  DNS_GET16(q->type, src);
  DNS_GET16(q->class, src);

  if (!(src = ixfr_gobble_authority_rr(t, query, querylen, src, &q->IR))) {
    free_iq(q);
    return (TASK_FAILED);
  }

  /* Get the serial number from the RR record in the authority section */
#if DEBUG_ENABLED && DEBUG_IXFR
  DebugX("ixfr", 1, _("%s: DNS IXFR Question[zone %s qclass %s qtype %s]"
		      " Authority[zone %s qclass %s qtype %s ttl %u "
		      "mname %s rname %s serial %u refresh %u retry %u expire %u minimum %u]"),
	 desctask(t), q->name, mydns_class_str(q->class), mydns_qtype_str(q->type),
	 q->IR.name, mydns_class_str(q->IR.class), mydns_qtype_str(q->IR.type), q->IR.ttl,
	 q->IR.mname, q->IR.rname, q->IR.serial, q->IR.refresh, q->IR.retry, q->IR.expire, q->IR.minimum);
#endif

  /*
   * As per RFC 1995 we have 3 options for a response if a delta exists.
   *
   * We can send a full zone transfer if it will fit in a UDP packet and is smaller
   * than sending deltas
   *
   * We can send a delta transfer if it will fit into a single UDP packet and we can calculate
   * one for the difference between the client and the current serial
   *
   * We can send a packet with a single SOA record for the latest SOA. This will force the client
   * to initiate an AXFR.
   *
   * We can calculate the size of the response by either building both messages
   * or by an estimation technique. In either case we need to look at the data.
   *
   * I have chosen to check for altered records within the database first.
   *
   * First check is to make sure that the serial held by the client is not the current one
   *
   * Next check to see if out incremental data for the transition from client serial
   * to current serial has not expired.
   *
   * Then retrieve the updated records between the client serial and the latest serial.
   * and retrieve the entire zone ... a record count is the first check.
   *
   * If the number of delta records is larger than the number of zone records then send the zone
   *
   * Calculate the size of the variable parts of the record and compare.
   * We assume that name encoding will have an equal effect on the data.
   * So having chosen to send either the zone or the deltas construct the packet.
   *
   * Check that the packet has not overflowed the UDP limit and send. If it has
   * that abandon the packet and send one containing just the latest SOA.
   *
   */

  if (soa->serial == q->IR.serial) {
    /* Tell the client to do no zone transfer */
    rrlist_add(t, ANSWER, DNS_RRTYPE_SOA, (void *)soa, soa->origin);
    t->sort_level++;
  } else {
    /* Do we have incremental information in the database */
    if (!truncateonly && mydns_rr_use_active && mydns_rr_use_stamp && mydns_rr_use_serial) {
      /* We can do incrementals */
      /* Need to send an IXFR if available */
      /*
       * Work out when the client SOA came into being
       */
      MYDNS_RR	*ThisRR = NULL, *rr = NULL;
      char	*deltafilter = NULL;
      int	deletecount, activecount, zonesize;
      size_t	deltasize, fullsize;
       
      /* For very large zones we do not want to load all of the records just to give up */
      sql_build_query(&deltafilter, "serial > %u", q->IR.serial);

      /*
       * Compare counts of changes from full zone data
       * ... assumes records are about the same size
       * approximate zone size by 2 * deleted count === actual number of delta records
       */
      deletecount = mydns_rr_count_deleted_filtered(sql,
							soa->id, DNS_QTYPE_ANY, NULL,
							soa->origin, deltafilter);
      activecount = mydns_rr_count_active_filtered(sql,
						       soa->id, DNS_QTYPE_ANY, NULL,
						       soa->origin, deltafilter);
      zonesize = mydns_rr_count_active(sql,
					   soa->id, DNS_QTYPE_ANY, NULL,
					   soa->origin);
      deltasize = deletecount + activecount + 4;
      fullsize = zonesize + 2;

      if ((deletecount < 0) || (activecount < 0) || (zonesize < 0)) {
	RELEASE(deltafilter);
	dnserror(t, DNS_RCODE_SERVFAIL, ERR_DB_ERROR);
	return (TASK_FAILED);
      }
      if (deletecount || activecount) {
	if (deltasize >= fullsize) {
	  /* Send a full zone transfer */
	  /* Current Serial first */
	  rrlist_add(t, ANSWER, DNS_RRTYPE_SOA, (void *)soa, soa->origin);
	  t->sort_level++;
	  if (mydns_rr_load_active(sql, &ThisRR, soa->id, DNS_QTYPE_ANY, NULL, soa->origin) == 0) {
	    for (rr = ThisRR; rr; rr = rr->next) {
	      char *name = mydns_rr_append_origin(MYDNS_RR_NAME(rr), soa->origin);
	      rrlist_add(t, ANSWER, DNS_RRTYPE_RR, (void *)rr, name);
	      if (name != MYDNS_RR_NAME(rr)) RELEASE(name);
	    }
	    t->sort_level++;
	    mydns_rr_free(ThisRR);
	    rrlist_add(t, ANSWER, DNS_RRTYPE_SOA, (void *)soa, soa->origin);
	    t->sort_level++;
	  }
	} else {
	  int latest_serial = soa->serial;

	  rrlist_add(t, ANSWER, DNS_RRTYPE_SOA, (void *)soa, soa->origin);
	  t->sort_level++;
	  soa->serial = q->IR.serial;
	  rrlist_add(t, ANSWER, DNS_RRTYPE_SOA, (void *)soa, soa->origin);
	  t->sort_level++;
	  soa->serial = latest_serial;
	  if (mydns_rr_load_deleted_filtered(sql, &ThisRR, soa->id, DNS_QTYPE_ANY, NULL, soa->origin,
					     deltafilter) == 0) {
	    for (rr = ThisRR; rr; rr = rr->next) {
	      char *name = mydns_rr_append_origin(MYDNS_RR_NAME(rr), soa->origin);
	      rrlist_add(t, ANSWER, DNS_RRTYPE_RR, (void *)rr, name);
	      if (name != MYDNS_RR_NAME(rr)) RELEASE(name);
	    }
	    t->sort_level++;
	    mydns_rr_free(ThisRR);
	  }
	  rrlist_add(t, ANSWER, DNS_RRTYPE_SOA, (void *)soa, soa->origin);
	  t->sort_level++;
	  if (mydns_rr_load_active_filtered(sql, &ThisRR, soa->id, DNS_QTYPE_ANY, NULL, soa->origin,
					    deltafilter) == 0) {
	    for (rr = ThisRR; rr; rr = rr->next) {
	      char *name = mydns_rr_append_origin(MYDNS_RR_NAME(rr), soa->origin);
	      rrlist_add(t, ANSWER, DNS_RRTYPE_RR, (void *)rr, name);
	      if (name != MYDNS_RR_NAME(rr)) RELEASE(name);
	    }
	    t->sort_level++;
	    mydns_rr_free(ThisRR);
	    rrlist_add(t, ANSWER, DNS_RRTYPE_SOA, (void *)soa, soa->origin);
	    t->sort_level++;
	  }
	  RELEASE(deltafilter);
	}
	goto FINISHEDIXFR;
      }
    }
  }

  /* Tell the client to do a full zone transfer or not at all */
  rrlist_add(t, ANSWER, DNS_RRTYPE_SOA, (void *)soa, soa->origin);
  t->sort_level++;

 FINISHEDIXFR:
  mydns_soa_free(soa);

  free_iq(q);

  t->hdr.aa = 1;

  return (TASK_EXECUTED);
}