Added the TLSA DNS record.
This commit is contained in:
@@ -129,6 +129,7 @@ pub fn is_yggdrasil_record(record: &DnsRecord) -> bool {
|
|||||||
DnsRecord::AAAA { addr, .. } => return is_yggdrasil(&IpAddr::from(*addr)),
|
DnsRecord::AAAA { addr, .. } => return is_yggdrasil(&IpAddr::from(*addr)),
|
||||||
DnsRecord::SRV { .. } => {}
|
DnsRecord::SRV { .. } => {}
|
||||||
DnsRecord::OPT { .. } => {}
|
DnsRecord::OPT { .. } => {}
|
||||||
|
DnsRecord::TLSA { .. } => {}
|
||||||
}
|
}
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|||||||
+43
-1
@@ -39,6 +39,7 @@ pub enum QueryType {
|
|||||||
AAAA, // 28
|
AAAA, // 28
|
||||||
SRV, // 33
|
SRV, // 33
|
||||||
OPT, // 41
|
OPT, // 41
|
||||||
|
TLSA, // 52
|
||||||
}
|
}
|
||||||
|
|
||||||
impl QueryType {
|
impl QueryType {
|
||||||
@@ -55,6 +56,7 @@ impl QueryType {
|
|||||||
QueryType::AAAA => 28,
|
QueryType::AAAA => 28,
|
||||||
QueryType::SRV => 33,
|
QueryType::SRV => 33,
|
||||||
QueryType::OPT => 41,
|
QueryType::OPT => 41,
|
||||||
|
QueryType::TLSA => 52,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,6 +72,7 @@ impl QueryType {
|
|||||||
28 => QueryType::AAAA,
|
28 => QueryType::AAAA,
|
||||||
33 => QueryType::SRV,
|
33 => QueryType::SRV,
|
||||||
41 => QueryType::OPT,
|
41 => QueryType::OPT,
|
||||||
|
52 => QueryType::TLSA,
|
||||||
_ => QueryType::UNKNOWN(num),
|
_ => QueryType::UNKNOWN(num),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -169,6 +172,14 @@ pub enum DnsRecord {
|
|||||||
flags: u32,
|
flags: u32,
|
||||||
data: String
|
data: String
|
||||||
}, // 41
|
}, // 41
|
||||||
|
TLSA {
|
||||||
|
domain: String,
|
||||||
|
certificate_usage: u8,
|
||||||
|
selector: u8,
|
||||||
|
matching_type: u8,
|
||||||
|
data: Vec<u8>,
|
||||||
|
ttl: TransientTtl
|
||||||
|
}, // 52
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DnsRecord {
|
impl DnsRecord {
|
||||||
@@ -281,6 +292,16 @@ impl DnsRecord {
|
|||||||
|
|
||||||
Ok(DnsRecord::OPT { packet_len: class, flags: ttl, data })
|
Ok(DnsRecord::OPT { packet_len: class, flags: ttl, data })
|
||||||
}
|
}
|
||||||
|
QueryType::TLSA => {
|
||||||
|
let certificate_usage = buffer.read()?;
|
||||||
|
let selector = buffer.read()?;
|
||||||
|
let matching_type = buffer.read()?;
|
||||||
|
let cur_pos = buffer.pos();
|
||||||
|
let data_len = data_len - 3;
|
||||||
|
let data = buffer.get_range(cur_pos, data_len as usize)?.to_vec();
|
||||||
|
buffer.step(data_len as usize)?;
|
||||||
|
Ok(DnsRecord::TLSA { domain, certificate_usage, selector, matching_type, data, ttl: TransientTtl(ttl) })
|
||||||
|
}
|
||||||
QueryType::UNKNOWN(_) => {
|
QueryType::UNKNOWN(_) => {
|
||||||
buffer.step(data_len as usize)?;
|
buffer.step(data_len as usize)?;
|
||||||
|
|
||||||
@@ -422,6 +443,20 @@ impl DnsRecord {
|
|||||||
buffer.write_u8(*b)?;
|
buffer.write_u8(*b)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
DnsRecord::TLSA { ref domain, certificate_usage, selector, matching_type, ref data, ttl: TransientTtl(ttl) } => {
|
||||||
|
buffer.write_qname(domain)?;
|
||||||
|
buffer.write_u16(QueryType::TLSA.to_num())?;
|
||||||
|
buffer.write_u16(1)?;
|
||||||
|
buffer.write_u32(ttl)?;
|
||||||
|
buffer.write_u16((data.len() + 3) as u16)?;
|
||||||
|
buffer.write_u8(certificate_usage)?;
|
||||||
|
buffer.write_u8(selector)?;
|
||||||
|
buffer.write_u8(matching_type)?;
|
||||||
|
|
||||||
|
for b in data {
|
||||||
|
buffer.write_u8(*b)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
DnsRecord::OPT { packet_len, flags, ref data } => {
|
DnsRecord::OPT { packet_len, flags, ref data } => {
|
||||||
buffer.write_u8(0)?;
|
buffer.write_u8(0)?;
|
||||||
buffer.write_u16(QueryType::OPT.to_num())?;
|
buffer.write_u16(QueryType::OPT.to_num())?;
|
||||||
@@ -454,6 +489,7 @@ impl DnsRecord {
|
|||||||
DnsRecord::SOA { .. } => QueryType::SOA,
|
DnsRecord::SOA { .. } => QueryType::SOA,
|
||||||
DnsRecord::TXT { .. } => QueryType::TXT,
|
DnsRecord::TXT { .. } => QueryType::TXT,
|
||||||
DnsRecord::OPT { .. } => QueryType::OPT,
|
DnsRecord::OPT { .. } => QueryType::OPT,
|
||||||
|
DnsRecord::TLSA { .. } => QueryType::TLSA,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -469,7 +505,8 @@ impl DnsRecord {
|
|||||||
| DnsRecord::UNKNOWN { ref domain, .. }
|
| DnsRecord::UNKNOWN { ref domain, .. }
|
||||||
| DnsRecord::SOA { ref domain, .. }
|
| DnsRecord::SOA { ref domain, .. }
|
||||||
| DnsRecord::TXT { ref domain, .. } => Some(domain.clone()),
|
| DnsRecord::TXT { ref domain, .. } => Some(domain.clone()),
|
||||||
DnsRecord::OPT { .. } => None,
|
DnsRecord::OPT { .. }
|
||||||
|
| DnsRecord::TLSA { .. } => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -490,6 +527,10 @@ impl DnsRecord {
|
|||||||
Some(result)
|
Some(result)
|
||||||
},
|
},
|
||||||
DnsRecord::UNKNOWN { ref domain, .. } => Some(domain.clone()),
|
DnsRecord::UNKNOWN { ref domain, .. } => Some(domain.clone()),
|
||||||
|
DnsRecord::TLSA { ref domain, certificate_usage, selector, matching_type, ref data, .. } => {
|
||||||
|
let data = crate::commons::to_hex(data);
|
||||||
|
Some(format!("{} {} {} {} {}", domain, certificate_usage, selector, matching_type, &data))
|
||||||
|
},
|
||||||
DnsRecord::OPT { .. } => None,
|
DnsRecord::OPT { .. } => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -506,6 +547,7 @@ impl DnsRecord {
|
|||||||
| DnsRecord::UNKNOWN { ttl: TransientTtl(ttl), .. }
|
| DnsRecord::UNKNOWN { ttl: TransientTtl(ttl), .. }
|
||||||
| DnsRecord::SOA { ttl: TransientTtl(ttl), .. }
|
| DnsRecord::SOA { ttl: TransientTtl(ttl), .. }
|
||||||
| DnsRecord::TXT { ttl: TransientTtl(ttl), .. } => ttl,
|
| DnsRecord::TXT { ttl: TransientTtl(ttl), .. } => ttl,
|
||||||
|
| DnsRecord::TLSA { ttl: TransientTtl(ttl), .. } => ttl,
|
||||||
DnsRecord::OPT { .. } => 0
|
DnsRecord::OPT { .. } => 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ pub trait DnsResolver {
|
|||||||
|
|
||||||
for filter in context.filters.iter() {
|
for filter in context.filters.iter() {
|
||||||
if let Some(packet) = filter.lookup(qname, qtype) {
|
if let Some(packet) = filter.lookup(qname, qtype) {
|
||||||
|
context.cache.store(&packet.answers)?;
|
||||||
return Ok(packet);
|
return Ok(packet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -107,6 +107,7 @@ pub fn execute_query(context: Arc<ServerContext>, request: &DnsPacket) -> DnsPac
|
|||||||
|
|
||||||
let question = &request.questions[0];
|
let question = &request.questions[0];
|
||||||
packet.questions.push(question.clone());
|
packet.questions.push(question.clone());
|
||||||
|
log::trace!("Resolving: {}, type {:?}", &question.name, &question.qtype);
|
||||||
|
|
||||||
let mut resolver = context.create_resolver(Arc::clone(&context));
|
let mut resolver = context.create_resolver(Arc::clone(&context));
|
||||||
let res_code = match resolver.resolve(&question.name, question.qtype, request.header.recursion_desired) {
|
let res_code = match resolver.resolve(&question.name, question.qtype, request.header.recursion_desired) {
|
||||||
|
|||||||
@@ -388,6 +388,7 @@
|
|||||||
<option>MX</option>
|
<option>MX</option>
|
||||||
<option>SRV</option>
|
<option>SRV</option>
|
||||||
<option>TXT</option>
|
<option>TXT</option>
|
||||||
|
<option>TLSA</option>
|
||||||
<!--<option>SOA</option>
|
<!--<option>SOA</option>
|
||||||
<option>OPT</option>-->
|
<option>OPT</option>-->
|
||||||
</select>
|
</select>
|
||||||
|
|||||||
+17
-3
@@ -81,7 +81,7 @@ function refreshRecordsList() {
|
|||||||
function showNewRecordDialog() {
|
function showNewRecordDialog() {
|
||||||
var button_positive = document.getElementById("new_record_positive_button");
|
var button_positive = document.getElementById("new_record_positive_button");
|
||||||
button_positive.onclick = function() {
|
button_positive.onclick = function() {
|
||||||
checkRecord(get_record_from_dialog());
|
checkRecord(getRecordFromDialog());
|
||||||
};
|
};
|
||||||
|
|
||||||
var button_negative = document.getElementById("new_record_negative_button");
|
var button_negative = document.getElementById("new_record_negative_button");
|
||||||
@@ -95,7 +95,7 @@ function showNewRecordDialog() {
|
|||||||
dialog.className = "modal is-active";
|
dialog.className = "modal is-active";
|
||||||
}
|
}
|
||||||
|
|
||||||
function get_record_from_dialog() {
|
function getRecordFromDialog() {
|
||||||
var record_name = document.getElementById("record_name").value.toLowerCase();
|
var record_name = document.getElementById("record_name").value.toLowerCase();
|
||||||
var record_type = document.getElementById("record_type").value;
|
var record_type = document.getElementById("record_type").value;
|
||||||
var record_ttl = parseInt(document.getElementById("record_ttl").value);
|
var record_ttl = parseInt(document.getElementById("record_ttl").value);
|
||||||
@@ -112,6 +112,12 @@ function get_record_from_dialog() {
|
|||||||
var record_weight = parseInt(document.getElementById("record_weight").value);
|
var record_weight = parseInt(document.getElementById("record_weight").value);
|
||||||
var record_port = parseInt(document.getElementById("record_port").value);
|
var record_port = parseInt(document.getElementById("record_port").value);
|
||||||
return { type: record_type, domain: record_name, ttl: record_ttl, priority: record_priority, weight: record_weight, port: record_port, host: record_data }
|
return { type: record_type, domain: record_name, ttl: record_ttl, priority: record_priority, weight: record_weight, port: record_port, host: record_data }
|
||||||
|
} else if (record_type == "TLSA") {
|
||||||
|
var certificate_usage = parseInt(document.getElementById("record_priority").value);
|
||||||
|
var selector = parseInt(document.getElementById("record_weight").value);
|
||||||
|
var matching_type = parseInt(document.getElementById("record_port").value);
|
||||||
|
record_data = hexToBytes(record_data);
|
||||||
|
return { type: record_type, domain: record_name, ttl: record_ttl, certificate_usage: certificate_usage, selector: selector, matching_type: matching_type, data: record_data }
|
||||||
}
|
}
|
||||||
return { type: record_type, domain: record_name, ttl: record_ttl, addr: record_data }
|
return { type: record_type, domain: record_name, ttl: record_ttl, addr: record_data }
|
||||||
}
|
}
|
||||||
@@ -266,7 +272,7 @@ function checkRecord(data) {
|
|||||||
|
|
||||||
function recordOkay(okay) {
|
function recordOkay(okay) {
|
||||||
if (okay) {
|
if (okay) {
|
||||||
addRecord(get_record_from_dialog()); // It will refresh list
|
addRecord(getRecordFromDialog()); // It will refresh list
|
||||||
var dialog = document.getElementById("new_record_dialog");
|
var dialog = document.getElementById("new_record_dialog");
|
||||||
dialog.className = "modal";
|
dialog.className = "modal";
|
||||||
} else {
|
} else {
|
||||||
@@ -654,4 +660,12 @@ function selectKey(index, event) {
|
|||||||
function keySelected(index) {
|
function keySelected(index) {
|
||||||
currentSelectedKey = index;
|
currentSelectedKey = index;
|
||||||
refreshKeysMenu();
|
refreshKeysMenu();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert a hex string to a byte array
|
||||||
|
function hexToBytes(hex) {
|
||||||
|
for (var bytes = [], c = 0; c < hex.length; c += 2) {
|
||||||
|
bytes.push(parseInt(hex.substr(c, 2), 16));
|
||||||
|
}
|
||||||
|
return bytes;
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user