package main import ( "encoding/json" "errors" "fmt" "io/ioutil" "log" "net" "net/http" "strings" "time" "github.com/go-ping/ping" "github.com/miekg/dns" ) const ( DEFAULT_RESOLVER = "2a01:e0a:2b:2250::1" ) var ( verbose = false test_name = "" ) // ICMP func check_ping(ip string, cb func(pkt *ping.Packet)) (err error) { var pinger *ping.Pinger pinger, err = ping.NewPinger(ip) if err != nil { return } defer pinger.Stop() pinger.Timeout = time.Second * 5 pinger.Count = 1 pinger.OnRecv = cb pinger.SetPrivileged(true) pinger.Run() return } func check_dns(domain, ip string) (aaaa net.IP, err error) { client := dns.Client{Timeout: time.Second * 5} m := new(dns.Msg) m.SetQuestion(domain, dns.TypeAAAA) var r *dns.Msg r, _, err = client.Exchange(m, fmt.Sprintf("[%s]:53", ip)) if err != nil { return } if r == nil { err = errors.New("response is nil") return } if r.Rcode != dns.RcodeSuccess { err = errors.New("failed to get a valid answer") return } for _, answer := range r.Answer { if t, ok := answer.(*dns.AAAA); ok { aaaa = t.AAAA } } return } // PORT 80 func check_http(ip, dn string) (err error) { client := &http.Client{ CheckRedirect: func(req *http.Request, via []*http.Request) error { return http.ErrUseLastResponse }, } req, errr := http.NewRequest("GET", fmt.Sprintf("http://[%s]/", ip), nil) if errr != nil { return errr } if dn != "" { req.Header.Add("Host", strings.TrimSuffix(dn, ".")) } var resp *http.Response resp, err = client.Do(req) if err != nil { return } defer resp.Body.Close() if dn != "" && resp.StatusCode >= 400 { return fmt.Errorf("Bad status, got: %d (%s)", resp.StatusCode, resp.Status) } _, err = ioutil.ReadAll(resp.Body) return } // PORT 443 func check_https(domain, ip string) (err error) { var resp *http.Response resp, err = http.Get(fmt.Sprintf("https://%s/", strings.TrimSuffix(domain, "."))) if err != nil { return } defer resp.Body.Close() if resp.StatusCode >= 300 && resp.StatusCode < 400 { loc := resp.Header.Get("Location") if loc != "" && strings.HasSuffix(dns.Fqdn(loc), domain) { if dns.Fqdn(loc) == domain { return fmt.Errorf("Redirection loop %s redirect to %s", domain, loc) } else if err = check_https(dns.Fqdn(loc), ip); err != nil { return fmt.Errorf("Error after following redirection to %s: %w", loc, err) } else { return } } } if resp.StatusCode >= 300 { return fmt.Errorf("Bad status, got: %d (%s)", resp.StatusCode, resp.Status) } _, err = ioutil.ReadAll(resp.Body) return } func wksChecker() { if collectorpubkey == nil { var err error if collectorpubkey, err = getCollectorPublicKey(); err != nil { log.Println("Contact collector:", err) return } } data, err := encodeData(SendMeta{Login: Login}, map[string]*string{ test_name: nil, }) if err != nil { log.Println("Unable to encode message:", err) return } err = sendData(data) if err != nil { log.Println("Unable to send message:", err) return } v, _ := json.Marshal(data) if verbose { log.Printf("sent %s", v) } return }