mirror of
				https://github.com/coredns/coredns.git
				synced 2025-11-04 03:03:14 -05:00 
			
		
		
		
	
		
			
	
	
		
			246 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
		
		
			
		
	
	
			246 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| 
								 | 
							
								package tsig
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								import (
							 | 
						||
| 
								 | 
							
									"fmt"
							 | 
						||
| 
								 | 
							
									"strings"
							 | 
						||
| 
								 | 
							
									"testing"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									"github.com/coredns/caddy"
							 | 
						||
| 
								 | 
							
									"github.com/coredns/coredns/plugin/test"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									"github.com/miekg/dns"
							 | 
						||
| 
								 | 
							
								)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func TestParse(t *testing.T) {
							 | 
						||
| 
								 | 
							
									secrets := map[string]string{
							 | 
						||
| 
								 | 
							
										"name.key.":  "test-key",
							 | 
						||
| 
								 | 
							
										"name2.key.": "test-key-2",
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									secretConfig := ""
							 | 
						||
| 
								 | 
							
									for k, s := range secrets {
							 | 
						||
| 
								 | 
							
										secretConfig += fmt.Sprintf("secret %s %s\n", k, s)
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									secretsFile, cleanup, err := test.TempFile(".", `key "name.key." {
							 | 
						||
| 
								 | 
							
									secret "test-key";
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								key "name2.key." {
							 | 
						||
| 
								 | 
							
									secret "test-key2";
							 | 
						||
| 
								 | 
							
								};`)
							 | 
						||
| 
								 | 
							
									if err != nil {
							 | 
						||
| 
								 | 
							
										t.Fatalf("failed to create temp file: %v", err)
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									defer cleanup()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									tests := []struct {
							 | 
						||
| 
								 | 
							
										input           string
							 | 
						||
| 
								 | 
							
										shouldErr       bool
							 | 
						||
| 
								 | 
							
										expectedZones   []string
							 | 
						||
| 
								 | 
							
										expectedQTypes  qTypes
							 | 
						||
| 
								 | 
							
										expectedSecrets map[string]string
							 | 
						||
| 
								 | 
							
										expectedAll     bool
							 | 
						||
| 
								 | 
							
									}{
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											input:           "tsig {\n " + secretConfig + "}",
							 | 
						||
| 
								 | 
							
											expectedZones:   []string{"."},
							 | 
						||
| 
								 | 
							
											expectedQTypes:  defaultQTypes,
							 | 
						||
| 
								 | 
							
											expectedSecrets: secrets,
							 | 
						||
| 
								 | 
							
										},
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											input:           "tsig {\n secrets " + secretsFile + "\n}",
							 | 
						||
| 
								 | 
							
											expectedZones:   []string{"."},
							 | 
						||
| 
								 | 
							
											expectedQTypes:  defaultQTypes,
							 | 
						||
| 
								 | 
							
											expectedSecrets: secrets,
							 | 
						||
| 
								 | 
							
										},
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											input:           "tsig example.com {\n " + secretConfig + "}",
							 | 
						||
| 
								 | 
							
											expectedZones:   []string{"example.com."},
							 | 
						||
| 
								 | 
							
											expectedQTypes:  defaultQTypes,
							 | 
						||
| 
								 | 
							
											expectedSecrets: secrets,
							 | 
						||
| 
								 | 
							
										},
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											input:           "tsig {\n " + secretConfig + " require all \n}",
							 | 
						||
| 
								 | 
							
											expectedZones:   []string{"."},
							 | 
						||
| 
								 | 
							
											expectedQTypes:  qTypes{},
							 | 
						||
| 
								 | 
							
											expectedAll:     true,
							 | 
						||
| 
								 | 
							
											expectedSecrets: secrets,
							 | 
						||
| 
								 | 
							
										},
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											input:           "tsig {\n " + secretConfig + " require none \n}",
							 | 
						||
| 
								 | 
							
											expectedZones:   []string{"."},
							 | 
						||
| 
								 | 
							
											expectedQTypes:  qTypes{},
							 | 
						||
| 
								 | 
							
											expectedAll:     false,
							 | 
						||
| 
								 | 
							
											expectedSecrets: secrets,
							 | 
						||
| 
								 | 
							
										},
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											input:           "tsig {\n " + secretConfig + " \n require A AAAA \n}",
							 | 
						||
| 
								 | 
							
											expectedZones:   []string{"."},
							 | 
						||
| 
								 | 
							
											expectedQTypes:  qTypes{dns.TypeA: {}, dns.TypeAAAA: {}},
							 | 
						||
| 
								 | 
							
											expectedSecrets: secrets,
							 | 
						||
| 
								 | 
							
										},
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											input:     "tsig {\n blah \n}",
							 | 
						||
| 
								 | 
							
											shouldErr: true,
							 | 
						||
| 
								 | 
							
										},
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											input:     "tsig {\n secret name. too many parameters \n}",
							 | 
						||
| 
								 | 
							
											shouldErr: true,
							 | 
						||
| 
								 | 
							
										},
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											input:     "tsig {\n require \n}",
							 | 
						||
| 
								 | 
							
											shouldErr: true,
							 | 
						||
| 
								 | 
							
										},
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											input:     "tsig {\n require invalid-qtype \n}",
							 | 
						||
| 
								 | 
							
											shouldErr: true,
							 | 
						||
| 
								 | 
							
										},
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									serverBlockKeys := []string{"."}
							 | 
						||
| 
								 | 
							
									for i, test := range tests {
							 | 
						||
| 
								 | 
							
										c := caddy.NewTestController("dns", test.input)
							 | 
						||
| 
								 | 
							
										c.ServerBlockKeys = serverBlockKeys
							 | 
						||
| 
								 | 
							
										ts, err := parse(c)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if err == nil && test.shouldErr {
							 | 
						||
| 
								 | 
							
											t.Fatalf("Test %d expected errors, but got no error.", i)
							 | 
						||
| 
								 | 
							
										} else if err != nil && !test.shouldErr {
							 | 
						||
| 
								 | 
							
											t.Fatalf("Test %d expected no errors, but got '%v'", i, err)
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if test.shouldErr {
							 | 
						||
| 
								 | 
							
											continue
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if len(test.expectedZones) != len(ts.Zones) {
							 | 
						||
| 
								 | 
							
											t.Fatalf("Test %d expected zones '%v', but got '%v'.", i, test.expectedZones, ts.Zones)
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										for j := range test.expectedZones {
							 | 
						||
| 
								 | 
							
											if test.expectedZones[j] != ts.Zones[j] {
							 | 
						||
| 
								 | 
							
												t.Errorf("Test %d expected zones '%v', but got '%v'.", i, test.expectedZones, ts.Zones)
							 | 
						||
| 
								 | 
							
												break
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if test.expectedAll != ts.all {
							 | 
						||
| 
								 | 
							
											t.Errorf("Test %d expected require all to be '%v', but got '%v'.", i, test.expectedAll, ts.all)
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if len(test.expectedQTypes) != len(ts.types) {
							 | 
						||
| 
								 | 
							
											t.Fatalf("Test %d expected required types '%v', but got '%v'.", i, test.expectedQTypes, ts.types)
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										for qt := range test.expectedQTypes {
							 | 
						||
| 
								 | 
							
											if _, ok := ts.types[qt]; !ok {
							 | 
						||
| 
								 | 
							
												t.Errorf("Test %d required types '%v', but got '%v'.", i, test.expectedQTypes, ts.types)
							 | 
						||
| 
								 | 
							
												break
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if len(test.expectedSecrets) != len(ts.secrets) {
							 | 
						||
| 
								 | 
							
											t.Fatalf("Test %d expected secrets '%v', but got '%v'.", i, test.expectedSecrets, ts.secrets)
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										for qt := range test.expectedSecrets {
							 | 
						||
| 
								 | 
							
											secret, ok := ts.secrets[qt]
							 | 
						||
| 
								 | 
							
											if !ok {
							 | 
						||
| 
								 | 
							
												t.Errorf("Test %d required secrets '%v', but got '%v'.", i, test.expectedSecrets, ts.secrets)
							 | 
						||
| 
								 | 
							
												break
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											if secret != ts.secrets[qt] {
							 | 
						||
| 
								 | 
							
												t.Errorf("Test %d required secrets '%v', but got '%v'.", i, test.expectedSecrets, ts.secrets)
							 | 
						||
| 
								 | 
							
												break
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func TestParseKeyFile(t *testing.T) {
							 | 
						||
| 
								 | 
							
									var reader = strings.NewReader(`key "foo" {
							 | 
						||
| 
								 | 
							
									algorithm hmac-sha256;
							 | 
						||
| 
								 | 
							
									secret "36eowrtmxceNA3T5AdE+JNUOWFCw3amtcyHACnrDVgQ=";
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								key "bar" {
							 | 
						||
| 
								 | 
							
									algorithm hmac-sha256;
							 | 
						||
| 
								 | 
							
									secret "X28hl0BOfAL5G0jsmJWSacrwn7YRm2f6U5brnzwWEus=";
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								key "baz" {
							 | 
						||
| 
								 | 
							
									secret "BycDPXSx/5YCD44Q4g5Nd2QNxNRDKwWTXddrU/zpIQM=";
							 | 
						||
| 
								 | 
							
								};`)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									secrets, err := parseKeyFile(reader)
							 | 
						||
| 
								 | 
							
									if err != nil {
							 | 
						||
| 
								 | 
							
										t.Fatalf("Unexpected error: %q", err)
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									expectedSecrets := map[string]string{
							 | 
						||
| 
								 | 
							
										"foo.": "36eowrtmxceNA3T5AdE+JNUOWFCw3amtcyHACnrDVgQ=",
							 | 
						||
| 
								 | 
							
										"bar.": "X28hl0BOfAL5G0jsmJWSacrwn7YRm2f6U5brnzwWEus=",
							 | 
						||
| 
								 | 
							
										"baz.": "BycDPXSx/5YCD44Q4g5Nd2QNxNRDKwWTXddrU/zpIQM=",
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if len(secrets) != len(expectedSecrets) {
							 | 
						||
| 
								 | 
							
										t.Fatalf("result has %d keys. expected %d", len(secrets), len(expectedSecrets))
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									for k, sec := range secrets {
							 | 
						||
| 
								 | 
							
										expectedSec, ok := expectedSecrets[k]
							 | 
						||
| 
								 | 
							
										if !ok {
							 | 
						||
| 
								 | 
							
											t.Errorf("unexpected key in result. %q", k)
							 | 
						||
| 
								 | 
							
											continue
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										if sec != expectedSec {
							 | 
						||
| 
								 | 
							
											t.Errorf("incorrect secret in result for key %q. expected %q got %q ", k, expectedSec, sec)
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func TestParseKeyFileErrors(t *testing.T) {
							 | 
						||
| 
								 | 
							
									tests := []struct {
							 | 
						||
| 
								 | 
							
										in  string
							 | 
						||
| 
								 | 
							
										err string
							 | 
						||
| 
								 | 
							
									}{
							 | 
						||
| 
								 | 
							
										{in: `key {`, err: "expected key name \"key {\""},
							 | 
						||
| 
								 | 
							
										{in: `foo "key" {`, err: "unexpected token \"foo\""},
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											in: `key "foo" {
							 | 
						||
| 
								 | 
							
										secret "36eowrtmxceNA3T5AdE+JNUOWFCw3amtcyHACnrDVgQ=";
							 | 
						||
| 
								 | 
							
									};
							 | 
						||
| 
								 | 
							
										key "foo" {
							 | 
						||
| 
								 | 
							
										secret "X28hl0BOfAL5G0jsmJWSacrwn7YRm2f6U5brnzwWEus=";
							 | 
						||
| 
								 | 
							
									}; `,
							 | 
						||
| 
								 | 
							
											err: "key \"foo.\" redefined",
							 | 
						||
| 
								 | 
							
										},
							 | 
						||
| 
								 | 
							
										{in: `key "foo" {
							 | 
						||
| 
								 | 
							
									schmalgorithm hmac-sha256;`,
							 | 
						||
| 
								 | 
							
											err: "unexpected token \"schmalgorithm\"",
							 | 
						||
| 
								 | 
							
										},
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											in: `key "foo" {
							 | 
						||
| 
								 | 
							
									schmecret "36eowrtmxceNA3T5AdE+JNUOWFCw3amtcyHACnrDVgQ=";`,
							 | 
						||
| 
								 | 
							
											err: "unexpected token \"schmecret\"",
							 | 
						||
| 
								 | 
							
										},
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											in: `key "foo" {
							 | 
						||
| 
								 | 
							
									secret`,
							 | 
						||
| 
								 | 
							
											err: "expected secret key \"\\tsecret\"",
							 | 
						||
| 
								 | 
							
										},
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											in: `key "foo" {
							 | 
						||
| 
								 | 
							
									secret ;`,
							 | 
						||
| 
								 | 
							
											err: "expected secret key \"\\tsecret ;\"",
							 | 
						||
| 
								 | 
							
										},
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											in: `key "foo" {
							 | 
						||
| 
								 | 
							
									};`,
							 | 
						||
| 
								 | 
							
											err: "expected secret for key \"foo.\"",
							 | 
						||
| 
								 | 
							
										},
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									for i, testcase := range tests {
							 | 
						||
| 
								 | 
							
										_, err := parseKeyFile(strings.NewReader(testcase.in))
							 | 
						||
| 
								 | 
							
										if err == nil {
							 | 
						||
| 
								 | 
							
											t.Errorf("Test %d: expected error, got no error", i)
							 | 
						||
| 
								 | 
							
											continue
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										if err.Error() != testcase.err {
							 | 
						||
| 
								 | 
							
											t.Errorf("Test %d: Expected error: %q, got %q", i, testcase.err, err.Error())
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 |