token-validator: add suffixip and version in db
This commit is contained in:
parent
daa0e00619
commit
28d5aa8fca
|
@ -123,6 +123,8 @@ CREATE TABLE IF NOT EXISTS student_tunnel_tokens(
|
|||
id_student INTEGER NOT NULL,
|
||||
time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
pubkey BLOB(50) DEFAULT NULL,
|
||||
suffixip INTEGER NOT NULL,
|
||||
version INTEGER NOT NULL,
|
||||
FOREIGN KEY(id_student) REFERENCES students(id_student)
|
||||
) DEFAULT CHARACTER SET = utf8 COLLATE = utf8_bin;
|
||||
`); err != nil {
|
||||
|
|
|
@ -0,0 +1,164 @@
|
|||
package adlin
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"crypto/sha512"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"net"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
func StudentIP(idstd int64) net.IP {
|
||||
return net.ParseIP(fmt.Sprintf("2a01:e0a:2b:2252:%x::", idstd))
|
||||
}
|
||||
|
||||
type WGDump struct {
|
||||
PubKey string
|
||||
PSK string
|
||||
Endpoint string
|
||||
AllowedIPs string
|
||||
LastHandS string
|
||||
RX string
|
||||
TX string
|
||||
KeepAlive string
|
||||
}
|
||||
|
||||
func readWgDump() (wgd map[string]WGDump, err error) {
|
||||
out, errr := exec.Command("wg", "show", "wg-adlin", "dump").Output()
|
||||
|
||||
if errr != nil {
|
||||
return nil, errr
|
||||
}
|
||||
|
||||
wgd = map[string]WGDump{}
|
||||
for _, line := range strings.Split(string(out), "\n") {
|
||||
cols := strings.Fields(line)
|
||||
if len(cols) != 8 {
|
||||
continue
|
||||
}
|
||||
|
||||
wgd[cols[0]] = WGDump{cols[0], cols[1], cols[2], cols[3], cols[4], cols[5], cols[6], cols[7]}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
type TunnelToken struct {
|
||||
token []byte
|
||||
TokenText string
|
||||
IdStudent int64
|
||||
PubKey []byte
|
||||
Time time.Time
|
||||
SuffixIP int
|
||||
// Version stores the TP number where the token is used
|
||||
Version int
|
||||
Dump *WGDump
|
||||
}
|
||||
|
||||
func tokenFromText(token string) []byte {
|
||||
sha := sha512.Sum512([]byte(token))
|
||||
return sha[:]
|
||||
}
|
||||
|
||||
func GetTunnelToken(token []byte) (t TunnelToken, err error) {
|
||||
err = DBQueryRow("SELECT token, token_text, id_student, pubkey, time, suffixip, version FROM student_tunnel_tokens WHERE token=? ORDER BY time DESC", token).Scan(&t.token, &t.TokenText, &t.IdStudent, &t.PubKey, &t.Time, &t.SuffixIP, &t.Version)
|
||||
if err == nil && t.PubKey != nil {
|
||||
if wgd, errr := readWgDump(); errr == nil {
|
||||
if v, ok := wgd[base64.StdEncoding.EncodeToString(t.PubKey)]; ok {
|
||||
t.Dump = &v
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (student Student) NewTunnelToken(suffixip int) (t TunnelToken, err error) {
|
||||
tok := make([]byte, 7)
|
||||
if _, err = rand.Read(tok); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
t.TokenText = strings.Replace(strings.Replace(strings.Replace(strings.Replace(strings.Replace(base64.RawStdEncoding.EncodeToString(tok), "/", ".", -1), "+", "_", -1), "O", "#", -1), "l", "$", -1), "I", ">", -1)
|
||||
t.token = tokenFromText(t.TokenText)
|
||||
t.IdStudent = student.Id
|
||||
|
||||
_, err = DBExec("INSERT INTO student_tunnel_tokens (token, token_text, id_student, time, suffixip, version) VALUES (?, ?, ?, ?, ?, 0)", t.token, t.TokenText, student.Id, time.Now(), suffixip)
|
||||
return
|
||||
}
|
||||
|
||||
func (student Student) GetTunnelTokens() (ts []TunnelToken, err error) {
|
||||
if rows, errr := DBQuery("SELECT token, token_text, id_student, pubkey, time, suffixip, version FROM student_tunnel_tokens WHERE id_student = ? ORDER BY time DESC", student.Id); errr != nil {
|
||||
return nil, errr
|
||||
} else if wgd, errr := readWgDump(); errr != nil {
|
||||
return nil, errr
|
||||
} else {
|
||||
defer rows.Close()
|
||||
|
||||
for rows.Next() {
|
||||
var t TunnelToken
|
||||
if err = rows.Scan(&t.token, &t.TokenText, &t.IdStudent, &t.PubKey, &t.Time, &t.SuffixIP, &t.Version); err != nil {
|
||||
return
|
||||
}
|
||||
if t.PubKey != nil {
|
||||
if v, ok := wgd[base64.StdEncoding.EncodeToString(t.PubKey)]; ok {
|
||||
t.Dump = &v
|
||||
}
|
||||
}
|
||||
ts = append(ts, t)
|
||||
}
|
||||
if err = rows.Err(); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (student Student) GetTunnelToken(token []byte) (t TunnelToken, err error) {
|
||||
err = DBQueryRow("SELECT token, token_text, id_student, pubkey, time, suffixip, version FROM student_tunnel_tokens WHERE token = ? AND id_student = ? ORDER BY time DESC", token, student.Id).Scan(&t.token, &t.TokenText, &t.IdStudent, &t.PubKey, &t.Time, &t.SuffixIP, &t.Version)
|
||||
if err == nil && t.PubKey != nil {
|
||||
if wgd, errr := readWgDump(); errr == nil {
|
||||
if v, ok := wgd[base64.StdEncoding.EncodeToString(t.PubKey)]; ok {
|
||||
t.Dump = &v
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (t *TunnelToken) Update() (int64, error) {
|
||||
newtoken := tokenFromText(t.TokenText)
|
||||
tm := time.Now()
|
||||
|
||||
if res, err := DBExec("UPDATE student_tunnel_tokens SET token = ?, token_text = ?, id_student = ?, pubkey = ?, time = ?, suffixip = ?, version = ? WHERE token = ?", newtoken, t.TokenText, t.IdStudent, t.PubKey, tm, t.SuffixIP, t.Version, t.token); err != nil {
|
||||
return 0, err
|
||||
} else if nb, err := res.RowsAffected(); err != nil {
|
||||
return 0, err
|
||||
} else {
|
||||
t.token = newtoken
|
||||
t.Time = tm
|
||||
return nb, err
|
||||
}
|
||||
}
|
||||
|
||||
func GetStudentsTunnels() (ts []TunnelToken, err error) {
|
||||
if rows, errr := DBQuery("SELECT T.token, T.token_text, T.id_student, T.pubkey, T.time, T.suffixip, T.version FROM student_tunnel_tokens T INNER JOIN (SELECT B.id_student, MAX(B.time) AS time FROM student_tunnel_tokens B WHERE B.pubkey IS NOT NULL GROUP BY id_student) L ON T.id_student = L.id_student AND T.time = L.time"); errr != nil {
|
||||
return nil, errr
|
||||
} else {
|
||||
defer rows.Close()
|
||||
|
||||
for rows.Next() {
|
||||
var t TunnelToken
|
||||
if err = rows.Scan(&t.token, &t.TokenText, &t.IdStudent, &t.PubKey, &t.Time, &t.SuffixIP, &t.Version); err != nil {
|
||||
return
|
||||
}
|
||||
ts = append(ts, t)
|
||||
}
|
||||
|
||||
err = rows.Err()
|
||||
return
|
||||
}
|
||||
}
|
|
@ -42,7 +42,7 @@ func showWgTunnel(student adlin.Student, ps httprouter.Params, body []byte) (int
|
|||
|
||||
func genWgToken(student adlin.Student, ps httprouter.Params, body []byte) (interface{}, error) {
|
||||
// Generate a token to access related wg info
|
||||
return student.NewTunnelToken()
|
||||
return student.NewTunnelToken(0)
|
||||
}
|
||||
|
||||
type TunnelInfo struct {
|
||||
|
|
Reference in New Issue