2020-04-26 15:26:39 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
|
|
|
"errors"
|
|
|
|
"fmt"
|
|
|
|
"strings"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/julienschmidt/httprouter"
|
|
|
|
"github.com/miekg/dns"
|
|
|
|
|
2021-10-31 15:43:43 +00:00
|
|
|
"git.nemunai.re/srs/adlin/libadlin"
|
2020-04-26 15:26:39 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
type checkGLUE struct {
|
|
|
|
Domain string `json:"domain"`
|
|
|
|
IP string `json:"ip"`
|
|
|
|
}
|
|
|
|
|
|
|
|
func init() {
|
2021-03-07 11:39:38 +00:00
|
|
|
router.POST("/api/check/GLUE", apiAuthHandler(func(student *adlin.Student, ps httprouter.Params, body []byte) (interface{}, error) {
|
2020-04-26 15:26:39 +00:00
|
|
|
var uc checkGLUE
|
|
|
|
if err := json.Unmarshal(body, &uc); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return true, check_GLUE_respond(student, uc.Domain, uc.IP)
|
|
|
|
}))
|
|
|
|
}
|
2021-03-07 11:39:38 +00:00
|
|
|
func check_GLUE_respond(student *adlin.Student, domain string, ip string) (err error) {
|
2020-04-26 15:26:39 +00:00
|
|
|
if !strings.HasPrefix(ip, adlin.StudentIP(student.Id).String()) {
|
2021-03-08 13:49:44 +00:00
|
|
|
return fmt.Errorf("%q is not your IP range", ip)
|
2020-04-26 15:26:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
client := dns.Client{Net: "tcp", Timeout: time.Second * 5}
|
|
|
|
|
|
|
|
m := new(dns.Msg)
|
|
|
|
m.SetQuestion(domain, dns.TypeAAAA)
|
|
|
|
m.RecursionDesired = false
|
|
|
|
m.SetEdns0(4096, true)
|
|
|
|
|
|
|
|
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 from name server is nil")
|
|
|
|
}
|
|
|
|
if r.Rcode != dns.RcodeSuccess {
|
2021-02-04 08:33:01 +00:00
|
|
|
return fmt.Errorf("Name server returns %s", dns.RcodeToString[r.Rcode])
|
2020-04-26 15:26:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if len(r.Answer) == 0 {
|
|
|
|
return errors.New("Empty response for this NS record")
|
|
|
|
}
|
|
|
|
|
|
|
|
found := false
|
|
|
|
|
|
|
|
for _, answer := range r.Answer {
|
|
|
|
if t, ok := answer.(*dns.AAAA); ok {
|
|
|
|
found = found || t.AAAA.String() == ip
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if !found {
|
|
|
|
return fmt.Errorf("%q not found in records", ip)
|
|
|
|
}
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|