55 "fmt"
66 "net"
77 "regexp"
8+ "strconv"
89 "strings"
910 "time"
1011
@@ -19,6 +20,13 @@ const (
1920func shouldRespondToNameResolutionQuery (config * Config , host string , queryType uint16 ,
2021 from net.IP , fromHostnames []string , handlerType HandlerType ,
2122) (bool , string ) {
23+ var hostWithService string
24+
25+ if queryType == dns .TypeSRV {
26+ hostWithService = host
27+ host = removeServiceAndPort (host )
28+ }
29+
2230 if config .spoofingTemporarilyDisabled {
2331 return false , "spoofing is temporarily disabled"
2432 }
@@ -63,7 +71,13 @@ func shouldRespondToNameResolutionQuery(config *Config, host string, queryType u
6371 }
6472
6573 if ! config .SpoofTypes .ShouldSpoof (queryType ) {
66- return false , fmt .Sprintf ("type %s is not in spoof-types" , dnsQueryType (queryType ))
74+ return false , fmt .Sprintf ("type %s is not in spoof-types list" , dnsQueryType (queryType ))
75+ }
76+
77+ if queryType == dns .TypeSRV && ! config .SpoofSRV .Contains (hostWithService ) {
78+ service , _ , _ := strings .Cut (hostWithService , "." )
79+
80+ return false , fmt .Sprintf ("service %s is not in spoof-srv list" , strings .TrimPrefix (service , "_" ))
6781 }
6882
6983 switch {
@@ -369,3 +383,104 @@ func starToRegex(s string) (*regexp.Regexp, error) {
369383
370384 return regexp .Compile ("^" + starReplacerRE .ReplaceAllString (regexp .QuoteMeta (s ), ".*" ) + "$" )
371385}
386+
387+ type srvMatchers []* srvMatcher
388+
389+ func asSRVMatchers (matcherStrings []string ) (srvMatchers , error ) {
390+ matchers := make (srvMatchers , 0 , len (matcherStrings ))
391+
392+ for _ , m := range matcherStrings {
393+ matcher := & srvMatcher {
394+ Service : strings .ToLower (m ),
395+ }
396+
397+ switch strings .Count (matcher .Service , ":" ) {
398+ case 0 :
399+ matcher .isDefaultPort = true
400+
401+ switch matcher .Service {
402+ case "ldap" :
403+ matcher .Port = 389
404+ case "ldaps" :
405+ matcher .Port = 636
406+ case "http" :
407+ matcher .Port = 80
408+ case "https" :
409+ matcher .Port = 443
410+ case "kerberos" :
411+ matcher .Port = 88
412+ default :
413+ return nil , fmt .Errorf ("missing port in service: %q" , m )
414+ }
415+
416+ matchers = append (matchers , matcher )
417+ case 1 :
418+ service , portStr , found := strings .Cut (m , ":" )
419+ if ! found {
420+ return nil , fmt .Errorf ("cannot parse service: %q" , m )
421+ }
422+
423+ port , err := strconv .Atoi (portStr )
424+ if err != nil {
425+ return nil , fmt .Errorf ("parse port %q in service %q" , portStr , m )
426+ }
427+
428+ matchers = append (matchers , & srvMatcher {Service : strings .ToLower (service ), Port : uint16 (port )}) //nolint:gosec
429+ default :
430+ return nil , fmt .Errorf ("SRV matcher contains more than one colon: %q" , m )
431+ }
432+ }
433+
434+ return matchers , nil
435+ }
436+
437+ func (matchers srvMatchers ) Contains (service string ) bool {
438+ service , _ , _ = strings .Cut (service , "." )
439+
440+ for _ , m := range matchers {
441+ if m .Matches (service ) {
442+ return true
443+ }
444+ }
445+
446+ return false
447+ }
448+
449+ func (matchers srvMatchers ) String () string {
450+ elements := make ([]string , 0 , len (matchers ))
451+
452+ for _ , m := range matchers {
453+ switch {
454+ case m .isDefaultPort :
455+ elements = append (elements , m .Service )
456+ default :
457+ elements = append (elements , fmt .Sprintf ("%s:%d" , m .Service , m .Port ))
458+ }
459+ }
460+
461+ return strings .Join (elements , ", " )
462+ }
463+
464+ func (matchers srvMatchers ) Get (service string ) * srvMatcher {
465+ service , _ , _ = strings .Cut (service , "." )
466+
467+ for _ , m := range matchers {
468+ if m .Matches (service ) {
469+ return m
470+ }
471+ }
472+
473+ return nil
474+ }
475+
476+ type srvMatcher struct {
477+ Service string
478+ Port uint16
479+ isDefaultPort bool
480+ }
481+
482+ func (sm * srvMatcher ) Matches (service string ) bool {
483+ service , _ , _ = strings .Cut (service , "." )
484+
485+ return strings .EqualFold (strings .TrimPrefix (sm .Service , "_" ), strings .TrimPrefix (service , "_" ))
486+ }
0 commit comments