Skip to content

Commit

Permalink
WIP2
Browse files Browse the repository at this point in the history
  • Loading branch information
cryptix committed May 28, 2024
1 parent 75afede commit 5e6d942
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 31 deletions.
2 changes: 1 addition & 1 deletion golang/cmd/sig0namectl/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ func main() {
&cli.StringFlag{Name: "key-name", Aliases: []string{"kn"}, Usage: "Kso.me.na.me.+aaa+bbbbb", EnvVars: []string{"SIG0_SIG0_KEYFILES"}},
},
Commands: []*cli.Command{
queryCmd, printKeyCmd, updateCmd,
queryCmd, printKeyCmd, updateCmd, requestKeyCmd,
},
}

Expand Down
44 changes: 44 additions & 0 deletions golang/cmd/sig0namectl/request_key.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package main

import (
"fmt"
"log"

"github.com/NetworkCommons/sig0namectl/sig0"
"github.com/davecgh/go-spew/spew"
"github.com/miekg/dns"
"github.com/urfave/cli/v2"
)

var requestKeyCmd = &cli.Command{
Name: "requestKey",
Usage: "requestKey <subZone> <zone>",
Aliases: []string{"rk"},
Action: requestKeyAction,
}

func requestKeyAction(cCtx *cli.Context) error {
newSubZone := cCtx.Args().Get(0)
zone := cCtx.Args().Get(1)
if newSubZone == "" || zone == "" {
return cli.Exit("subZone and zone are required", 1)
}

reqMsg, dohServer, err := sig0.CreateRequestKeyMsg(newSubZone, zone)
if err != nil {
return fmt.Errorf("Failed to create request key message: %w", err)
}
log.Println("Requesting key for", newSubZone, "under", zone, "from", dohServer)
spew.Dump(reqMsg)

answer, err := sig0.SendDOHQuery(dohServer, reqMsg)
if err != nil {
return fmt.Errorf("Failed to send DOH query: %w", err)
}

if answer.Rcode != dns.RcodeSuccess {
return fmt.Errorf("Update failed: %v", answer)
}

return nil
}
1 change: 0 additions & 1 deletion golang/sig0/answers.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ func ParseBase64Answer(answer string) (*dns.Msg, error) {
if err != nil {
return nil, fmt.Errorf("parse: invalid base64: %w", err)
}

var resp = new(dns.Msg)
err = resp.Unpack(data)
if err != nil {
Expand Down
45 changes: 19 additions & 26 deletions golang/sig0/request_key.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,89 +14,82 @@ var (
DefaultDOHResolver = "dns.quad9.net"
)

func CreateRequestKeyMsg(subZone, zone string) (*dns.Msg, error) {
func CreateRequestKeyMsg(subZone, zone string) (*dns.Msg, string, error) {

// Determine the zone master using the provided sub zone and base zone
signalZone := fmt.Sprintf("%s.%s", SignalSubzonePrefix, zone)
querySOAForSignal, err := QuerySOA(signalZone)
if err != nil {
return nil, fmt.Errorf("Error: ZONE %s SOA record does not resolve: %w", signalZone, err)
return nil, "", fmt.Errorf("Error: ZONE %s SOA record does not resolve: %w", signalZone, err)
}

soaAnswer, err := SendDOHQuery(DefaultDOHResolver, querySOAForSignal)
if err != nil {
return nil, fmt.Errorf("Error: DOH query failed for %s: %w", DefaultDOHResolver, err)
return nil, "", fmt.Errorf("Error: DOH query failed for %s: %w", DefaultDOHResolver, err)
}

zoneSoa, err := ExpectSOA(soaAnswer)
if err != nil {
return nil, fmt.Errorf("Error: SOA record not found in response for %s: %w", signalZone, err)
return nil, "", fmt.Errorf("Error: SOA record not found in response for %s: %w", signalZone, err)
}

if zoneSoa != "ns1.free2air.org." {
return nil, fmt.Errorf("Unexpected SOA: %s - TODO: Query SVCB to get the zone master's DOH endpoint", zoneSoa)
return nil, "", fmt.Errorf("Unexpected SOA: %s - TODO: Query SVCB to get the zone master's DOH endpoint", zoneSoa)
}
var dohUpdateURL = "doh.zenr.io"
var dohUpdateHost = "doh.zenr.io"

// Check if zone already exists
newSubZone := fmt.Sprintf("%s.%s", subZone, zone)
err = checkZoneDoesntExist(dohUpdateURL, newSubZone)
err = checkZoneDoesntExist(dohUpdateHost, newSubZone)
if err != nil {
return nil, err
return nil, "", err
}

zoneRequest := fmt.Sprintf("%s.%s.%s", subZone, SignalSubzonePrefix, zone)
err = checkZoneDoesntExist(dohUpdateURL, zoneRequest)
err = checkZoneDoesntExist(dohUpdateHost, zoneRequest)
if err != nil {
return nil, err
return nil, "", err
}

// craft RRs and create signed update
subZoneSigner, err := LoadOrGenerateKey(newSubZone)
if err != nil {
return nil, err
return nil, "", err
}

err = subZoneSigner.StartUpdate(zone)
if err != nil {
return nil, err
return nil, "", err
}

// Here we split the key details
// turn it into an RR and split of the first 3 fields
// so that we can re-use the key for a different zone
keyDetails := strings.TrimSpace(subZoneSigner.Key.String())
keyFields := strings.Fields(keyDetails)
if len(keyFields) < 6 {
return nil, errors.New("Invalid key data")
return nil, "", errors.New("Invalid key data")
}
keyData := strings.Join(keyFields[3:], " ")

nsupdateItemSig0Key := fmt.Sprintf("%s %d %s", zoneRequest, DefaultTTL, keyData)
err = subZoneSigner.UpdateParsedRR(nsupdateItemSig0Key)
if err != nil {
return nil, err
return nil, "", err
}

nsupdateItemPtr := fmt.Sprintf("%s %d IN PTR %s.", newSubZone, DefaultTTL, zoneRequest)
err = subZoneSigner.UpdateParsedRR(nsupdateItemPtr)
if err != nil {
return nil, err
return nil, "", err
}

signedUpdateMsg, err := subZoneSigner.SignUpdate()
if err != nil {
return nil, err
return nil, "", err
}

// updateAnswer, err := SendDOHQuery(dohUpdateURL, signedUpdateMsg)
// if err != nil {
// return nil, err
// }

// if updateAnswer.Rcode != dns.RcodeSuccess {
// return nil, fmt.Errorf("Error: Update failed: %v", updateAnswer)
// }

return signedUpdateMsg, nil
return signedUpdateMsg, dohUpdateHost, nil
}

func checkZoneDoesntExist(dohServer, zone string) error {
Expand Down
5 changes: 3 additions & 2 deletions golang/sig0/request_key_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,11 @@ func TestRequestKey(t *testing.T) {
rand.Read(buf)
testSubZone := fmt.Sprintf("sig0namectl-test-%x", buf)

zoneRequestMsg, err := CreateRequestKeyMsg(testSubZone, "zenr.io")
zoneRequestMsg, dohServer, err := CreateRequestKeyMsg(testSubZone, "zenr.io")
r.NoError(err)
r.Equal("doh.zenr.io", dohServer)
t.Log(zoneRequestMsg)
t.FailNow()
// t.FailNow()

// TODO: cleanup test keys
}
2 changes: 1 addition & 1 deletion golang/sig0/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ func (signer *Signer) SignUpdate() (*dns.Msg, error) {
func (signer *Signer) UpdateParsedRR(rr string) error {
rrInsert, err := dns.NewRR(rr)
if err != nil {
return err
return fmt.Errorf("sig0: failed to parse RR: %w", err)
}

return signer.UpdateRR(rrInsert)
Expand Down

0 comments on commit 5e6d942

Please sign in to comment.