proper parsing of TLS and DS attrs
[pdns-pipe-nmc.git] / SPEC.md
1 % JSON Domain Format as Implemented by Pdns-Pipe-Nmc
2
3 ## Data Format
4
5 `DomObj` is a JSON object, specifically a `Map` (not an `Array`), or a
6 `String` containing a dotted quad (see Note below).
7
8 ### `DomObj` Object
9
10 `DomObj` is a JSON `Map`, with the following attributes, all optional:
11
12 | Key         | Type                                  | Comment                         |
13 |-------------|---------------------------------------|---------------------------------|
14 | service     | Array(SrvObj)                         | Located two levels above pos.   |
15 | ip          | Array(String)                         | Dotted quad "1.2.3.4"           |
16 | ip6         | Array(String)                         | Semicolon format "DEAD::BEEF"   |
17 | tor         | String                                | Onion name                      |
18 | i2p         | I2pObj                                |                                 |
19 | freenet     | String                                |                                 |
20 | alias       | String                                | Nullifies other attributes      |
21 | translate   | String                                | Nullifies other attributes      |
22 | email       | String                                | Used in `SOA`                   |
23 | loc         | String                                | Format suitable for `LOC`       |
24 | info        | JsonObj                               | Currently unspecified           |
25 | ns          | Array(String)                         | Domain names as in `NS`         |
26 | delegate    | String                                | Replaces current object         |
27 | import      | String                                | "Deep" merges into current obj. |
28 | map         | Map(String:DomObj)                    | Tree of subdomain objects       |
29 | fingerprint | Array(String)                         |                                 |
30 | tls         | Map(String:Map(String:Array(TlsObj))) |                                 |
31 | ds          | Array(DsObj)                          |                                 |
32
33 #### Notes:
34
35 * Any attribute specified as `Array(String)` may be present in the
36   JSON document as `String`, which is interpreted the same way as
37   an `Array` containing a single `String` element.
38 * In any place where `DomObj` is expected there may be a `String`, which
39   is interpreted as an IPv4 address. In other words, a string `"1.2.3.4"`
40   is interpreted the same way as the object `"{\"ip\":\"1.2.3.4\"}"`
41   Such "shorthand" DomObj can be present at the top level or as a value
42   in the `"map"` attribute.
43
44 ### `SrvObj` Object
45
46 `SrvObj` is a heterogenous Array of fixed size containing 6 elements:
47
48 | N | Type   | Meaning  |
49 |---|--------|----------|
50 | 0 | String | Service  |
51 | 1 | String | Protocol |
52 | 2 | Int    | Priority |
53 | 3 | Int    | Weight   |
54 | 4 | Int    | Port     |
55 | 5 | String | Hostname |
56
57 #### Notes
58
59 * `Service` and `Protocol` are two elements of the domain name, without
60   the undescore '_'.
61 * `SrvObj` with Service `"smtp"`, Protocol `"tcp"` and Port `25` is also
62   interpteted as an `MX` DNS respource.
63 * When lookup is performed for `SRV` records at fqdn
64   `"_serv._proto.sub.dom.bit"`, domain object for `"sub.dom.bit"` must be
65   fetched, and in this object, `SrvObj`s for the Service `"serv"` and
66   Protocol `"proto"` selected from it.
67
68 ### `TlsObj` Object
69
70 `TlsObj` is a heterogenous Array of fixed size containing 3 elements:
71
72 | N | Type   | Meaning                                               |
73 |---|--------|-------------------------------------------------------|
74 | 0 | Int    | Match type - 0:Exact, 1:SHA-256, 2:SHA-512            |
75 | 1 | String | Match value - certificate or hash of it as hex string |
76 | 2 | Int    | Include subdomains - 0:No, 1:Yes                      |
77
78 ### `DsObj` Object
79
80 `DsObj` is a heterogenous Array of fixed size containing 4 elements:
81
82 | N | Type   | Meaning                  |
83 |---|--------|--------------------------|
84 | 0 | Int    | Key Tag                  |
85 | 1 | Int    | Key Algorithm            |
86 | 2 | Int    | Hash Type                |
87 | 3 | String | Hash Value as hex string |
88
89 ## Data Interpretation
90
91 Assuming a query for a subdomain of a basedomain in the `.bit` TLD
92 (subdomain possibly being empty), lookup starts by fetching the
93 "base" object for basedomain. The domain object is then transformed
94 by the following sequece applied recursively:
95
96 1. Value of the element of the `"map"` attribute with the key `""`
97    (empty string) is recursively merged into the base domain. The
98    `""` element of the `"map"` is removed from the result.
99 2. If attribute `"import"` does not exist in the resulting object,
100    recursion stops, and step 3 is performed on the result
101    If attribute `"import"` exists in the resulting object, lookup is
102    is performed for the value of this attribute, and fetched object
103    is recursively merged into the base domain. The `"import"` attribute
104    is removed from the result. Then the result is passed as base
105    domain to step 1.
106 3. If subdomain chain is empty, recursion stops, and step 4 is
107    performed on the result. If subdomain chain is not empty, next
108    element is taken out of the chain, and the `"map"` is looked
109    up for the element with the name matching the subdomain element.
110    The value of this element of the `"map"` is passed as base domain
111    to step 1. If matching element does not exist, lookup is considered
112    failed.
113 4. Domain object with all `""` map elements and all `"import"` data
114    merged is "normalized" by removal of attributes that are nullified
115    by the presence of other attributes.
116
117 Note that the process involves recursion nested to three levels.
118
119 ## Merging
120
121 When a domain object `sub` needs merging into a domain object `base`,
122 the following rules are applied:
123
124 * Of `String` and other "scalar" attributes, one is chosen, the value
125   from the `base` taking precedence.
126 * On `Array` attribtes, `union` operation is performed. (Of equal
127   elements, only one copy is left.)
128 * On `Map` attributes, recursive merge is performed. On the top level,
129   elemens with keys that are only present in either `base` or `sub`
130   object are all put into result. The values of the elements that are
131   present in both `base` and `sub` are merged according to the rules
132   applicable to their type.
133