135 lines
2.9 KiB
Go
135 lines
2.9 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"io/ioutil"
|
|
"log"
|
|
"net/http"
|
|
"time"
|
|
|
|
"github.com/miekg/dns"
|
|
"github.com/sparrc/go-ping"
|
|
|
|
"git.nemunai.re/lectures/adlin/libadlin"
|
|
)
|
|
|
|
var baseChallenge = 100
|
|
var verbose = false
|
|
|
|
// 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
|
|
}
|
|
|
|
// 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 := adlin.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 := adlin.StudentIP(std.Id).String() + "1"
|
|
go check_ping(stdIP, func(pkt *ping.Packet) {
|
|
if verbose {
|
|
log.Printf("%s PONG\n", std.Login)
|
|
}
|
|
std.OnPong(true)
|
|
|
|
// Check HTTP
|
|
if err := check_http(stdIP); err == nil {
|
|
if verbose {
|
|
log.Printf("%s just unlocked HTTP challenge\n", std.Login)
|
|
}
|
|
if _, err := std.UnlockNewChallenge(baseChallenge+0, ""); err != nil {
|
|
if _, err := std.UpdateUnlockedChallenge(baseChallenge+0, ""); 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 verbose {
|
|
log.Printf("%s just unlocked HTTPS challenge\n", std.Login)
|
|
}
|
|
if _, err := std.UnlockNewChallenge(baseChallenge+1, ""); err != nil {
|
|
if _, err := std.UpdateUnlockedChallenge(baseChallenge+1, ""); 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 verbose {
|
|
log.Printf("%s just unlocked DNS challenge\n", std.Login)
|
|
}
|
|
if _, err := std.UnlockNewChallenge(baseChallenge+2, ""); err != nil {
|
|
if _, err := std.UpdateUnlockedChallenge(baseChallenge+2, ""); err != nil {
|
|
log.Printf("Unable to register challenge for %s: %s\n", std.Login, err.Error())
|
|
}
|
|
}
|
|
}
|
|
|
|
return
|
|
})
|
|
}
|
|
}
|