diff --git a/checker/checker.go b/checker/checker.go index a094070..5d510aa 100644 --- a/checker/checker.go +++ b/checker/checker.go @@ -19,7 +19,6 @@ import ( const ( DEFAULT_RESOLVER = "2a01:e0a:2b:2250::1" - year68 = 1 << 31 // For RFC1982 (Serial Arithmetic) calculations in 32 bits. Taken from miekg/dns ) var verbose = false @@ -89,11 +88,9 @@ func check_dns(domain, ip string) (aaaa net.IP, err error) { 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 { @@ -105,168 +102,6 @@ func check_dns(domain, ip string) (aaaa net.IP, err error) { return } -func check_dnssec(domain, ip string) (err error) { - client := dns.Client{Net: "tcp", Timeout: time.Second * 10} - - // Get DNSKEY - m := new(dns.Msg) - m.SetEdns0(4096, true) - m.SetQuestion(domain, dns.TypeDNSKEY) - - var r *dns.Msg - r, _, err = client.Exchange(m, fmt.Sprintf("[%s]:53", ip)) - if err != nil { - return - } - - if r == nil { - return errors.New("response is nil") - } - if r.Rcode != dns.RcodeSuccess { - return errors.New("failed to get a valid answer when getting DNSKEY") - } - - var rrs []dns.RR - var dnskeys []*dns.DNSKEY - var dnskeysig *dns.RRSIG - for _, answer := range r.Answer { - if t, ok := answer.(*dns.DNSKEY); ok { - dnskeys = append(dnskeys, t) - rrs = append(rrs, dns.RR(t)) - } else if t, ok := answer.(*dns.RRSIG); ok { - dnskeysig = t - } - } - - if dnskeysig == nil { - return fmt.Errorf("Unable to verify DNSKEY record signature: No RRSIG found for DNSKEY record.") - } - - found := false - for _, dnskey := range dnskeys { - if err = dnskeysig.Verify(dnskey, rrs); err == nil { - found = true - break - } - } - - if !found { - return fmt.Errorf("Unable to verify DNSKEY record signature: %w", err) - } - - // Check AAAA validity - m = new(dns.Msg) - m.SetEdns0(4096, true) - m.SetQuestion(domain, dns.TypeAAAA) - - r, _, err = client.Exchange(m, fmt.Sprintf("[%s]:53", ip)) - if err != nil { - return - } - - if r == nil { - return errors.New("response is nil") - } - if r.Rcode != dns.RcodeSuccess { - return errors.New("failed to get a valid answer when getting AAAA records") - } - - rrs = []dns.RR{} - var aaaas []*dns.AAAA - var aaaasig *dns.RRSIG - for _, answer := range r.Answer { - if t, ok := answer.(*dns.AAAA); ok { - aaaas = append(aaaas, t) - rrs = append(rrs, t) - } else if t, ok := answer.(*dns.RRSIG); ok { - aaaasig = t - } - } - - if len(aaaas) == 0 { - return errors.New("Something odd happen: no AAAA record found.") - } - - if aaaasig == nil { - return fmt.Errorf("Unable to verify AAAA record signature: No RRSIG found for AAAA record.") - } - - found = false - for _, dnskey := range dnskeys { - if err = aaaasig.Verify(dnskey, rrs); err == nil { - found = true - - if !aaaasig.ValidityPeriod(time.Now()) { - utc := time.Now().UTC().Unix() - - modi := (int64(aaaasig.Inception) - utc) / year68 - ti := int64(aaaasig.Inception) + modi*year68 - - mode := (int64(aaaasig.Expiration) - utc) / year68 - te := int64(aaaasig.Expiration) + mode*year68 - - if ti > utc { - return fmt.Errorf("Unable to verify AAAA record signature: signature not yet valid") - } else if utc > te { - return fmt.Errorf("Unable to verify AAAA record signature: signature expired") - } else { - return fmt.Errorf("Unable to verify AAAA record signature: signature expired or not yet valid") - } - } - - break - } - } - - if !found { - return fmt.Errorf("Unable to verify AAAA record signature: %w", err) - } - - // Check DS - m = new(dns.Msg) - m.SetQuestion(domain, dns.TypeDS) - m.RecursionDesired = false - m.SetEdns0(4096, true) - - r, _, err = client.Exchange(m, "[2a01:e0a:2b:2250::b]:53") - if err != nil { - return - } - - if r == nil { - return errors.New("response is nil") - } - if r.Rcode != dns.RcodeSuccess { - return errors.New("failed to get a valid answer when getting DS records in parent server") - } - - found = false - for _, answer := range r.Answer { - if t, ok := answer.(*dns.DS); ok { - for _, dnskey := range dnskeys { - expectedDS := dnskey.ToDS(dns.SHA256) - if expectedDS.KeyTag == t.KeyTag && expectedDS.Algorithm == t.Algorithm && expectedDS.DigestType == t.DigestType && expectedDS.Digest == t.Digest { - found = true - err = nil - break - } else { - err = fmt.Errorf("DS record found in parent zone differs from DNSKEY %v vs. %v.", expectedDS, t) - } - } - } - } - - if !found { - if err == nil { - return fmt.Errorf("Unable to find a valid DS record in parent zone.") - } else { - return err - } - } - - return -} - // PORT 80 func check_http(ip, dn string) (err error) { @@ -335,7 +170,6 @@ func check_https(domain, ip string) (err error) { type matrix_result struct { WellKnownResult struct { - Server string `json:"m.server"` Result string `json:"result"` } DNSResult struct { @@ -353,7 +187,7 @@ type matrix_result struct { Name string `json:"name"` Version string `json:"version"` } - FederationOK bool `json:"FederationOK"` + FederationOK bool } func check_matrix(domain string) (version string, err error) { @@ -365,16 +199,16 @@ func check_matrix(domain string) (version string, err error) { defer resp.Body.Close() if resp.StatusCode >= 300 { - return "", fmt.Errorf("Sorry, the federation tester is broken. Check on https://federationtester.matrix.org/#%s", strings.TrimSuffix(domain, ".")) + return "", fmt.Errorf("Sorry, the federation tester is broken. Check on https://federationtester.matrix.org/#%s", domain) } var federationTest matrix_result - if err = json.NewDecoder(resp.Body).Decode(&federationTest); err != nil { - log.Printf("Error in check_matrix, when decoding json: %w", err.Error()) - return "", fmt.Errorf("Sorry, the federation tester is broken. Check on https://federationtester.matrix.org/#%s", strings.TrimSuffix(domain, ".")) - } else if federationTest.FederationOK { + if federationTest.FederationOK { version = federationTest.Version.Name + " " + federationTest.Version.Version return version, nil + } else if err = json.NewDecoder(resp.Body).Decode(&federationTest); err != nil { + log.Printf("Error in chech_matrix, when decoding json:", err.Error()) + return "", fmt.Errorf("Sorry, the federation tester is broken. Check on https://federationtester.matrix.org/#%s", domain) } else if federationTest.DNSResult.SRVError != nil && federationTest.WellKnownResult.Result != "" { return "", fmt.Errorf("%s OR %s", federationTest.DNSResult.SRVError.Message, federationTest.WellKnownResult.Result) } else if len(federationTest.ConnectionErrors) > 0 { @@ -388,10 +222,8 @@ func check_matrix(domain string) (version string, err error) { msg.WriteString(cerr.Message) } return "", fmt.Errorf("Connection errors: %s", msg.String()) - } else if federationTest.WellKnownResult.Server != strings.TrimSuffix(domain, ".") { - return "", fmt.Errorf("Bad homeserver_name: got %s, expected %s.", federationTest.WellKnownResult.Server, strings.TrimSuffix(domain, ".")) } else { - return "", fmt.Errorf("An unimplemented error occurs. Please report to nemunaire. But know that federation seems to be broken. Check https://federationtester.matrix.org/#%s", strings.TrimSuffix(domain, ".")) + return "", fmt.Errorf("An unimplemented error occurs. Please report to nemunaire. But know that federation seems to be broken. Check https://federationtester.matrix.org/#%s", domain) } } @@ -516,7 +348,7 @@ func studentsChecker() { } } - // Check Matrix (only if GLUE Ok and defer contraint) + // Check Matrix (only if GLUE Ok and) if glueErr == nil && istd%10 == check_matrix_for { if v, err := check_matrix(std.MyDelegatedDomain()); err == nil { if verbose { @@ -532,23 +364,6 @@ func studentsChecker() { } } } - - // Check DNSSEC (only if GLUE Ok) - if glueErr == nil { - if err := check_dnssec(std.MyDelegatedDomain(), dnsIP); err == nil { - if verbose { - log.Printf("%s just unlocked DNSSEC challenge\n", std.Login) - } - if _, err := std.UnlockChallenge(100*(tunnel_version-1)+7, ""); err != nil { - log.Printf("Unable to register challenge for %s: %s\n", std.Login, err.Error()) - } - } else { - std.RegisterChallengeError(100*(tunnel_version-1)+7, err) - if verbose { - log.Printf("%s and DNSSEC: %s\n", std.Login, err) - } - } - } } } else { if errreg := std.RegisterChallengeError(100*(tunnel_version-1)+3, err); errreg != nil { diff --git a/token-validator/check.go b/token-validator/check.go index c9e0ddc..722e54f 100644 --- a/token-validator/check.go +++ b/token-validator/check.go @@ -29,7 +29,7 @@ func init() { } func check_GLUE_respond(student *adlin.Student, domain string, ip string) (err error) { if !strings.HasPrefix(ip, adlin.StudentIP(student.Id).String()) { - return fmt.Errorf("%q is not your IP range", ip) + return fmt.Errorf("%q is not your IP range") } client := dns.Client{Net: "tcp", Timeout: time.Second * 5} diff --git a/token-validator/domain.go b/token-validator/domain.go index 37ecb26..596f3bd 100644 --- a/token-validator/domain.go +++ b/token-validator/domain.go @@ -205,17 +205,17 @@ func parseZoneRead(globalDomain string, domain string) (rr []Entry, err error) { for _, r := range response.RR { if strings.HasSuffix(r.Header().Name, domain) { - z := []string{} + var z string if v, ok := r.(*dns.A); ok { - z = append(z, fmt.Sprintf("%s", v.A)) + z = fmt.Sprintf("%s", v.A) } else if v, ok := r.(*dns.AAAA); ok { - z = append(z, fmt.Sprintf("%s", v.AAAA)) + z = fmt.Sprintf("%s", v.AAAA) } else if v, ok := r.(*dns.NS); ok { - z = append(z, fmt.Sprintf("%s", v.Ns)) + z = fmt.Sprintf("%s", v.Ns) } else if v, ok := r.(*dns.DS); ok { - z = append(z, fmt.Sprintf("%d", v.KeyTag), fmt.Sprintf("%d", v.Algorithm), fmt.Sprintf("%d", v.DigestType), fmt.Sprintf("%s", v.Digest)) + z = fmt.Sprintf("%s", v.Digest) } - rr = append(rr, Entry{r.Header().Name, r.Header().Ttl, dns.TypeToString[r.Header().Rrtype], "", z}) + rr = append(rr, Entry{r.Header().Name, r.Header().Ttl, dns.TypeToString[r.Header().Rrtype], "", []string{z}}) } } } @@ -260,7 +260,7 @@ func delAssociatedDomains(student *adlin.Student, dn string) (err error) { m1.Id = dns.Id() m1.Opcode = dns.OpcodeUpdate m1.Question = make([]dns.Question, 1) - m1.Question[0] = dns.Question{Name: adlin.AssociatedDomainSuffix, Qtype: dns.TypeSOA, Qclass: dns.ClassINET} + m1.Question[0] = dns.Question{adlin.AssociatedDomainSuffix, dns.TypeSOA, dns.ClassINET} var rrs []dns.RR for _, domain := range adomains { @@ -302,7 +302,7 @@ func AddAssociatedDomains(student *adlin.Student, aaaa net.IP) (err error) { m2.Id = dns.Id() m2.Opcode = dns.OpcodeUpdate m2.Question = make([]dns.Question, 1) - m2.Question[0] = dns.Question{Name: adlin.AssociatedDomainSuffix, Qtype: dns.TypeSOA, Qclass: dns.ClassINET} + m2.Question[0] = dns.Question{adlin.AssociatedDomainSuffix, dns.TypeSOA, dns.ClassINET} rrA := new(dns.A) rrA.Hdr = dns.RR_Header{Name: student.DefaultAssociatedDomain(), Rrtype: dns.TypeA, Class: dns.ClassINET, Ttl: 3600} @@ -354,7 +354,7 @@ func AddNSDelegatedDomain(student *adlin.Student, dn string, ttl uint32, ns stri m1.Id = dns.Id() m1.Opcode = dns.OpcodeUpdate m1.Question = make([]dns.Question, 1) - m1.Question[0] = dns.Question{Name: adlin.DelegatedDomainSuffix, Qtype: dns.TypeSOA, Qclass: dns.ClassINET} + m1.Question[0] = dns.Question{adlin.DelegatedDomainSuffix, dns.TypeSOA, dns.ClassINET} rrNS := new(dns.NS) rrNS.Hdr = dns.RR_Header{Name: d, Rrtype: dns.TypeNS, Class: dns.ClassINET, Ttl: ttl} @@ -377,7 +377,7 @@ func UpdateNSDelegatedDomain(student *adlin.Student, dn string, ttl uint32, oldn m1.Id = dns.Id() m1.Opcode = dns.OpcodeUpdate m1.Question = make([]dns.Question, 1) - m1.Question[0] = dns.Question{Name: adlin.DelegatedDomainSuffix, Qtype: dns.TypeSOA, Qclass: dns.ClassINET} + m1.Question[0] = dns.Question{adlin.DelegatedDomainSuffix, dns.TypeSOA, dns.ClassINET} rrOldNS := new(dns.NS) rrOldNS.Hdr = dns.RR_Header{Name: d, Rrtype: dns.TypeNS, Class: dns.ClassINET} @@ -417,7 +417,7 @@ func AddGLUEDelegatedDomain(student *adlin.Student, dn string, ttl uint32, aaaa m1.Id = dns.Id() m1.Opcode = dns.OpcodeUpdate m1.Question = make([]dns.Question, 1) - m1.Question[0] = dns.Question{Name: adlin.DelegatedDomainSuffix, Qtype: dns.TypeSOA, Qclass: dns.ClassINET} + m1.Question[0] = dns.Question{adlin.DelegatedDomainSuffix, dns.TypeSOA, dns.ClassINET} var rr dns.RR rr, err = dns.NewRR(fmt.Sprintf("%s %d IN AAAA %s", dn, ttl, aaaa)) @@ -453,7 +453,7 @@ func UpdateGLUEDelegatedDomain(student *adlin.Student, dn string, ttl uint32, ol m1.Id = dns.Id() m1.Opcode = dns.OpcodeUpdate m1.Question = make([]dns.Question, 1) - m1.Question[0] = dns.Question{Name: adlin.DelegatedDomainSuffix, Qtype: dns.TypeSOA, Qclass: dns.ClassINET} + m1.Question[0] = dns.Question{adlin.DelegatedDomainSuffix, dns.TypeSOA, dns.ClassINET} var rr dns.RR @@ -509,7 +509,7 @@ func AddDSDelegatedDomain(student *adlin.Student, dn string, ttl uint32, rdata s m1.Id = dns.Id() m1.Opcode = dns.OpcodeUpdate m1.Question = make([]dns.Question, 1) - m1.Question[0] = dns.Question{Name: adlin.DelegatedDomainSuffix, Qtype: dns.TypeSOA, Qclass: dns.ClassINET} + m1.Question[0] = dns.Question{adlin.DelegatedDomainSuffix, dns.TypeSOA, dns.ClassINET} var ds *dns.DS ds = dnskey.ToDS(dns.SHA256) @@ -545,7 +545,7 @@ func DeleteRRDelegatedDomain(student *adlin.Student, dn string, rr string, value m1.Id = dns.Id() m1.Opcode = dns.OpcodeUpdate m1.Question = make([]dns.Question, 1) - m1.Question[0] = dns.Question{Name: adlin.DelegatedDomainSuffix, Qtype: dns.TypeSOA, Qclass: dns.ClassINET} + m1.Question[0] = dns.Question{adlin.DelegatedDomainSuffix, dns.TypeSOA, dns.ClassINET} rrr, errr := dns.NewRR(fmt.Sprintf("%s %s %s", dn, rr, strings.Join(values, " "))) if errr != nil { diff --git a/token-validator/htdocs/dashboard.html b/token-validator/htdocs/dashboard.html index 5999dd3..8783eb6 100644 --- a/token-validator/htdocs/dashboard.html +++ b/token-validator/htdocs/dashboard.html @@ -104,11 +104,11 @@
- {{ stats[ch].warning * 100 / stats.total | number:0 }} % + {{ stats[ch].warning * 100 / stats.total | number:0 }} %
-
+