From 840d58e8b07d8a15d32314e47196a5be81fd8c10 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Sun, 31 Oct 2021 18:16:58 +0100 Subject: [PATCH] checker: Can call checker with a list of students to one-check --- checker/checker.go | 446 +++++++++++++++++++++++---------------------- checker/main.go | 19 +- 2 files changed, 243 insertions(+), 222 deletions(-) diff --git a/checker/checker.go b/checker/checker.go index f7bbf16..df1eb19 100644 --- a/checker/checker.go +++ b/checker/checker.go @@ -559,6 +559,230 @@ func minTunnelVersion(std *adlin.Student, suffixip int) (int, error) { return minversion, nil } +func studentChecker(std *adlin.Student, also_check_matrix bool) { + tuns, err := std.GetActivesTunnels() + if err != nil { + if verbose2 { + log.Printf("SKip %s due to error when getting active tunnels: %s", std.Login, err.Error()) + } + return + } + if verbose2 && len(tuns) == 0 { + log.Printf("%s has no active tunnels: %s", std.Login, err.Error()) + } + + for _, tun := range tuns { + stdIP := tun.GetStudentIP() + if verbose2 { + log.Printf("Tests %s on %s...", std.Login, stdIP) + } + // Check ping + check_ping(stdIP, func(pkt *ping.Packet) { + tunnel_version, err := minTunnelVersion(std, tun.SuffixIP) + if verbose { + log.Printf("%s PONG (on %x); version=%d (%v)\n", std.Login, tun.SuffixIP, tunnel_version, err) + } + std.OnPong(true) + + if tunnel_version == 2147483647 || tunnel_version == 0 { + log.Printf("%s unknown tunnel version: %d skipping tests (%v)", std.Login, tunnel_version, err) + return + } + + // PingResolver + if tunnel_version == 3 { + tmp := strings.Split(stdIP, ":") + tmp[len(tmp)-1] = "2" + stdResolverIP := strings.Join(tmp, ":") + go check_ping(stdResolverIP, func(_ *ping.Packet) { + if verbose { + log.Printf("%s resolver PONG", std.Login) + } + if _, err := std.UnlockChallenge(CheckMap[tunnel_version][PingResolver], ""); err != nil { + log.Printf("Unable to register challenge for %s: %s\n", std.Login, err.Error()) + } + }) + } + + dnsIP := stdIP + var glueErr error + // Is GLUE defined? + if glueIP, err := get_GLUE(std.MyDelegatedDomain()); glueIP != nil { + dnsIP = glueIP.String() + + if verbose { + log.Printf("%s has defined GLUE: %s\n", std.Login, dnsIP) + } + } else if err != nil { + log.Printf("%s and GLUE: %s\n", std.Login, err) + glueErr = err + } + + // Check DNS + if addr, err := check_dns(std.MyDelegatedDomain(), dnsIP); err == nil { + if addr == nil { + dnsAt := " at " + dnsIP + if glueErr != nil { + dnsAt = " + there is a problem with the GLUE record: " + glueErr.Error() + } + if errreg := std.RegisterChallengeError(CheckMap[tunnel_version][DNSDelegation], fmt.Errorf("%s: empty response from the server%s", std.MyDelegatedDomain(), dnsAt)); errreg != nil { + log.Printf("Unable to register challenge error for %s: %s\n", std.Login, errreg) + } + } else { + if verbose { + log.Printf("%s just unlocked DNS challenge\n", std.Login) + } + if _, err := std.UnlockChallenge(CheckMap[tunnel_version][DNSDelegation], addr.String()); err != nil { + log.Printf("Unable to register challenge for %s: %s\n", std.Login, err.Error()) + } + + // Check HTTP with DNS + if glueErr != nil { + std.RegisterChallengeError(CheckMap[tunnel_version][HTTPonDelegatedDomain], fmt.Errorf("Unable to perform the test due to GLUE problem: %w", glueErr)) + } else if err := check_http(addr.String(), std.MyDelegatedDomain()); err == nil { + if verbose { + log.Printf("%s just unlocked HTTP challenge\n", std.Login) + } + if _, err := std.UnlockChallenge(CheckMap[tunnel_version][HTTPonDelegatedDomain], ""); err != nil { + log.Printf("Unable to register challenge for %s: %s\n", std.Login, err.Error()) + } + } else { + std.RegisterChallengeError(CheckMap[tunnel_version][HTTPonDelegatedDomain], err) + if verbose { + log.Printf("%s and HTTP (with DNS ip=%s): %s\n", std.Login, addr.String(), err) + } + } + + // Check HTTPs with DNS + if glueErr != nil { + std.RegisterChallengeError(CheckMap[tunnel_version][HTTPSonDelegatedDomain], fmt.Errorf("Unable to perform the test due to GLUE problem: %w", glueErr)) + } else if err := check_https(std.MyDelegatedDomain(), addr.String()); err == nil { + if verbose { + log.Printf("%s just unlocked HTTPS challenge\n", std.Login) + } + if _, err := std.UnlockChallenge(CheckMap[tunnel_version][HTTPSonDelegatedDomain], ""); err != nil { + log.Printf("Unable to register challenge for %s: %s\n", std.Login, err.Error()) + } + } else { + std.RegisterChallengeError(CheckMap[tunnel_version][HTTPSonDelegatedDomain], err) + if verbose { + log.Printf("%s and HTTPS (with DNS ip=%s): %s\n", std.Login, addr.String(), err) + } + } + + // Check Matrix (only if GLUE Ok and defer contraint) + if glueErr == nil && also_check_matrix { + // Check Matrix Federation first + if v, err := check_matrix_federation(std.MyDelegatedDomain()); err == nil { + if verbose { + log.Printf("%s just unlocked Matrix federation challenge\n", std.Login) + } + if _, err := std.UnlockChallenge(CheckMap[tunnel_version][MatrixSrv], v); err != nil { + log.Printf("Unable to register challenge for %s: %s\n", std.Login, err.Error()) + } + } else { + std.RegisterChallengeError(CheckMap[tunnel_version][MatrixSrv], err) + if verbose { + log.Printf("%s and Matrix federation: %s\n", std.Login, err) + } + } + + // Check Matrix Client + if v, err := check_matrix_client(std.MyDelegatedDomain()); err == nil { + if verbose { + log.Printf("%s just unlocked Matrix client challenge\n", std.Login) + } + if _, err := std.UnlockChallenge(CheckMap[tunnel_version][MatrixClt], v); err != nil { + log.Printf("Unable to register challenge for %s: %s\n", std.Login, err.Error()) + } + } else { + std.RegisterChallengeError(CheckMap[tunnel_version][MatrixClt], err) + if verbose { + log.Printf("%s and Matrix client: %s\n", std.Login, err) + } + } + } + + // 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(CheckMap[tunnel_version][DNSSEC], ""); err != nil { + log.Printf("Unable to register challenge for %s: %s\n", std.Login, err.Error()) + } + } else { + std.RegisterChallengeError(CheckMap[tunnel_version][DNSSEC], err) + if verbose { + log.Printf("%s and DNSSEC: %s\n", std.Login, err) + } + } + } + } + } else { + if errreg := std.RegisterChallengeError(CheckMap[tunnel_version][DNSDelegation], err); errreg != nil { + log.Printf("Unable to register challenge error for %s: %s\n", std.Login, errreg) + } + if verbose { + log.Printf("%s and DNS: %s\n", std.Login, err) + } + } + + // Check HTTP without DNS + if err := check_http(stdIP, ""); err == nil { + if verbose { + log.Printf("%s just unlocked HTTP IP (without DNS) challenge\n", std.Login) + } + if _, err := std.UnlockChallenge(CheckMap[tunnel_version][HTTPonIP], ""); err != nil { + log.Printf("Unable to register challenge for %s: %s\n", std.Login, err.Error()) + } + } else { + std.RegisterChallengeError(CheckMap[tunnel_version][HTTPonIP], err) + if verbose { + log.Printf("%s and HTTP IP (without DNS): %s\n", std.Login, err) + } + } + + // Check DNS for association + if addr, err := check_dns(std.MyAssociatedDomain(), DEFAULT_RESOLVER); err == nil { + // Check HTTP on delegated domain + if err := check_http(addr.String(), std.MyAssociatedDomain()); err == nil { + if verbose { + log.Printf("%s just unlocked HTTP (without DNS) challenge\n", std.Login) + } + if _, err := std.UnlockChallenge(CheckMap[tunnel_version][HTTPonAssociatedDomain], ""); err != nil { + log.Printf("Unable to register challenge for %s: %s\n", std.Login, err.Error()) + } + } else { + std.RegisterChallengeError(CheckMap[tunnel_version][HTTPonAssociatedDomain], err) + if verbose { + log.Printf("%s and HTTP (without DNS): %s\n", std.Login, err) + } + } + + // Check HTTPs without DNS + if err := check_https(std.MyAssociatedDomain(), stdIP); err == nil { + if verbose { + log.Printf("%s just unlocked HTTPS challenge\n", std.Login) + } + if _, err := std.UnlockChallenge(CheckMap[tunnel_version][HTTPSonAssociatedDomain], ""); err != nil { + log.Printf("Unable to register challenge for %s: %s\n", std.Login, err.Error()) + } + } else { + std.RegisterChallengeError(CheckMap[tunnel_version][HTTPSonAssociatedDomain], err) + if verbose { + log.Printf("%s and HTTPS (without DNS): %s\n", std.Login, err) + } + } + } + + return + }) + } + +} + func studentsChecker() { students, err := adlin.GetStudents() if err != nil { @@ -571,226 +795,6 @@ func studentsChecker() { for istd, s := range students { time.Sleep(250 * time.Millisecond) - // Check ping - std := s - tuns, err := std.GetActivesTunnels() - if err != nil { - if verbose2 { - log.Printf("SKip %s due to error when getting active tunnels: %s", std.Login, err.Error()) - } - continue - } - if verbose2 && len(tuns) == 0 { - log.Printf("%s has no active tunnels: %s", std.Login, err.Error()) - } - - for _, tun := range tuns { - stdIP := tun.GetStudentIP() - if verbose2 { - log.Printf("Tests %s on %s...", std.Login, stdIP) - } - go check_ping(stdIP, func(pkt *ping.Packet) { - tunnel_version, err := minTunnelVersion(std, tun.SuffixIP) - if verbose { - log.Printf("%s PONG (on %x); version=%d (%v)\n", std.Login, tun.SuffixIP, tunnel_version, err) - } - std.OnPong(true) - - if tunnel_version == 2147483647 || tunnel_version == 0 { - log.Printf("%s unknown tunnel version: %d skipping tests (%v)", std.Login, tunnel_version, err) - return - } - - // PingResolver - if tunnel_version == 3 { - tmp := strings.Split(stdIP, ":") - tmp[len(tmp)-1] = "2" - stdResolverIP := strings.Join(tmp, ":") - go check_ping(stdResolverIP, func(_ *ping.Packet) { - if verbose { - log.Printf("%s resolver PONG", std.Login) - } - if _, err := std.UnlockChallenge(CheckMap[tunnel_version][PingResolver], ""); err != nil { - log.Printf("Unable to register challenge for %s: %s\n", std.Login, err.Error()) - } - }) - } - - dnsIP := stdIP - var glueErr error - // Is GLUE defined? - if glueIP, err := get_GLUE(std.MyDelegatedDomain()); glueIP != nil { - dnsIP = glueIP.String() - - if verbose { - log.Printf("%s has defined GLUE: %s\n", std.Login, dnsIP) - } - } else if err != nil { - log.Printf("%s and GLUE: %s\n", std.Login, err) - glueErr = err - } - - // Check DNS - if addr, err := check_dns(std.MyDelegatedDomain(), dnsIP); err == nil { - if addr == nil { - dnsAt := " at " + dnsIP - if glueErr != nil { - dnsAt = " + there is a problem with the GLUE record: " + glueErr.Error() - } - if errreg := std.RegisterChallengeError(CheckMap[tunnel_version][DNSDelegation], fmt.Errorf("%s: empty response from the server%s", std.MyDelegatedDomain(), dnsAt)); errreg != nil { - log.Printf("Unable to register challenge error for %s: %s\n", std.Login, errreg) - } - } else { - if verbose { - log.Printf("%s just unlocked DNS challenge\n", std.Login) - } - if _, err := std.UnlockChallenge(CheckMap[tunnel_version][DNSDelegation], addr.String()); err != nil { - log.Printf("Unable to register challenge for %s: %s\n", std.Login, err.Error()) - } - - // Check HTTP with DNS - if glueErr != nil { - std.RegisterChallengeError(CheckMap[tunnel_version][HTTPonDelegatedDomain], fmt.Errorf("Unable to perform the test due to GLUE problem: %w", glueErr)) - } else if err := check_http(addr.String(), std.MyDelegatedDomain()); err == nil { - if verbose { - log.Printf("%s just unlocked HTTP challenge\n", std.Login) - } - if _, err := std.UnlockChallenge(CheckMap[tunnel_version][HTTPonDelegatedDomain], ""); err != nil { - log.Printf("Unable to register challenge for %s: %s\n", std.Login, err.Error()) - } - } else { - std.RegisterChallengeError(CheckMap[tunnel_version][HTTPonDelegatedDomain], err) - if verbose { - log.Printf("%s and HTTP (with DNS ip=%s): %s\n", std.Login, addr.String(), err) - } - } - - // Check HTTPs with DNS - if glueErr != nil { - std.RegisterChallengeError(CheckMap[tunnel_version][HTTPSonDelegatedDomain], fmt.Errorf("Unable to perform the test due to GLUE problem: %w", glueErr)) - } else if err := check_https(std.MyDelegatedDomain(), addr.String()); err == nil { - if verbose { - log.Printf("%s just unlocked HTTPS challenge\n", std.Login) - } - if _, err := std.UnlockChallenge(CheckMap[tunnel_version][HTTPSonDelegatedDomain], ""); err != nil { - log.Printf("Unable to register challenge for %s: %s\n", std.Login, err.Error()) - } - } else { - std.RegisterChallengeError(CheckMap[tunnel_version][HTTPSonDelegatedDomain], err) - if verbose { - log.Printf("%s and HTTPS (with DNS ip=%s): %s\n", std.Login, addr.String(), err) - } - } - - // Check Matrix (only if GLUE Ok and defer contraint) - if glueErr == nil && istd%10 == check_matrix_for { - // Check Matrix Federation first - if v, err := check_matrix_federation(std.MyDelegatedDomain()); err == nil { - if verbose { - log.Printf("%s just unlocked Matrix federation challenge\n", std.Login) - } - if _, err := std.UnlockChallenge(CheckMap[tunnel_version][MatrixSrv], v); err != nil { - log.Printf("Unable to register challenge for %s: %s\n", std.Login, err.Error()) - } - } else { - std.RegisterChallengeError(CheckMap[tunnel_version][MatrixSrv], err) - if verbose { - log.Printf("%s and Matrix federation: %s\n", std.Login, err) - } - } - - // Check Matrix Client - if v, err := check_matrix_client(std.MyDelegatedDomain()); err == nil { - if verbose { - log.Printf("%s just unlocked Matrix client challenge\n", std.Login) - } - if _, err := std.UnlockChallenge(CheckMap[tunnel_version][MatrixClt], v); err != nil { - log.Printf("Unable to register challenge for %s: %s\n", std.Login, err.Error()) - } - } else { - std.RegisterChallengeError(CheckMap[tunnel_version][MatrixClt], err) - if verbose { - log.Printf("%s and Matrix client: %s\n", std.Login, err) - } - } - } - - // 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(CheckMap[tunnel_version][DNSSEC], ""); err != nil { - log.Printf("Unable to register challenge for %s: %s\n", std.Login, err.Error()) - } - } else { - std.RegisterChallengeError(CheckMap[tunnel_version][DNSSEC], err) - if verbose { - log.Printf("%s and DNSSEC: %s\n", std.Login, err) - } - } - } - } - } else { - if errreg := std.RegisterChallengeError(CheckMap[tunnel_version][DNSDelegation], err); errreg != nil { - log.Printf("Unable to register challenge error for %s: %s\n", std.Login, errreg) - } - if verbose { - log.Printf("%s and DNS: %s\n", std.Login, err) - } - } - - // Check HTTP without DNS - if err := check_http(stdIP, ""); err == nil { - if verbose { - log.Printf("%s just unlocked HTTP IP (without DNS) challenge\n", std.Login) - } - if _, err := std.UnlockChallenge(CheckMap[tunnel_version][HTTPonIP], ""); err != nil { - log.Printf("Unable to register challenge for %s: %s\n", std.Login, err.Error()) - } - } else { - std.RegisterChallengeError(CheckMap[tunnel_version][HTTPonIP], err) - if verbose { - log.Printf("%s and HTTP IP (without DNS): %s\n", std.Login, err) - } - } - - // Check DNS for association - if addr, err := check_dns(std.MyAssociatedDomain(), DEFAULT_RESOLVER); err == nil { - // Check HTTP on delegated domain - if err := check_http(addr.String(), std.MyAssociatedDomain()); err == nil { - if verbose { - log.Printf("%s just unlocked HTTP (without DNS) challenge\n", std.Login) - } - if _, err := std.UnlockChallenge(CheckMap[tunnel_version][HTTPonAssociatedDomain], ""); err != nil { - log.Printf("Unable to register challenge for %s: %s\n", std.Login, err.Error()) - } - } else { - std.RegisterChallengeError(CheckMap[tunnel_version][HTTPonAssociatedDomain], err) - if verbose { - log.Printf("%s and HTTP (without DNS): %s\n", std.Login, err) - } - } - - // Check HTTPs without DNS - if err := check_https(std.MyAssociatedDomain(), stdIP); err == nil { - if verbose { - log.Printf("%s just unlocked HTTPS challenge\n", std.Login) - } - if _, err := std.UnlockChallenge(CheckMap[tunnel_version][HTTPSonAssociatedDomain], ""); err != nil { - log.Printf("Unable to register challenge for %s: %s\n", std.Login, err.Error()) - } - } else { - std.RegisterChallengeError(CheckMap[tunnel_version][HTTPSonAssociatedDomain], err) - if verbose { - log.Printf("%s and HTTPS (without DNS): %s\n", std.Login, err) - } - } - } - - return - }) - } + go studentChecker(s, istd%10 == check_matrix_for) } } diff --git a/checker/main.go b/checker/main.go index 6eb561b..123a9f8 100644 --- a/checker/main.go +++ b/checker/main.go @@ -33,6 +33,24 @@ func main() { log.Fatal("Cannot create database: ", err) } + if len(flag.Args()) >= 1 { + // Check one or more students and exit + for _, std_login := range flag.Args() { + if verbose { + log.Println("==============================\n") + } + + if std, err := adlin.GetStudentByLogin(std_login); err != nil { + log.Printf("%s: %s", std_login, err.Error()) + } else { + log.Printf("Checking %s...", std.Login) + studentChecker(std, true) + } + } + + return + } + // Prepare graceful shutdown interrupt := make(chan os.Signal, 1) signal.Notify(interrupt, os.Interrupt, syscall.SIGTERM) @@ -51,5 +69,4 @@ loop: studentsChecker() } } - }