awl/cli/misc.go
Sam Therapy eda2e5b55f
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
More work!
Signed-off-by: Sam Therapy <sam@samtherapy.net>
2022-07-22 23:22:43 +02:00

150 lines
4.2 KiB
Go

// SPDX-License-Identifier: BSD-3-Clause
package cli
import (
"fmt"
"math/rand"
"strings"
"git.froth.zone/sam/awl/conf"
"git.froth.zone/sam/awl/util"
"github.com/miekg/dns"
"golang.org/x/net/idna"
)
// Parse the wildcard arguments, drill style.
func ParseMiscArgs(args []string, opts *Options) error {
var err error
for _, arg := range args {
r, ok := dns.StringToType[strings.ToUpper(arg)]
switch {
// If it starts with @, it's a DNS server
case strings.HasPrefix(arg, "@"):
arg = arg[1:]
// Automatically set flags based on URI header
opts.Logger.Info(arg, "detected as a server")
switch {
case strings.HasPrefix(arg, "tls://"):
opts.TLS = true
opts.Request.Server = arg[6:]
opts.Logger.Info("DNS-over-TLS implicitly set")
case strings.HasPrefix(arg, "https://"):
opts.HTTPS = true
opts.Request.Server = arg
opts.Logger.Info("DNS-over-HTTPS implicitly set")
case strings.HasPrefix(arg, "quic://"):
opts.QUIC = true
opts.Request.Server = arg[7:]
opts.Logger.Info("DNS-over-QUIC implicitly set.")
case strings.HasPrefix(arg, "sdns://"):
opts.DNSCrypt = true
opts.Request.Server = arg
opts.Logger.Info("DNSCrypt implicitly set")
default:
opts.Request.Server = arg
}
case strings.Contains(arg, "."):
opts.Logger.Info(arg, "detected as a domain name")
opts.Request.Name, err = idna.ToASCII(arg)
if err != nil {
return err
}
case ok:
opts.Logger.Info(arg, "detected as a type")
// If it's a DNS request, it's a DNS request (obviously)
opts.Request.Type = r
case strings.HasPrefix(arg, "+"):
opts.Logger.Info(arg, "detected as a dig query")
// Dig-style +queries
err = ParseDig(strings.ToLower(arg[1:]), opts)
if err != nil {
return err
}
default:
opts.Logger.Info(arg, "is unknown. Assuming domain")
opts.Request.Name, err = idna.ToASCII(arg)
if err != nil {
return err
}
}
}
// If nothing was set, set a default
if opts.Request.Name == "" {
opts.Logger.Info("Domain not specified, making a default")
opts.Request.Name = "."
if opts.Request.Type == 0 {
opts.Request.Type = dns.StringToType["NS"]
}
} else {
opts.Logger.Info("Query not specified, making an \"A\" query")
if opts.Request.Type == 0 {
opts.Request.Type = dns.StringToType["A"]
}
}
//
if opts.Request.Server == "" {
opts.Logger.Info("Server not specified, selecting a default")
// Set "defaults" for each if there is no input
switch {
case opts.DNSCrypt:
// This is adguard
opts.Request.Server = "sdns://AQMAAAAAAAAAETk0LjE0MC4xNC4xNDo1NDQzINErR_JS3PLCu_iZEIbq95zkSV2LFsigxDIuUso_OQhzIjIuZG5zY3J5cHQuZGVmYXVsdC5uczEuYWRndWFyZC5jb20"
case opts.TLS:
opts.Request.Server = "dns.google"
case opts.HTTPS:
opts.Request.Server = "https://dns.cloudflare.com/dns-query"
case opts.QUIC:
opts.Request.Server = "dns.adguard.com"
default:
resolv, err := conf.GetDNSConfig()
if err != nil {
// :^)
opts.Logger.Error("Could not query system for server. Using default")
opts.Request.Server = "95.216.99.249"
} else {
// Make sure that if IPv4 or IPv6 is asked for it actually uses it
for _, srv := range resolv.Servers {
if opts.IPv4 {
if strings.Contains(srv, ".") {
opts.Request.Server = srv
break
}
} else if opts.IPv6 {
if strings.Contains(srv, ":") {
opts.Request.Server = srv
break
}
} else {
//#nosec -- This isn't used for anything secure
opts.Request.Server = resolv.Servers[rand.Intn(len(resolv.Servers))]
break
}
}
}
}
}
opts.Logger.Info("DNS server set to", opts.Request.Server)
// Make reverse adresses proper addresses
if opts.Reverse {
opts.Logger.Info("Making reverse DNS query proper *.arpa domain")
if dns.TypeToString[opts.Request.Type] == "A" {
opts.Request.Type = dns.StringToType["PTR"]
}
opts.Request.Name, err = util.ReverseDNS(opts.Request.Name, opts.Request.Type)
if err != nil {
return err
}
}
// if the domain is not canonical, make it canonical
if !strings.HasSuffix(opts.Request.Name, ".") {
opts.Request.Name = fmt.Sprintf("%s.", opts.Request.Name)
opts.Logger.Debug("Domain made canonical")
}
return nil
}