示例#1
0
/** 
 * insert a new-AAAA entry in message
 * 
 */
void DNSUpdate::addinMsg_newAAAA(){
    DnsRR rr;
    rr.NAME = domainname(_hostname, *zoneroot);
    rr.TYPE = qtype_getcode("AAAA", false);
    rr.TTL = txt_to_int(ttl);
    string data = rr_fromstring(rr.TYPE, hostip, *zoneroot);
    rr.RDLENGTH = data.size();
    rr.RDATA = (unsigned char*)memdup(data.c_str(), rr.RDLENGTH);
    
    message->authority.push_back(rr);
    Log(Debug) << "DDNS: AAAA record created:" << rr.NAME.tostring() << " -> " << hostip << LogEnd;
}
示例#2
0
/** 
 * delete a single rr from rrset. If no such RRs exist, then this Update RR will be
 * silently ignored by the primary master.
 * 
 */
void DNSUpdate::deleteAAAARecordFromRRSet(){
  DnsRR rr;
  rr.NAME = domainname(_hostname, *zoneroot);
  rr.TYPE = qtype_getcode("AAAA", false);
  rr.CLASS = QCLASS_NONE; /* 254 */
  rr.TTL = 0;
  string data = rr_fromstring(rr.TYPE, hostip, *zoneroot);
  rr.RDLENGTH = data.size();
  rr.RDATA = (unsigned char*)memdup(data.c_str(), rr.RDLENGTH);
  message->authority.push_back(rr);

  Log(Debug) << "DDNS: AAAA record created:" << rr.NAME.tostring() << " -> " << hostip << LogEnd;
}
示例#3
0
stl_string calc_mac (DnsRR &tsig_rr, message_buff msg, stl_string sign_key, message_buff *extra) {
  struct hmac_md5_ctx md5;
  unsigned char md5res [MD5_DIGEST_SIZE];
  memset (&md5, 0, sizeof (hmac_md5_ctx));
    
  unsigned char *digestpos = rr_getdata (tsig_rr.RDATA, DNS_TYPE_TSIG, 3);
  uint16_t digestlen = uint16_value (digestpos);
  
//  print_buff (sign_key.size(), (unsigned char*)sign_key.c_str());
  hmac_md5_set_key(&md5, sign_key.size(), (uint8_t *)sign_key.c_str());
  
//  printf ("Begin MAC calculation\n");
  
  /* original MAC */
  if (extra && extra->len) hmac_md5_update(&md5, extra->len, extra->msg);
  
  /* message */
  hmac_md5_update(&md5, 10, msg.msg);
  hmac_md5_update(&md5, 2, uint16_buff (uint16_value (msg.msg + 10) - 1));
  hmac_md5_update(&md5, msg.len - 12, msg.msg + 12);
  
  /* tsig rr */
  stl_string canname = tsig_rr.NAME.canonical();
  hmac_md5_update(&md5, canname.size(), (const uint8_t *)canname.c_str());
  hmac_md5_update(&md5, 2, uint16_buff (QCLASS_ANY));
  hmac_md5_update(&md5, 4, uint32_buff (0));
  
  /* start of TSIG rrdata */
  domainname dom = domainname (true, tsig_rr.RDATA);
  canname = dom.canonical();
  hmac_md5_update (&md5, canname.size(), (const uint8_t*)canname.c_str());
  hmac_md5_update(&md5, 8, digestpos - 8);
  
  /* rest, excluding original ID */
  hmac_md5_update(&md5, tsig_rr.RDLENGTH - (digestpos - tsig_rr.RDATA) - digestlen - 4,
                  digestpos + digestlen + 4);
  hmac_md5_digest(&md5, MD5_DIGEST_SIZE, md5res);
  
//  printf ("End MAC calculation\n");
  
//  print_buff (MD5_DIGEST_SIZE, md5res);
  
  stl_string ret;
  ret.append ((char*)md5res, MD5_DIGEST_SIZE);
  return ret;
}
示例#4
0
domainname guess_zone_name(const char *file) {
  const char *ptr = file + strlen(file) - 1;
  char tmp[256];
  int t;

  while (ptr >= file) {
    if (*ptr == pathdelim) { ptr++; break; }
    ptr--;
  }

  t = strlen(ptr);
  if (tolower(ptr[0]) == 'd' &&
      tolower(ptr[1]) == 'b' &&
      ptr[2] == '.') {
    return ptr + 3;
  } else if (t >= 4 && (strncmpi(ptr + t - 4, ".prm", 4) == 0 || strncmpi(ptr + t - 4, ".dns", 4) == 0)) {
    if (strlen(ptr) - 4 >= 256) throw PException("File name too long!");
    memcpy(tmp, ptr, t - 4);
    tmp[t - 4] = '\0';
    return domainname((char*)tmp);
  } else return ptr;
}
示例#5
0
void DNSUpdate::addDHCID(const char* duid, int duidlen) {
    DnsRR rr;
    rr.NAME = domainname(_hostname, *zoneroot);
    rr.TYPE = qtype_getcode("DHCID", false);
    rr.TTL = txt_to_int(ttl);
    

    char input_buf[512];
    char output_buf[35]; // identifier-type code (2) + digest type code (1) + digest (SHA-256 = 32 bytes)

    memcpy(input_buf, duid, duidlen); // 
    memcpy(input_buf+duidlen, rr.NAME.c_str(), strlen((const char*)rr.NAME.c_str()) );

    sha256_buffer(input_buf, duidlen + strlen((const char*)rr.NAME.c_str() ),
                  output_buf+3);
   
    output_buf[0] = 0;
    output_buf[1] = 2; // identifier-type code: 0x0002 - DUID used as client identifier
    output_buf[2] = 1; // digest type = 1 (SHA-256)

    message->authority.push_back(rr);

}
示例#6
0
stl_string rrdata_convertdoms(rr_type *rr, domainname znroot, domainname origin, char *ptr) {
  stl_string ret, tmp;
  char *cptr = rr->properties;
  domainname tmpd;
  while (*cptr) {
    tmp = read_entry(ptr);
    if (*cptr == 'd' || *cptr == 'm') {
      /* domain name */
      if (!(*cptr == 'm' && strchr(tmp.c_str(), '@')) &&
          tmp[tmp.size() - 1] != '.') {
        /* domain name is relative to a non-root origin. convert it to a root origin */
        tmpd = domainname(tmp.c_str(), origin);
        if (ret.size()) ret += " ";
        ret += tmpd.torelstring(znroot);
        cptr++;
        continue;
      }
    }
    if (ret.size()) ret += " ";
    ret += tmp;
    cptr++;
  }
  return ret;
}
示例#7
0
void read_master_file(const char *file, domainname &znroot, void *userdat,
                      error_callback err, rr_callback rr_cb, rr_literal_callback rrl_cb,
                      comment_callback comm_cb, int flags) {
  bool has_znroot = !(flags&POSLIB_MF_AUTOPROBE), has_soa = false;
  char buff[1024];
  char *ptr, *p2;
  int c;
  bool ttl_given = false; stl_string ttl = "3600";
  domainname origin, nam;
  int linenum = 1, linenum2;
  stl_string str, tmp, t2, t3, nm;
  DnsRR rr;
  rr_type *type = NULL;
  
  FILE *f = try_fopen_r(file);
  if (!f) throw PException(true, "Could not open %s", file);
  
  c = fgetc(f);
  if (c != EOF) ungetc(c, f);
		
	if (has_znroot) origin = znroot;

  try {
  begin:
    while (!feof(f)) {
      /* since the poslib functions will filter out comments, let's do them ourselves */
      if (comm_cb) {
        c = fgetc(f);
        if (c == ';') {
            fgets(buff, 1024, f);
	    ptr = buff + strlen(buff) - 1;
	    while (ptr >= buff && (*ptr == '\n' || *ptr == '\r')) *ptr = '\0';
	    comm_cb(userdat, buff);
	    continue;
        }
        ungetc(c, f);
      }

      try {
        read_line(buff, f, &linenum, &linenum2);
      } catch (PException p) {
        break;
      }

      if (buff[0] == 0) goto begin;
      ptr = buff;
      while (*ptr == ' ' || *ptr == '\t') ptr++;
      if (*ptr == '\0') continue;

      if (buff[0] == '$') {
        if (strncmpi(buff, "$ttl ", 4) == 0) {
          ttl = buff + 5;
          ttl_given = true;
        } else if (strncmpi(buff, "$origin ", 8) == 0) {
          /* origin */
          origin = domainname(buff + 8, znroot);
          if (!has_znroot) {
            /* first entry. this is the zone root */
            znroot = origin;
            has_znroot = true;
          }
        } else err(userdat, file, linenum2,
                   PException(true, "Unknown directive %s", buff).message);
        continue;
      }

      if (!has_znroot) {
        znroot = guess_zone_name(file);
        origin =  znroot;
        has_znroot = true;
      }

      if (buff[0] != ' ' && buff[0] != '\t') {
        nam = domainname(read_entry(ptr).c_str(), origin);
      } else if (!has_soa) {
        err(userdat, file, linenum2, "First record in zone should have a domain name! Using origin instead.");
        nam = origin;
      }

      /* can be class or ttl or rrtype */
      while (1) {
        str = read_entry(ptr);
        if (str == "IN" || str == "HS" || str == "CH" || str == "HS" ||
            str == "in" || str == "hs" || str == "ch" || str == "hs") {
          /* class */
          continue;
        } else if ((type = rrtype_getinfo(str.c_str())) != NULL) {
          break;
        } else {
          try {
            txt_to_int(str.c_str());
            ttl_given = true;
          } catch (PException p) {
            err(userdat, file, linenum2, PException(true, "Invalid TTL/RR type %s!", str.c_str()).message);
            goto begin;
          }
          ttl = str.c_str();
        }
      }

      if (!has_soa) {
        if (type->type != DNS_TYPE_SOA) {
          if (!(flags & POSLIB_MF_NOSOA)) {
            err(userdat, file, linenum2, "First record was no SOA record; using default SOA record instead.");
            if (rr_cb) {
              rr.NAME = znroot;
              rr.TYPE = DNS_TYPE_SOA;
              rr.TTL = 3600;
              tmp = rr_fromstring(DNS_TYPE_SOA, "ns1 hostmaster 1 2h 1h 1d 2h", znroot);
              rr.RDLENGTH = tmp.size();
              rr.RDATA = (unsigned char *)memdup(tmp.c_str(), tmp.size());
              rr_cb(userdat, &rr);
            }
            if (rrl_cb)
              rrl_cb(userdat, "@", "1h", "SOA", "ns1 hostmaster 1 2h 1h 1d 2h", znroot);
          } else if (!ttl_given) {
            err(userdat, file, linenum2, "First record should have TTL value; using 1h for now.");
            ttl = "3600";
            ttl_given = true;
          }
        } else {
          if (!ttl_given) {
            p2 = ptr;
            read_entry(p2); read_entry(p2); read_entry(p2);
            read_entry(p2); read_entry(p2); read_entry(p2);
            t3 = read_entry(p2);
            if (strlen(t3.c_str()) < 32) ttl = t3;
          }
        }
        has_soa = true;
      } else if (type->type == DNS_TYPE_SOA && !(flags & POSLIB_MF_NOSOA)) {
        err(userdat, file, linenum2, "Non-initial SOA record ignored");
        continue;
      }

      if (!(nam >= znroot)) {
        err(userdat, file, linenum2, PException(true, "Ignoring domain name %s outside of zone %s!", nam.tocstr(), znroot.tocstr()).message);
        continue;
      }

      if (rr_cb) {
        try {
          rr.NAME = nam;
          rr.TYPE = type->type;
          rr.TTL = txt_to_int(ttl.c_str());
          tmp = rr_fromstring(type->type, ptr, origin);
          rr.RDLENGTH = tmp.size();
          rr.RDATA = (unsigned char *)memdup(tmp.c_str(), tmp.size());
          rr_cb(userdat, &rr);
        } catch (PException p) {
          err(userdat, file, linenum2, p.message);
        }
      }

      if (rrl_cb) {
        try {
          t2 = ptr;
          nm = nam.torelstring(znroot);
          tmp = rr_fromstring(type->type, ptr, origin);
          if (origin != znroot) t2 = rrdata_convertdoms(type, znroot, origin, ptr);
        } catch (PException p) {
          err(userdat, file, linenum2, p.message);
        }
        rrl_cb(userdat, nm.c_str(), ttl.c_str(), type->name, t2.c_str(), znroot);
      }
    }
  } catch (PException p) {
    fclose(f);
    throw p;
  }
  fclose(f);
}
示例#8
0
void
apop(Ticketreq *tr, int type)
{
	int challen, i, tries;
	char *secret, *hkey, *p;
	Ticketreq treq;
	DigestState *s;
	char sbuf[SECRETLEN], hbuf[DESKEYLEN];
	char tbuf[TICKREQLEN];
	char buf[MD5dlen*2];
	uchar digest[MD5dlen], resp[MD5dlen];
	ulong rb[4];
	char chal[256];

	USED(tr);

	/*
	 *  Create a challenge and send it.
	 */
	randombytes((uchar*)rb, sizeof(rb));
	p = chal;
	p += snprint(p, sizeof(chal), "<%lux%lux.%lux%lux@%s>",
		rb[0], rb[1], rb[2], rb[3], domainname());
	challen = p - chal;
	print("%c%-5d%s", AuthOKvar, challen, chal);

	/* give user a few attempts */
	for(tries = 0; ; tries++) {
		/*
		 *  get ticket request
		 */
		if(readn(0, tbuf, TICKREQLEN) < 0)
			exits(0);
		convM2TR(tbuf, &treq);
		tr = &treq;
		if(tr->type != type)
			exits(0);

		/*
		 * read response
		 */
		if(readn(0, buf, MD5dlen*2) < 0)
			exits(0);
		for(i = 0; i < MD5dlen; i++)
			resp[i] = (h2b(buf[2*i])<<4)|h2b(buf[2*i+1]);

		/*
		 * lookup
		 */
		secret = findsecret(KEYDB, tr->uid, sbuf);
		hkey = findkey(KEYDB, tr->hostid, hbuf);
		if(hkey == 0 || secret == 0){
			replyerror("apop-fail bad response %s", raddr);
			logfail(tr->uid);
			if(tries > 5)
				return;
			continue;
		}

		/*
		 *  check for match
		 */
		if(type == AuthCram){
			hmac_md5((uchar*)chal, challen,
				(uchar*)secret, strlen(secret),
				digest, nil);
		} else {
			s = md5((uchar*)chal, challen, 0, 0);
			md5((uchar*)secret, strlen(secret), digest, s);
		}
		if(memcmp(digest, resp, MD5dlen) != 0){
			replyerror("apop-fail bad response %s", raddr);
			logfail(tr->uid);
			if(tries > 5)
				return;
			continue;
		}
		break;
	}

	succeed(tr->uid);

	/*
	 *  reply with ticket & authenticator
	 */
	if(tickauthreply(tr, hkey) < 0)
		exits(0);

	if(debug){
		if(type == AuthCram)
			syslog(0, AUTHLOG, "cram-ok %s %s", tr->uid, raddr);
		else
			syslog(0, AUTHLOG, "apop-ok %s %s", tr->uid, raddr);
	}
}