checker: integrate student checker script into token-validator
This commit is contained in:
parent
709205846e
commit
63e39f8b03
3 changed files with 133 additions and 9 deletions
122
token-validator/checker.go
Normal file
122
token-validator/checker.go
Normal file
|
|
@ -0,0 +1,122 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/miekg/dns"
|
||||||
|
"github.com/sparrc/go-ping"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 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
|
||||||
|
}
|
||||||
|
|
||||||
|
pinger.Timeout = time.Second * 5
|
||||||
|
pinger.Count = 1
|
||||||
|
pinger.OnRecv = cb
|
||||||
|
pinger.SetPrivileged(true)
|
||||||
|
pinger.Run()
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Student) onPong(state bool) (err error) {
|
||||||
|
_, err = DBExec("INSERT INTO student_pong (id_student, time, state) VALUES (?, ?, ?)", s.Id, time.Now(), state)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// PORT 53
|
||||||
|
|
||||||
|
func check_dns(domain, ip string) (err error) {
|
||||||
|
client := dns.Client{Timeout: time.Second * 5}
|
||||||
|
|
||||||
|
m := new(dns.Msg)
|
||||||
|
m.SetQuestion(domain, dns.TypeSOA)
|
||||||
|
|
||||||
|
_, _, err = client.Exchange(m, fmt.Sprintf("[%s]:53", ip))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// PORT 80
|
||||||
|
|
||||||
|
func check_http(ip string) (err error) {
|
||||||
|
var resp *http.Response
|
||||||
|
resp, err = http.Get(fmt.Sprintf("http://[%s]/", ip))
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
_, 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/", domain))
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
_, err = ioutil.ReadAll(resp.Body)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Main
|
||||||
|
|
||||||
|
func studentsChecker() {
|
||||||
|
students, err := getStudents()
|
||||||
|
if err != nil {
|
||||||
|
log.Println("Unable to check students:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, s := range students {
|
||||||
|
time.Sleep(250 * time.Millisecond)
|
||||||
|
// Check ping
|
||||||
|
std := s
|
||||||
|
stdIP := studentIP(std.Id).String() + "1"
|
||||||
|
go check_ping(stdIP, func(pkt *ping.Packet) {
|
||||||
|
std.onPong(true)
|
||||||
|
|
||||||
|
// Check HTTP
|
||||||
|
if err := check_http(stdIP); err == nil {
|
||||||
|
if _, err := std.UnlockNewChallenge(100, ""); err != nil {
|
||||||
|
if _, err := std.UpdateUnlockedChallenge(100, ""); err != nil {
|
||||||
|
log.Printf("Unable to register challenge for %s: %s\n", std.Login, err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check HTTPs
|
||||||
|
if err := check_https(std.myAssociatedDomain(), stdIP); err == nil {
|
||||||
|
if _, err := std.UnlockNewChallenge(101, ""); err != nil {
|
||||||
|
if _, err := std.UpdateUnlockedChallenge(101, ""); err != nil {
|
||||||
|
log.Printf("Unable to register challenge for %s: %s\n", std.Login, err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check DNS
|
||||||
|
if err := check_dns(std.MyDelegatedDomain(), stdIP); err == nil {
|
||||||
|
if _, err := std.UnlockNewChallenge(102, ""); err != nil {
|
||||||
|
if _, err := std.UpdateUnlockedChallenge(102, ""); err != nil {
|
||||||
|
log.Printf("Unable to register challenge for %s: %s\n", std.Login, err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -12,6 +12,7 @@ import (
|
||||||
"path"
|
"path"
|
||||||
"strings"
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
var baseURL string = "/"
|
var baseURL string = "/"
|
||||||
|
|
@ -106,6 +107,14 @@ func main() {
|
||||||
Handler: StripPrefix(baseURL, Router()),
|
Handler: StripPrefix(baseURL, Router()),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Launch checker
|
||||||
|
go func() {
|
||||||
|
for {
|
||||||
|
studentsChecker()
|
||||||
|
time.Sleep(500 * time.Millisecond)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
// Serve content
|
// Serve content
|
||||||
go func() {
|
go func() {
|
||||||
log.Fatal(srv.ListenAndServe())
|
log.Fatal(srv.ListenAndServe())
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ var PongSecret = "felixfixit"
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
router.GET("/api/students/:sid/ping", apiHandler(studentHandler(lastPing)))
|
router.GET("/api/students/:sid/ping", apiHandler(studentHandler(lastPing)))
|
||||||
router.GET("/api/students/:sid/pong", apiHandler(studentHandler(func (student Student, body []byte) (interface{}, error) {
|
router.GET("/api/students/:sid/pong", apiHandler(studentHandler(func(student Student, body []byte) (interface{}, error) {
|
||||||
return student.lastPongs()
|
return student.lastPongs()
|
||||||
})))
|
})))
|
||||||
router.POST("/api/students/:sid/pong", apiHandler(studentHandler(stdPong), sslOnly))
|
router.POST("/api/students/:sid/pong", apiHandler(studentHandler(stdPong), sslOnly))
|
||||||
|
|
@ -62,12 +62,5 @@ func stdPong(student Student, body []byte) (interface{}, error) {
|
||||||
return nil, errors.New("This is not the expected token.")
|
return nil, errors.New("This is not the expected token.")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true, student.onPong(gt.Challenge == 0)
|
||||||
if res, err := DBExec("INSERT INTO student_pong (id_student, time, state) VALUES (?, ?, ?)", student.Id, time.Now(), gt.Challenge == 0); err != nil {
|
|
||||||
return false, err
|
|
||||||
} else if _, err := res.LastInsertId(); err != nil {
|
|
||||||
return false, err
|
|
||||||
} else {
|
|
||||||
return true, err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Reference in a new issue