void tsig_from_string (DnsRR*& tsig_rr, stl_string& sign_key, const char* keystring) { stl_string keyname, key; const char *ptr; ptr = strchr (keystring, ':'); if (!ptr) throw PException (true, "%s is not a valid key string (should be keyname:key)", keystring); keyname.append (keystring, (int)(ptr - keystring)); keystring = ptr + 1; ptr = strchr (keystring, ':'); key.append (keystring, ptr ? (int)(ptr - keystring) : strlen (keystring)); if (tsig_rr) { delete tsig_rr; tsig_rr = NULL; } if (ptr) { int fudge = txt_to_int (ptr + 1); tsig_rr = tsig_record (keyname.c_str (), fudge); } else { tsig_rr = tsig_record (keyname.c_str ()); } sign_key = base64_decode (key.c_str ()); }
int getserviceportbyname(const char *name) { struct servent *service; try { int t = txt_to_int(name); return t; } catch (PException p) { } if ((service = getservbyname(name, NULL)) == NULL) throw PException(true, "Unknown service %s", name); return ntohs(service->s_port); }
int getprotocolbyname(const char *name) { struct protoent *protocol; try { int t = txt_to_int(name); return t; } catch (PException p) { } if ((protocol = getprotobyname(name)) == NULL) throw PException(true, "Unknown protocol %s", name); return protocol->p_proto; }
/** * 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; }
/** * insert a new-PTR entry in message * */ void DNSUpdate::addinMsg_newPTR(){ DnsRR rr; const int bufSize = 128; char destination[16]; char result[bufSize]; memset(result, 0, bufSize); inet_pton6(hostip, destination); doRevDnsAddress(destination,result); rr.NAME = result; rr.TYPE = qtype_getcode("PTR", false); rr.TTL = txt_to_int(ttl); string tmp = string(_hostname); string data = rr_fromstring(rr.TYPE, tmp.c_str()); rr.RDLENGTH = data.size(); rr.RDATA = (unsigned char*)memdup(data.c_str(), rr.RDLENGTH); message->authority.push_back(rr); Log(Debug) << "DDNS: PTR record created: " << result << " -> " << tmp << LogEnd; }
uint16_t qtype_getcode(const char *name, bool allow_qtype) { try { uint16_t ret = txt_to_int(name); if (!is_common_rr(ret)) throw PException(); return ret; } catch (PException p) { if (allow_qtype) { if (strcmpi(name, "maila") == 0) return QTYPE_MAILA; if (strcmpi(name, "mailb") == 0) return QTYPE_MAILB; if (strcmpi(name, "ixfr") == 0) return QTYPE_IXFR; if (strcmpi(name, "axfr") == 0) return QTYPE_AXFR; if (strcmpi(name, "any") == 0) return QTYPE_ANY; if (strcmpi(name, "all") == 0) return QTYPE_ANY; } rr_type *t = rrtype_getinfo(name); if (!t) throw PException(true, "Qtype %s not supported", name); return t->type; } }
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); }
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); }