Skip to content

Commit

Permalink
fixed SD_inspector for new DNS, added more services
Browse files Browse the repository at this point in the history
- Added services: ftp, telnet
- Added https service links for port 443
- Added a lot of error catching
- updated SD_Inspector to new dns query return object
  • Loading branch information
MathJud committed Aug 28, 2024
1 parent 4c90e99 commit b3b46c0
Show file tree
Hide file tree
Showing 4 changed files with 126 additions and 65 deletions.
111 changes: 72 additions & 39 deletions demo/playground/dns.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,13 @@
/// Manages dns queries
class Dns {
/// construct the DNS object with the domain to query
/// you can optionally provide a keys
/// you can optionally provide a key for the domain
constructor(domain_name, key, on_initialized) {
// FIXME: there is an error to investigate within the dohjs library when
// resolving queries via 'https://doh.zembla.io/dns-query'.
// This problem needs further investigation. In the meantime, we resolve
// everything via 'https://1.1.1.1/dns-query'
this.doh_url_dohjs = 'https://1.1.1.1/dns-query';
// domain name
this.domain = domain_name;
this.doh_domain = '1.1.1.1';
Expand All @@ -26,7 +31,7 @@ class Dns {
this.initialized_callbacks = [];

// create the resolver
this.resolver = new doh.DohResolver(this.doh_url);
this.resolver = new doh.DohResolver(this.doh_url_dohjs);

// initialize longer tasks
this.init_wasm(on_initialized);
Expand Down Expand Up @@ -54,7 +59,9 @@ class Dns {
}

/// read the record types from dns of a domain
/// and return an object
/// and returns an array of entries.
///
/// this function never errors. If it fails, it returns an empty array
async query(query_domain, record_type, callback, referrer) {
const query = doh.makeQuery(query_domain, record_type);
// we always want to query with DNSSEC enabled
Expand All @@ -70,50 +77,72 @@ class Dns {
}]
}

console.log('query: ' + query_domain + ' ' + record_type)
const log_message = 'query: ' + query_domain + ' ' + record_type + ' ' +
this.doh_url + ' ' + this.doh_method;
console.log(log_message);
console.log(query)
let query_result =
await doh.sendDohMsg(query, this.doh_url, this.doh_method);
console.log(query_result)
let result = [];

query_result.answers.forEach(ans => {
if (ans.type == record_type) {
result.push(ans.data);
try {
// FIXME: the `https://doh.zenr.io/dns_query` server throws an error in
// the dohjs library. Until this is fixed we use the default doh server.
//
// ```
// let query_result = await doh.sendDohMsg(query, this.doh_url,
// this.doh_method)
// ```
let query_result =
await doh.sendDohMsg(query, this.doh_url_dohjs, this.doh_method)
console.log(query_result)
let results = [];

for (let answer of query_result.answers) {
if (answer.type == record_type) {
results.push(answer);
}
}
});

// return object
if (typeof callback === Function) {
callback(result, referrer);
}
// return object
if (typeof callback == 'function') {
callback(results, referrer);
}

return result;
return results;
} catch (error) {
console.error(error)

if (typeof callback == 'function') {
callback([], referrer);
}

return [];
}
}

/// read the query response & look for SOA record from:
/// 1. answers section, which means zone cut is at query_domain, or
// 2. authorities section, which means zone cut is above query domain
/// and return an object
async get_zone(query_domain) {
const query_result = await this.resolver.query(query_domain, 'SOA');

for (let i = 0; i < query_result.answers.length; i++) {
const ans = query_result.answers[i];
if (ans.type == 'SOA') {
console.log('SOA found in answers: ' + ans.name);
return ans.name;
const query_result = await this.resolver.query(query_domain, 'SOA').catch(error => {
console.error('get_zone query failed')
Promise.reject('query Zone for ' + query_domain + ' failed')
})

for (let i = 0; i < query_result.answers.length; i++) {
const ans = query_result.answers[i];
if (ans.type == 'SOA') {
console.log('SOA found in answers: ' + ans.name);
return ans.name;
}
}
}

for (const auth of query_result.authorities) {
if (auth.type == 'SOA') {
console.log('SOA found in authorities: ' + auth.name);
return auth.name;
for (const auth of query_result.authorities) {
if (auth.type == 'SOA') {
console.log('SOA found in authorities: ' + auth.name);
return auth.name;
}
}
}

return Promise.reject('no Zone found for ' + query_domain);
return Promise.reject('no Zone found for ' + query_domain);
}

/// get DoH endpoint
Expand All @@ -125,10 +154,12 @@ class Dns {
if (this.domain.endsWith('zenr.io')) {
this.doh_domain = 'doh.zenr.io';
this.doh_url = 'https://doh.zenr.io/dns_query';
return
}
if (this.domain.endsWith('beta.freifunk.net')) {
this.doh_domain = 'doh.zenr.io';
this.doh_url = 'https://doh.zenr.io/dns_query';
return
}

return;
Expand Down Expand Up @@ -156,15 +187,17 @@ class Dns {

/// check if an RRSIG record is present for a specific domain
async check_rrsig(query_domain) {
const query_result = await this.resolver.query(query_domain, 'RRSIG');

if (query_result.answers.length > 0) {
return true
} else {
const query_result = await this.resolver.query(query_domain, 'RRSIG').catch(error => {
console.error('check_rrsig query failed for ' +query_domain)
return false
}
})

return Promise.reject('something went wrong');
if (query_result.answers.length > 0) {
return true
}
else {
return false
}
}

/// check key status
Expand Down
40 changes: 25 additions & 15 deletions demo/playground/keys.js
Original file line number Diff line number Diff line change
Expand Up @@ -166,22 +166,32 @@ class Key {
// check status of key
console.log(
'key.check_status ' + this.domain + ' ' + zone + ' ' + doh_domain)
let status =
await window.goFuncs.checkKeyStatus(this.filename, zone, doh_domain);

if (status.KeyRRExists === 'true') {
this.active = true;
} else {
this.active = false;
}
if (status.QueuePTRExists === 'true') {
this.waiting = true;
} else {
this.waiting = false;
}
try {
const status =
await window.goFuncs.checkKeyStatus(this.filename, zone, doh_domain)

console.log(
'status received: ' + this.domain + ' active: ' + this.active +
' waiting: ' + this.waiting)
if (status.KeyRRExists === 'true') {
this.active = true;
}
else {
this.active = false;
}
if (status.QueuePTRExists === 'true') {
this.waiting = true;
} else {
this.waiting = false;
}

console.log(
'status received: ' + this.domain + ' active: ' + this.active +
' waiting: ' + this.waiting)
} catch (error) {
console.log(
'key.check_status error ' + this.domain + ' ' + zone + ' ' +
doh_domain)
console.error(error);
return
}
}
}
18 changes: 10 additions & 8 deletions demo/playground/sd_inspector.js
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ class UiEntry {
} else {
// add entries
for (let i = 0; i < list.length; i++) {
referrer.append_entry(list[i], referrer);
referrer.append_entry(list[i].data, referrer);
}
// remove loader
const spinner =
Expand Down Expand Up @@ -295,22 +295,24 @@ class UiServiceInstance extends UiEntry {
for (let i = 0; i < list.length; i++) {
if (i > 0) {
// append hr
let hr = document.createElement('HR');
const hr = document.createElement('HR');
content.appendChild(hr);
}

let p = document.createElement('P');
let text = document.createTextNode(list[i]);
p.appendChild(text);
content.appendChild(p);
for (const entry of list[i].data) {
const p = document.createElement('P');
const text = document.createTextNode(entry);
p.appendChild(text);
content.appendChild(p);
}
}
}

// loop through service list entries and update their link
// if needed
let entries = referrer.container.getElementsByClassName('srv-entry');
for (let i = 0; i < entries.length; i++) {
entries[i].create_service_link(list)
for (const entry of entries) {
entry.create_service_link(list)
}
}
}
Expand Down
22 changes: 19 additions & 3 deletions demo/playground/services.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,24 @@ class SdServiceInfo {
'txt': 'required',
'icon': 'terminal'
},
'_telnet': {
'url': 'telnet://',
'default_port': 23,
'txt': 'required',
'icon': 'terminal'
},
'_sftp': {
'url': 'sftp://',
'default_port': 22,
'txt': 'required',
'icon': 'folder-tree'
},
'_ftp': {
'url': 'ftp://',
'default_port': 21,
'txt': 'required',
'icon': 'folder-tree'
},
'_gopher': {
'url': 'gopher://',
'default_port': 70,
Expand All @@ -45,9 +57,13 @@ class SdServiceInfo {
let link_path = '';

// check if service is known
const service_object = this.service_list[service];
let service_object = this.service_list[service];
if (service_object === undefined) {
return null
} else if (service === '_http' && port === 443) {
// set specific https settings
service_object.default_port = 443;
service_object.url = 'https://'
}

// set port, if it is not at default port
Expand Down Expand Up @@ -80,9 +96,9 @@ class SdServiceInfo {
txt_2_object(txt_array) {
let txt_result = {};
for (let i = 0; i < txt_array.length; i++) {
for (let j = 0; j < txt_array[i].length; j++) {
for (let j = 0; j < txt_array[i].data.length; j++) {
// convert the binary array to string
let entry = String.fromCharCode.apply(String, txt_array[i][j])
let entry = String.fromCharCode.apply(String, txt_array[i].data[j])

// split string
const key_value = entry.split('=')
Expand Down

0 comments on commit b3b46c0

Please sign in to comment.