Skip to content

Commit a71b89e

Browse files
authored
NEW FEATURE: Add SMIMEA support for BIND and deSEC (#3786)
1 parent 2be2b0f commit a71b89e

File tree

24 files changed

+384
-148
lines changed

24 files changed

+384
-148
lines changed

build/generate/featureMatrix.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ func matrixData() *FeatureMatrix {
115115
DomainModifierNaptr = "[`NAPTR`](../language-reference/domain-modifiers/NAPTR.md)"
116116
DomainModifierOpenpgpkey = "[`DNSKEY`](../language-reference/domain-modifiers/OPENPGPKEY.md)"
117117
DomainModifierPtr = "[`PTR`](../language-reference/domain-modifiers/PTR.md)"
118+
DomainModifierSMIMEA = "[`SMIMEA`](../language-reference/domain-modifiers/SMIMEA.md)"
118119
DomainModifierSoa = "[`SOA`](../language-reference/domain-modifiers/SOA.md)"
119120
DomainModifierSrv = "[`SRV`](../language-reference/domain-modifiers/SRV.md)"
120121
DomainModifierSshfp = "[`SSHFP`](../language-reference/domain-modifiers/SSHFP.md)"
@@ -164,6 +165,7 @@ func matrixData() *FeatureMatrix {
164165
[]string{ // security
165166
DomainModifierCaa,
166167
DomainModifierHTTPS,
168+
DomainModifierSMIMEA,
167169
DomainModifierSshfp,
168170
DomainModifierTlsa,
169171
},
@@ -278,6 +280,10 @@ func matrixData() *FeatureMatrix {
278280
DomainModifierPtr,
279281
providers.CanUsePTR,
280282
)
283+
setCapability(
284+
DomainModifierSMIMEA,
285+
providers.CanUseSMIMEA,
286+
)
281287
setCapability(
282288
DomainModifierSoa,
283289
providers.CanUseSOA,

commands/getZones.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,8 @@ func formatDsl(rec *models.RecordConfig, defaultTTL uint32) string {
351351
jsonQuoted(rec.NaptrRegexp), // regex
352352
jsonQuoted(rec.GetTargetField()), // .
353353
)
354+
case "SMIMEA":
355+
target = fmt.Sprintf(`%d, %d, %d, "%s"`, rec.SmimeaUsage, rec.SmimeaSelector, rec.SmimeaMatchingType, rec.GetTargetField())
354356
case "SSHFP":
355357
target = fmt.Sprintf(`%d, %d, "%s"`, rec.SshfpAlgorithm, rec.SshfpFingerprint, rec.GetTargetField())
356358
case "SOA":

commands/types/dnscontrol.d.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2870,6 +2870,38 @@ declare function REV(address: string): string;
28702870
*/
28712871
declare function REVCOMPAT(rfc: string): string;
28722872

2873+
/**
2874+
* `SMIMEA` adds a `SMIMEA` record to a domain. The name should be the hashed and stripped local part of the e-mail.
2875+
*
2876+
* To create the name, you can the following command:
2877+
*
2878+
* ```bash
2879+
* # For the e-mail [email protected] run:
2880+
* echo -n "bosun" | sha256sum | awk '{print $1}' | cut -c1-56
2881+
* # f10e7de079689f55c0cdd6782e4dd1448c84006962a4bd832e8eff73
2882+
* ```
2883+
*
2884+
* Usage, selector, and type are ints.
2885+
*
2886+
* Certificate is a hex string.
2887+
*
2888+
* To create the string for the type 0, you can run this command with your S/MIME certificate:
2889+
*
2890+
* ```bash
2891+
* openssl x509 -in smime-cert.pem -outform DER | xxd -p -c 10000
2892+
* ```
2893+
*
2894+
* ```javascript
2895+
* D("example.com", REG_MY_PROVIDER, DnsProvider(DSP_MY_PROVIDER),
2896+
* // Create SMIMEA record for certificate for the name bosun
2897+
* SMIMEA("f10e7de079689f55c0cdd6782e4dd1448c84006962a4bd832e8eff73", 3, 0, 0, "30820353308202f8a003020102..."),
2898+
* );
2899+
* ```
2900+
*
2901+
* @see https://docs.dnscontrol.org/language-reference/domain-modifiers/smimea
2902+
*/
2903+
declare function SMIMEA(name: string, usage: number, selector: number, type: number, certificate: string, ...modifiers: RecordModifier[]): DomainModifier;
2904+
28732905
/**
28742906
* `SOA` adds an `SOA` record to a domain. The name should be `@`. ns and mbox are strings. The other fields are unsigned 32-bit ints.
28752907
*

documentation/SUMMARY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@
7070
* [OPENPGPKEY](language-reference/domain-modifiers/OPENPGPKEY.md)
7171
* [PTR](language-reference/domain-modifiers/PTR.md)
7272
* [PURGE](language-reference/domain-modifiers/PURGE.md)
73+
* [SMIMEA](language-reference/domain-modifiers/SMIMEA.md)
7374
* [SOA](language-reference/domain-modifiers/SOA.md)
7475
* [SPF_BUILDER](language-reference/domain-modifiers/SPF_BUILDER.md)
7576
* [SRV](language-reference/domain-modifiers/SRV.md)
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
---
2+
name: SMIMEA
3+
parameters:
4+
- name
5+
- usage
6+
- selector
7+
- type
8+
- certificate
9+
- modifiers...
10+
parameter_types:
11+
name: string
12+
usage: number
13+
selector: number
14+
type: number
15+
certificate: string
16+
"modifiers...": RecordModifier[]
17+
---
18+
19+
`SMIMEA` adds a `SMIMEA` record to a domain. The name should be the hashed and stripped local part of the e-mail.
20+
21+
To create the name, you can the following command:
22+
23+
```bash
24+
# For the e-mail [email protected] run:
25+
echo -n "bosun" | sha256sum | awk '{print $1}' | cut -c1-56
26+
# f10e7de079689f55c0cdd6782e4dd1448c84006962a4bd832e8eff73
27+
```
28+
29+
Usage, selector, and type are ints.
30+
31+
Certificate is a hex string.
32+
33+
To create the string for the type 0, you can run this command with your S/MIME certificate:
34+
35+
```bash
36+
openssl x509 -in smime-cert.pem -outform DER | xxd -p -c 10000
37+
```
38+
39+
{% code title="dnsconfig.js" %}
40+
```javascript
41+
D("example.com", REG_MY_PROVIDER, DnsProvider(DSP_MY_PROVIDER),
42+
// Create SMIMEA record for certificate for the name bosun
43+
SMIMEA("f10e7de079689f55c0cdd6782e4dd1448c84006962a4bd832e8eff73", 3, 0, 0, "30820353308202f8a003020102..."),
44+
);
45+
```
46+
{% endcode %}

documentation/provider/index.md

Lines changed: 47 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -252,53 +252,53 @@ Jump to a table:
252252

253253
### Security <!--(table 5/6)-->
254254

255-
| Provider name | [`CAA`](../language-reference/domain-modifiers/CAA.md) | [`HTTPS`](../language-reference/domain-modifiers/HTTPS.md) | [`SSHFP`](../language-reference/domain-modifiers/SSHFP.md) | [`TLSA`](../language-reference/domain-modifiers/TLSA.md) |
256-
| ------------- | ------------------------------------------------------ | ---------------------------------------------------------- | ---------------------------------------------------------- | -------------------------------------------------------- |
257-
| [`AKAMAIEDGEDNS`](akamaiedgedns.md) |||||
258-
| [`AUTODNS`](autodns.md) |||||
259-
| [`AXFRDDNS`](axfrddns.md) |||||
260-
| [`AZURE_DNS`](azure_dns.md) |||||
261-
| [`AZURE_PRIVATE_DNS`](azure_private_dns.md) |||||
262-
| [`BIND`](bind.md) |||||
263-
| [`BUNNY_DNS`](bunny_dns.md) |||||
264-
| [`CLOUDFLAREAPI`](cloudflareapi.md) |||||
265-
| [`CLOUDNS`](cloudns.md) |||||
266-
| [`CNR`](cnr.md) |||||
267-
| [`CSCGLOBAL`](cscglobal.md) |||||
268-
| [`DESEC`](desec.md) |||||
269-
| [`DIGITALOCEAN`](digitalocean.md) |||||
270-
| [`DNSIMPLE`](dnsimple.md) |||||
271-
| [`DNSMADEEASY`](dnsmadeeasy.md) |||||
272-
| [`DOMAINNAMESHOP`](domainnameshop.md) |||||
273-
| [`EXOSCALE`](exoscale.md) |||||
274-
| [`GANDI_V5`](gandi_v5.md) |||||
275-
| [`GCLOUD`](gcloud.md) |||||
276-
| [`GCORE`](gcore.md) |||||
277-
| [`HEDNS`](hedns.md) |||||
278-
| [`HETZNER`](hetzner.md) |||||
279-
| [`HEXONET`](hexonet.md) |||||
280-
| [`HOSTINGDE`](hostingde.md) |||||
281-
| [`HUAWEICLOUD`](huaweicloud.md) |||||
282-
| [`INWX`](inwx.md) |||||
283-
| [`JOKER`](joker.md) |||||
284-
| [`LINODE`](linode.md) |||||
285-
| [`LOOPIA`](loopia.md) |||||
286-
| [`LUADNS`](luadns.md) |||||
287-
| [`MYTHICBEASTS`](mythicbeasts.md) |||||
288-
| [`NAMECHEAP`](namecheap.md) |||||
289-
| [`NETCUP`](netcup.md) |||||
290-
| [`NETLIFY`](netlify.md) |||||
291-
| [`NS1`](ns1.md) |||||
292-
| [`ORACLE`](oracle.md) |||||
293-
| [`OVH`](ovh.md) |||||
294-
| [`PORKBUN`](porkbun.md) |||||
295-
| [`POWERDNS`](powerdns.md) |||||
296-
| [`REALTIMEREGISTER`](realtimeregister.md) |||||
297-
| [`ROUTE53`](route53.md) |||||
298-
| [`RWTH`](rwth.md) |||||
299-
| [`SAKURACLOUD`](sakuracloud.md) |||||
300-
| [`TRANSIP`](transip.md) |||||
301-
| [`VULTR`](vultr.md) |||||
255+
| Provider name | [`CAA`](../language-reference/domain-modifiers/CAA.md) | [`HTTPS`](../language-reference/domain-modifiers/HTTPS.md) | [`SMIMEA`](../language-reference/domain-modifiers/SMIMEA.md) | [`SSHFP`](../language-reference/domain-modifiers/SSHFP.md) | [`TLSA`](../language-reference/domain-modifiers/TLSA.md) |
256+
| ------------- | ------------------------------------------------------ | ---------------------------------------------------------- | ------------------------------------------------------------ | ---------------------------------------------------------- | -------------------------------------------------------- |
257+
| [`AKAMAIEDGEDNS`](akamaiedgedns.md) ||| | ||
258+
| [`AUTODNS`](autodns.md) ||| | ||
259+
| [`AXFRDDNS`](axfrddns.md) ||| | ||
260+
| [`AZURE_DNS`](azure_dns.md) ||| | ||
261+
| [`AZURE_PRIVATE_DNS`](azure_private_dns.md) ||| | ||
262+
| [`BIND`](bind.md) ||||||
263+
| [`BUNNY_DNS`](bunny_dns.md) ||| | ||
264+
| [`CLOUDFLAREAPI`](cloudflareapi.md) ||| | ||
265+
| [`CLOUDNS`](cloudns.md) ||| | ||
266+
| [`CNR`](cnr.md) ||| | ||
267+
| [`CSCGLOBAL`](cscglobal.md) ||||||
268+
| [`DESEC`](desec.md) ||||||
269+
| [`DIGITALOCEAN`](digitalocean.md) ||||||
270+
| [`DNSIMPLE`](dnsimple.md) ||| | ||
271+
| [`DNSMADEEASY`](dnsmadeeasy.md) ||| | ||
272+
| [`DOMAINNAMESHOP`](domainnameshop.md) ||| | ||
273+
| [`EXOSCALE`](exoscale.md) |||| | |
274+
| [`GANDI_V5`](gandi_v5.md) ||| | ||
275+
| [`GCLOUD`](gcloud.md) ||| | ||
276+
| [`GCORE`](gcore.md) ||| | ||
277+
| [`HEDNS`](hedns.md) ||| | ||
278+
| [`HETZNER`](hetzner.md) ||| | ||
279+
| [`HEXONET`](hexonet.md) |||| | |
280+
| [`HOSTINGDE`](hostingde.md) ||| | ||
281+
| [`HUAWEICLOUD`](huaweicloud.md) ||| | ||
282+
| [`INWX`](inwx.md) ||| | ||
283+
| [`JOKER`](joker.md) ||| | ||
284+
| [`LINODE`](linode.md) ||||||
285+
| [`LOOPIA`](loopia.md) ||| | ||
286+
| [`LUADNS`](luadns.md) ||| | ||
287+
| [`MYTHICBEASTS`](mythicbeasts.md) ||| | ||
288+
| [`NAMECHEAP`](namecheap.md) |||| | |
289+
| [`NETCUP`](netcup.md) ||||||
290+
| [`NETLIFY`](netlify.md) ||| | ||
291+
| [`NS1`](ns1.md) |||| | |
292+
| [`ORACLE`](oracle.md) ||| | ||
293+
| [`OVH`](ovh.md) ||| | ||
294+
| [`PORKBUN`](porkbun.md) ||| | ||
295+
| [`POWERDNS`](powerdns.md) ||| | ||
296+
| [`REALTIMEREGISTER`](realtimeregister.md) ||| | ||
297+
| [`ROUTE53`](route53.md) ||| | ||
298+
| [`RWTH`](rwth.md) ||| | ||
299+
| [`SAKURACLOUD`](sakuracloud.md) ||| | ||
300+
| [`TRANSIP`](transip.md) ||| | ||
301+
| [`VULTR`](vultr.md) ||| | ||
302302

303303

304304
### DNSSEC <!--(table 6/6)-->

integrationTest/helpers_integration_test.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -479,6 +479,12 @@ func r53alias(name, aliasType, target, evalTargetHealth string) *models.RecordCo
479479
return r
480480
}
481481

482+
func smimea(name string, usage, selector, matchingtype uint8, target string) *models.RecordConfig {
483+
r := makeRec(name, target, "SMIMEA")
484+
panicOnErr(r.SetTargetSMIMEA(usage, selector, matchingtype, target))
485+
return r
486+
}
487+
482488
func soa(name string, ns, mbox string, serial, refresh, retry, expire, minttl uint32) *models.RecordConfig {
483489
r := makeRec(name, "", "SOA")
484490
panicOnErr(r.SetTargetSOA(ns, mbox, serial, refresh, retry, expire, minttl))

integrationTest/integration_test.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2021,6 +2021,15 @@ func makeTests() []*TestGroup {
20212021
tc("final", txt("final", `TestDNSProviders was successful!`)),
20222022
),
20232023

2024+
testgroup("SMIMEA",
2025+
requires(providers.CanUseSMIMEA),
2026+
tc("SMIMEA record", smimea("_443._tcp", 3, 1, 1, sha256hash)),
2027+
tc("SMIMEA change usage", smimea("_443._tcp", 2, 1, 1, sha256hash)),
2028+
tc("SMIMEA change selector", smimea("_443._tcp", 2, 0, 1, sha256hash)),
2029+
tc("SMIMEA change matchingtype", smimea("_443._tcp", 2, 0, 2, sha512hash)),
2030+
tc("SMIMEA change certificate", smimea("_443._tcp", 2, 0, 2, reversedSha512)),
2031+
),
2032+
20242033
// Narrative: Congrats! You're done! If you've made it this far
20252034
// you're very close to being able to submit your PR. Here's
20262035
// some tips:

models/dnsrr.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ func helperRRtoRC(rr dns.RR, origin string, fixBug bool) (RecordConfig, error) {
6868
err = rc.SetTarget(v.Ns)
6969
case *dns.PTR:
7070
err = rc.SetTarget(v.Ptr)
71+
case *dns.SMIMEA:
72+
err = rc.SetTargetSMIMEA(v.Usage, v.Selector, v.MatchingType, v.Certificate)
7173
case *dns.SOA:
7274
err = rc.SetTargetSOA(v.Ns, v.Mbox, v.Serial, v.Refresh, v.Retry, v.Expire, v.Minttl)
7375
case *dns.SRV:

models/domain.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ func (dc *DomainConfig) Punycode() error {
142142
if err := rec.SetTarget(rec.GetTargetField()); err != nil {
143143
return err
144144
}
145-
case "A", "AAAA", "CAA", "DHCID", "DNSKEY", "DS", "HTTPS", "LOC", "NAPTR", "OPENPGPKEY", "SOA", "SSHFP", "SVCB", "TXT", "TLSA", "AZURE_ALIAS":
145+
case "A", "AAAA", "CAA", "DHCID", "DNSKEY", "DS", "HTTPS", "LOC", "NAPTR", "OPENPGPKEY", "SMIMEA", "SOA", "SSHFP", "SVCB", "TXT", "TLSA", "AZURE_ALIAS":
146146
// Nothing to do.
147147
default:
148148
return fmt.Errorf("Punycode rtype %v unimplemented", rec.Type)

0 commit comments

Comments
 (0)