token-validator: ip, ping, ...
This commit is contained in:
parent
6d6af5f7f4
commit
081b22a64a
@ -112,6 +112,31 @@ func challengeTime(s *Student, t *givenToken, chid int) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func challengePing(s *Student, t *givenToken, chid int) error {
|
||||||
|
var expected []byte
|
||||||
|
switch s.Id % 5 {
|
||||||
|
case 1:
|
||||||
|
expected = []byte("baaaaaad")
|
||||||
|
case 2:
|
||||||
|
expected = []byte("baadfood")
|
||||||
|
case 3:
|
||||||
|
expected = []byte("baddcafe")
|
||||||
|
case 4:
|
||||||
|
expected = []byte("cafebabe")
|
||||||
|
default:
|
||||||
|
expected = []byte("deadbeef")
|
||||||
|
}
|
||||||
|
|
||||||
|
pkey := s.GetPKey()
|
||||||
|
if expectedToken, err := GenerateToken(pkey, chid, expected); err != nil {
|
||||||
|
return err
|
||||||
|
} else if ! hmac.Equal(expectedToken, t.token) {
|
||||||
|
return errors.New("This is not the expected token.")
|
||||||
|
} else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func challengeDisk(s *Student, t *givenToken, chid int) error {
|
func challengeDisk(s *Student, t *givenToken, chid int) error {
|
||||||
pkey := fmt.Sprintf("%x", s.GetPKey())
|
pkey := fmt.Sprintf("%x", s.GetPKey())
|
||||||
|
|
||||||
@ -164,28 +189,37 @@ func init() {
|
|||||||
Check: challengeTime,
|
Check: challengeTime,
|
||||||
},
|
},
|
||||||
|
|
||||||
/* Challenge 4 : disk */
|
/* Challenge 4 : DNS TXT */
|
||||||
Challenge{
|
|
||||||
Accessible: []func(*Student, *http.Request) error{noAccessRestriction},
|
|
||||||
Check: challengeDisk,
|
|
||||||
},
|
|
||||||
|
|
||||||
/* Challenge 5 : DNS TXT */
|
|
||||||
Challenge{
|
Challenge{
|
||||||
Accessible: []func(*Student, *http.Request) error{accessFrom(IPgwDMZ), sslOnly},
|
Accessible: []func(*Student, *http.Request) error{accessFrom(IPgwDMZ), sslOnly},
|
||||||
Check: challengeDNS,
|
Check: challengeDNS,
|
||||||
},
|
},
|
||||||
|
|
||||||
/* Challenge 6 : time net */
|
/* Challenge 5 : time net */
|
||||||
Challenge{
|
Challenge{
|
||||||
Accessible: []func(*Student, *http.Request) error{maxProxy(1)},
|
Accessible: []func(*Student, *http.Request) error{maxProxy(1)},
|
||||||
Check: challengeTime,
|
Check: challengeTime,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/* Bonus 1 : echo request */
|
||||||
|
Challenge{
|
||||||
|
Accessible: []func(*Student, *http.Request) error{noAccessRestriction},
|
||||||
|
Check: challengePing,
|
||||||
|
},
|
||||||
|
|
||||||
|
/* Bonus 2 : disk */
|
||||||
|
Challenge{
|
||||||
|
Accessible: []func(*Student, *http.Request) error{noAccessRestriction},
|
||||||
|
Check: challengeDisk,
|
||||||
|
},
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
router.GET("/challenge", apiHandler(getChallengeList))
|
router.GET("/challenge", apiHandler(getChallengeList))
|
||||||
router.GET("/challenge/:chid", rawHandler(accessibleChallenge))
|
router.GET("/challenge/:chid", rawHandler(accessibleChallenge))
|
||||||
router.POST("/challenge", rawHandler(receiveToken))
|
router.POST("/challenge", rawHandler(challengeHandler(receiveToken)))
|
||||||
|
router.POST("/echorequest", rawHandler(definedChallengeHandler(receiveToken, 6)))
|
||||||
|
router.POST("/testdisk", rawHandler(definedChallengeHandler(receiveToken, 7)))
|
||||||
}
|
}
|
||||||
|
|
||||||
type givenToken struct {
|
type givenToken struct {
|
||||||
@ -219,7 +253,7 @@ func accessibleChallenge(r *http.Request, ps httprouter.Params, _ []byte) (inter
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func receiveToken(r *http.Request, ps httprouter.Params, body []byte) (interface{}, error) {
|
func receiveToken(r *http.Request, body []byte, chid int) (interface{}, error) {
|
||||||
var gt givenToken
|
var gt givenToken
|
||||||
if err := json.Unmarshal(body, >); err != nil {
|
if err := json.Unmarshal(body, >); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -231,22 +265,11 @@ func receiveToken(r *http.Request, ps httprouter.Params, body []byte) (interface
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Find challenge ID
|
// Find challenge ID
|
||||||
var chid int
|
if gt.Challenge >= 1 {
|
||||||
var err error
|
chid = gt.Challenge
|
||||||
if chid, err = strconv.Atoi(string(ps.ByName("chid"))); err != nil {
|
|
||||||
if gt.Challenge > 0 {
|
|
||||||
chid = gt.Challenge
|
|
||||||
} else if string(ps.ByName("chid")) != "" {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
err = nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if chid == 0 {
|
if chid <= 0 || chid - 1 > len(challenges) {
|
||||||
chid = 4
|
|
||||||
}
|
|
||||||
|
|
||||||
if chid > len(challenges) {
|
|
||||||
return nil, errors.New("This challenge doesn't exist")
|
return nil, errors.New("This challenge doesn't exist")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,6 +107,18 @@ func rawHandler(f func(*http.Request, httprouter.Params, []byte) (interface{}, e
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func challengeHandler(f func (*http.Request, []byte, int) (interface{}, error)) func(*http.Request, httprouter.Params, []byte) (interface{}, error) {
|
||||||
|
return func(r *http.Request, ps httprouter.Params, body []byte) (interface{}, error) {
|
||||||
|
return f(r, body, 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func definedChallengeHandler(f func (*http.Request, []byte, int) (interface{}, error), chid int) func(*http.Request, httprouter.Params, []byte) (interface{}, error) {
|
||||||
|
return func(r *http.Request, ps httprouter.Params, body []byte) (interface{}, error) {
|
||||||
|
return f(r, body, chid)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func apiHandler(f DispatchFunction, access ...func(*Student, *http.Request) error) func(http.ResponseWriter, *http.Request, httprouter.Params) {
|
func apiHandler(f DispatchFunction, access ...func(*Student, *http.Request) error) func(http.ResponseWriter, *http.Request, httprouter.Params) {
|
||||||
return rawHandler(func (_ *http.Request, ps httprouter.Params, b []byte) (interface{}, error) { return f(ps, b) }, access...)
|
return rawHandler(func (_ *http.Request, ps httprouter.Params, b []byte) (interface{}, error) { return f(ps, b) }, access...)
|
||||||
}
|
}
|
||||||
|
@ -24,10 +24,13 @@ func showIPs(_ httprouter.Params, body []byte) (interface{}, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, std := range students {
|
for _, std := range students {
|
||||||
r[std.Login] = make(map[string]string)
|
sid := fmt.Sprintf("%d", std.Id)
|
||||||
|
|
||||||
r[std.Login]["vlan0"] = fmt.Sprintf("172.23.0.%d", std.IPSuffix())
|
r[sid] = make(map[string]string)
|
||||||
r[std.Login]["vlan7"] = fmt.Sprintf("172.23.142.%d", std.IPSuffix())
|
|
||||||
|
r[sid]["mac"] = std.MAC
|
||||||
|
r[sid]["vlan0"] = fmt.Sprintf("172.23.0.%d", std.IPSuffix())
|
||||||
|
r[sid]["vlan7"] = fmt.Sprintf("172.23.142.%d", std.IPSuffix())
|
||||||
}
|
}
|
||||||
|
|
||||||
return r, nil
|
return r, nil
|
||||||
|
@ -1,14 +1,63 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var PongSecret = "felixfixit"
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
router.GET("/api/students/:sid/ping", apiHandler(studentHandler(isPinging)))
|
||||||
|
router.GET("/api/students/:sid/pong", apiHandler(studentHandler(func (student Student, body []byte) (interface{}, error) {
|
||||||
|
return student.lastPongs()
|
||||||
|
})))
|
||||||
router.POST("/api/students/:sid/pong", apiHandler(studentHandler(stdPong), sslOnly))
|
router.POST("/api/students/:sid/pong", apiHandler(studentHandler(stdPong), sslOnly))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func isPinging(student Student, body []byte) (interface{}, error) {
|
||||||
|
if pongs, err := student.lastPongs(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
} else if len(pongs) <= 0 {
|
||||||
|
return false, nil
|
||||||
|
} else {
|
||||||
|
return time.Now().Before(pongs[0].Add(time.Second * 10)), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s Student) lastPongs() (pongs []time.Time, err error) {
|
||||||
|
if rows, errr := DBQuery("SELECT time FROM student_pong WHERE id_student = ? ORDER BY time DESC", s.Id); errr != nil {
|
||||||
|
return nil, errr
|
||||||
|
} else {
|
||||||
|
defer rows.Close()
|
||||||
|
|
||||||
|
for rows.Next() {
|
||||||
|
var t time.Time
|
||||||
|
if err = rows.Scan(&t); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
pongs = append(pongs, t)
|
||||||
|
}
|
||||||
|
if err = rows.Err(); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func stdPong(student Student, body []byte) (interface{}, error) {
|
func stdPong(student Student, body []byte) (interface{}, error) {
|
||||||
|
var gt givenToken
|
||||||
|
if err := json.Unmarshal(body, >); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if gt.Token != PongSecret {
|
||||||
|
return nil, errors.New("This is not the expected token.")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if res, err := DBExec("INSERT INTO student_pong (id_student, time) VALUES (?, ?)", student.Id, time.Now()); err != nil {
|
if res, err := DBExec("INSERT INTO student_pong (id_student, time) VALUES (?, ?)", student.Id, time.Now()); err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
} else if _, err := res.LastInsertId(); err != nil {
|
} else if _, err := res.LastInsertId(); err != nil {
|
||||||
|
@ -87,7 +87,7 @@ func getStudent(id int) (s Student, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func getStudentByLogin(login string) (s Student, err error) {
|
func getStudentByLogin(login string) (s Student, err error) {
|
||||||
err = DBQueryRow("SELECT id_student, login, time FROM students WHERE login=?", login).Scan(&s.Id, &s.Login, &s.Time)
|
err = DBQueryRow("SELECT S.id_student, S.login, MAX(L.time), L.ip, L.mac FROM students S INNER JOIN (SELECT a.id_student, a.time, a.ip, a.mac FROM student_login a INNER JOIN (SELECT id_student, MAX(time) AS time FROM student_login GROUP BY id_student) b ON a.id_student = b.id_student AND a.time = b.time) L ON S.id_student = L.id_student WHERE login=?", login).Scan(&s.Id, &s.Login, &s.Time, &s.IP, &s.MAC)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -155,6 +155,9 @@ func createStudent(_ httprouter.Params, body []byte) (interface{}, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
exist.registerAccess(std.IP, std.MAC)
|
exist.registerAccess(std.IP, std.MAC)
|
||||||
|
|
||||||
|
exist.IP = fmt.Sprintf("172.23.0.%d", exist.IPSuffix())
|
||||||
|
|
||||||
return exist, nil
|
return exist, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user