diff --git a/tsig.go b/tsig.go index 24013096..4837b4ab 100644 --- a/tsig.go +++ b/tsig.go @@ -208,6 +208,9 @@ func tsigBuffer(msgbuf []byte, rr *TSIG, requestMAC string, timersOnly bool) []b rr.Fudge = 300 // Standard (RFC) default. } + // Replace message ID in header with original ID from TSIG + binary.BigEndian.PutUint16(msgbuf[0:2], rr.OrigId) + if requestMAC != "" { m := new(macWireFmt) m.MACSize = uint16(len(requestMAC) / 2) diff --git a/tsig_test.go b/tsig_test.go index 48b9988b..4bc52733 100644 --- a/tsig_test.go +++ b/tsig_test.go @@ -1,6 +1,7 @@ package dns import ( + "encoding/binary" "testing" "time" ) @@ -22,6 +23,20 @@ func TestTsig(t *testing.T) { if err != nil { t.Fatal(err) } + + // TSIG accounts for ID substitution. This means if the message ID is + // changed by a forwarder, we should still be able to verify the TSIG. + m = newTsig(HmacMD5) + buf, _, err = TsigGenerate(m, "pRZgBrBvI4NAHZYhxmhs/Q==", "", false) + if err != nil { + t.Fatal(err) + } + + binary.BigEndian.PutUint16(buf[0:2], uint16(42)) + err = TsigVerify(buf, "pRZgBrBvI4NAHZYhxmhs/Q==", "", false) + if err != nil { + t.Fatal(err) + } } func TestTsigCase(t *testing.T) {