Compare commits
	
		
			No commits in common. "bd8b57efd11e75472e9372a252e91189f8b830d9" and "b5ec1f7982beb9deaa8119c47cd9db67af61eeb6" have entirely different histories.
		
	
	
		
			bd8b57efd1
			...
			b5ec1f7982
		
	
		
@ -22,7 +22,7 @@ Install
 | 
			
		||||
### systemd service
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
curl -L https://git.coolaj86.com/coolaj86/digd.js/raw/v1.2/install.sh | bash
 | 
			
		||||
curl -L https://git.coolaj86.com/coolaj86/digd.js/raw/v1.1/install.sh | bash
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### with git
 | 
			
		||||
@ -33,8 +33,8 @@ npm install -g 'git+https://git.coolaj86.com/coolaj86/digd.js.git#v1'
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
# Install exactly v1.2.0
 | 
			
		||||
npm install -g 'git+https://git.coolaj86.com/coolaj86/digd.js.git#v1.2.0'
 | 
			
		||||
# Install exactly v1.1.9
 | 
			
		||||
npm install -g 'git+https://git.coolaj86.com/coolaj86/digd.js.git#v1.1.9'
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### without git
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										13
									
								
								bin/digd.js
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								bin/digd.js
									
									
									
									
									
								
							@ -373,7 +373,7 @@ cli.main(function (args, cli) {
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function respondWithResults(err, resp) {
 | 
			
		||||
    require('../lib/dns-store').query(path.resolve(cli.input), query, function (err, resp) {
 | 
			
		||||
 | 
			
		||||
      if (err) { console.log('[DEV] answer not found in local db, recursing'); console.error(err); recurse(); return; }
 | 
			
		||||
 | 
			
		||||
@ -383,16 +383,7 @@ cli.main(function (args, cli) {
 | 
			
		||||
      if (!cli.norecurse && query.header.rd) { resp.header.ra = 1; }
 | 
			
		||||
 | 
			
		||||
      sendResponse(resp);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    var engine;
 | 
			
		||||
    try {
 | 
			
		||||
      engine = require('../lib/store.json.js').create({ filepath: path.resolve(cli.input) });
 | 
			
		||||
    } catch(e) {
 | 
			
		||||
      respondWithResults(e);
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
    require('../lib/digd.js').query(engine, query, respondWithResults);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -10,14 +10,23 @@ var NOERROR = 0;
 | 
			
		||||
var NXDOMAIN = 3;
 | 
			
		||||
var REFUSED = 5;
 | 
			
		||||
 | 
			
		||||
function getRecords(engine, qname, cb) {
 | 
			
		||||
function getRecords(db, qname, cb) {
 | 
			
		||||
  var delMe = {};
 | 
			
		||||
  var dns = require('dns');
 | 
			
		||||
  // SECURITY XXX TODO var dig = require('dig.js/dns-request');
 | 
			
		||||
  var count;
 | 
			
		||||
  var myRecords = db.records.slice(0).filter(function (r) {
 | 
			
		||||
 | 
			
		||||
  return engine.getRecords({ name: qname }, function (err, myRecords) {
 | 
			
		||||
    if (err) { cb(err); return; }
 | 
			
		||||
    if ('string' !== typeof r.name) {
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // TODO use IN in masterquest (or implement OR)
 | 
			
		||||
    // Only return single-level wildcard?
 | 
			
		||||
    if (qname === r.name || ('*.' + qname.split('.').slice(1).join('.')) === r.name) {
 | 
			
		||||
      return true;
 | 
			
		||||
    }
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  function checkCount() {
 | 
			
		||||
    var ready;
 | 
			
		||||
@ -99,13 +108,12 @@ function getRecords(engine, qname, cb) {
 | 
			
		||||
  if (!myRecords.length) {
 | 
			
		||||
    checkCount();
 | 
			
		||||
  }
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function dbToResourceRecord(r) {
 | 
			
		||||
  return {
 | 
			
		||||
    name: r.name
 | 
			
		||||
  , typeName: r.typeName || r.type // NS
 | 
			
		||||
  , typeName: r.type // NS
 | 
			
		||||
  , className: 'IN'
 | 
			
		||||
  , ttl: r.ttl || 300
 | 
			
		||||
 | 
			
		||||
@ -139,7 +147,7 @@ function dbToResourceRecord(r) {
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function getNs(engine, ds, results, cb) {
 | 
			
		||||
function getNs(db, ds, results, cb) {
 | 
			
		||||
  console.log('[DEV] getNs entered with domains', ds);
 | 
			
		||||
 | 
			
		||||
  var d = ds.shift();
 | 
			
		||||
@ -153,7 +161,7 @@ function getNs(engine, ds, results, cb) {
 | 
			
		||||
 | 
			
		||||
  var qn = d.id.toLowerCase();
 | 
			
		||||
 | 
			
		||||
  return getRecords(engine, qn, function (err, records) {
 | 
			
		||||
  return getRecords(db, qn, function (err, records) {
 | 
			
		||||
    if (err) { cb(err); return; }
 | 
			
		||||
 | 
			
		||||
    records.forEach(function (r) {
 | 
			
		||||
@ -179,16 +187,16 @@ function getNs(engine, ds, results, cb) {
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    if (!results.authority.length) {
 | 
			
		||||
      return getNs(engine, ds, results, cb);
 | 
			
		||||
      return getNs(db, ds, results, cb);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // d.vanityNs should only be vanity nameservers (pointing to this same server)
 | 
			
		||||
    if (d.vanityNs || results.authority.some(function (ns) {
 | 
			
		||||
      console.log('[debug] ns', ns);
 | 
			
		||||
      return -1 !== engine.primaryNameservers.indexOf(ns.data.toLowerCase());
 | 
			
		||||
      return -1 !== db.primaryNameservers.indexOf(ns.data.toLowerCase());
 | 
			
		||||
    })) {
 | 
			
		||||
      results.authority.length = 0;
 | 
			
		||||
      results.authority.push(domainToSoa(engine.primaryNameservers, d));
 | 
			
		||||
      results.authority.push(domainToSoa(db, d));
 | 
			
		||||
      results.header.rcode = NXDOMAIN;
 | 
			
		||||
    }
 | 
			
		||||
    cb(null, results);
 | 
			
		||||
@ -196,8 +204,8 @@ function getNs(engine, ds, results, cb) {
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function domainToSoa(primaryNameservers, domain) {
 | 
			
		||||
  var nameservers = domain.vanityNs || primaryNameservers;
 | 
			
		||||
function domainToSoa(db, domain) {
 | 
			
		||||
  var nameservers = domain.vanityNs || db.primaryNameservers;
 | 
			
		||||
 | 
			
		||||
  var index = Math.floor(Math.random() * nameservers.length) % nameservers.length;
 | 
			
		||||
  var nameserver = nameservers[index];
 | 
			
		||||
@ -237,20 +245,20 @@ function domainToSoa(primaryNameservers, domain) {
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function getSoa(primaryNameservers, domain, results, cb, answerSoa) {
 | 
			
		||||
function getSoa(db, domain, results, cb, answerSoa) {
 | 
			
		||||
  console.log('[DEV] getSoa entered');
 | 
			
		||||
 | 
			
		||||
  if (!answerSoa) {
 | 
			
		||||
    results.authority.push(domainToSoa(primaryNameservers, domain));
 | 
			
		||||
    results.authority.push(domainToSoa(db, domain));
 | 
			
		||||
  } else {
 | 
			
		||||
    results.answer.push(domainToSoa(primaryNameservers, domain));
 | 
			
		||||
    results.answer.push(domainToSoa(db, domain));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  cb(null, results);
 | 
			
		||||
  return;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
module.exports.query = function (engine, query, cb) {
 | 
			
		||||
module.exports.query = function (input, query, cb) {
 | 
			
		||||
  /*
 | 
			
		||||
  var fs = require('fs');
 | 
			
		||||
 | 
			
		||||
@ -263,7 +271,11 @@ module.exports.query = function (engine, query, cb) {
 | 
			
		||||
  });
 | 
			
		||||
  */
 | 
			
		||||
 | 
			
		||||
  var db;
 | 
			
		||||
  var qname;
 | 
			
		||||
  try {
 | 
			
		||||
    db = require(input);
 | 
			
		||||
  } catch(e) { cb(e); return; }
 | 
			
		||||
 | 
			
		||||
  if (!Array.isArray(query.question) || query.question.length < 1) {
 | 
			
		||||
    cb(new Error("query is missing question section"));
 | 
			
		||||
@ -325,10 +337,9 @@ module.exports.query = function (engine, query, cb) {
 | 
			
		||||
    console.log('[DEV] answerSoa?', answerSoa);
 | 
			
		||||
    console.log('[DEV] qnames');
 | 
			
		||||
    console.log(qnames);
 | 
			
		||||
 | 
			
		||||
    return engine.getSoas({ names: qnames}, function (err, myDomains) {
 | 
			
		||||
      console.log('[SOA] looking for', qnames, 'and proudly serving', err, myDomains);
 | 
			
		||||
      if (err) { cb(err); return; }
 | 
			
		||||
    var myDomains = db.domains.filter(function (d) {
 | 
			
		||||
      return -1 !== qnames.indexOf(d.id.toLowerCase());
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    // this should result in a REFUSED status
 | 
			
		||||
    if (!myDomains.length) {
 | 
			
		||||
@ -350,10 +361,10 @@ module.exports.query = function (engine, query, cb) {
 | 
			
		||||
    //console.log('sorted domains', myDomains);
 | 
			
		||||
 | 
			
		||||
    if (!getNsAlso) {
 | 
			
		||||
        return getSoa(engine.primaryNameservers, myDomains[0], results, cb, answerSoa);
 | 
			
		||||
      return getSoa(db, myDomains[0], results, cb, answerSoa);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
      return getNs(engine, /*myDomains.slice(0)*/qnames.map(function (qn) { return { id: qn }; }), results, function (err, results) {
 | 
			
		||||
    return getNs(db, /*myDomains.slice(0)*/qnames.map(function (qn) { return { id: qn }; }), results, function (err, results) {
 | 
			
		||||
      //console.log('[DEV] getNs complete');
 | 
			
		||||
 | 
			
		||||
      if (err) { cb(err, results); return; }
 | 
			
		||||
@ -364,10 +375,9 @@ module.exports.query = function (engine, query, cb) {
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // myDomains was sorted such that the longest was first
 | 
			
		||||
        return getSoa(engine.primaryNameservers, myDomains[0], results, cb);
 | 
			
		||||
      return getSoa(db, myDomains[0], results, cb);
 | 
			
		||||
 | 
			
		||||
    });
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if ('SOA' === query.question[0].typeName) {
 | 
			
		||||
@ -375,7 +385,7 @@ module.exports.query = function (engine, query, cb) {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  //console.log('[DEV] QUERY NAME', qname);
 | 
			
		||||
  return getRecords(engine, qname, function (err, someRecords) {
 | 
			
		||||
  return getRecords(db, qname, function (err, someRecords) {
 | 
			
		||||
    var myRecords;
 | 
			
		||||
    var nsRecords = [];
 | 
			
		||||
 | 
			
		||||
@ -400,7 +410,7 @@ module.exports.query = function (engine, query, cb) {
 | 
			
		||||
      // NOTE: I think that the issue here is EXTERNAL vs INTERNAL vanity NS
 | 
			
		||||
      // We _should_ reply for EXTERNAL vanity NS... but not when it's listed on the SOA internally?
 | 
			
		||||
      // It's surrounding the problem of what if I do sub domain delegation to the same server.
 | 
			
		||||
      if (-1 === engine.primaryNameservers.indexOf(r.data.toLowerCase())) {
 | 
			
		||||
      if (-1 === db.primaryNameservers.indexOf(r.data.toLowerCase())) {
 | 
			
		||||
        console.log("It's a vanity NS");
 | 
			
		||||
        return false;
 | 
			
		||||
      }
 | 
			
		||||
@ -1,37 +0,0 @@
 | 
			
		||||
'use strict';
 | 
			
		||||
 | 
			
		||||
module.exports.create = function (opts) {
 | 
			
		||||
  // opts = { filepath };
 | 
			
		||||
  var engine = { db: null };
 | 
			
		||||
 | 
			
		||||
  var db = require(opts.filepath);
 | 
			
		||||
 | 
			
		||||
  engine.primaryNameservers = db.primaryNameservers;
 | 
			
		||||
  engine.getSoas = function (query, cb) {
 | 
			
		||||
    var myDomains = db.domains.filter(function (d) {
 | 
			
		||||
      return -1 !== query.names.indexOf(d.id.toLowerCase());
 | 
			
		||||
    });
 | 
			
		||||
    process.nextTick(function () {
 | 
			
		||||
      cb(null, myDomains);
 | 
			
		||||
    });
 | 
			
		||||
  };
 | 
			
		||||
  engine.getRecords = function (query, cb) {
 | 
			
		||||
    var myRecords = db.records.slice(0).filter(function (r) {
 | 
			
		||||
 | 
			
		||||
      if ('string' !== typeof r.name) {
 | 
			
		||||
        return false;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // TODO use IN in masterquest (or implement OR)
 | 
			
		||||
      // Only return single-level wildcard?
 | 
			
		||||
      if (query.name === r.name || ('*.' + query.name.split('.').slice(1).join('.')) === r.name) {
 | 
			
		||||
        return true;
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
    process.nextTick(function () {
 | 
			
		||||
      cb(null, myRecords);
 | 
			
		||||
    });
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  return engine;
 | 
			
		||||
};
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "digd.js",
 | 
			
		||||
  "version": "1.2.0",
 | 
			
		||||
  "version": "1.1.9",
 | 
			
		||||
  "description": "A lightweight DNS / mDNS daemon (server) for creating and capturing DNS and mDNS query and response packets to disk as binary and/or JSON. Options are similar to the Unix dig command.",
 | 
			
		||||
  "main": "bin/digd.js",
 | 
			
		||||
  "homepage": "https://git.coolaj86.com/coolaj86/digd.js",
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user