token-validator: Implement token collector
This commit is contained in:
parent
ae3b2e6f3b
commit
3e3a0e9e37
@ -1,6 +1,7 @@
|
||||
package adlin
|
||||
|
||||
import (
|
||||
"crypto/ed25519"
|
||||
"crypto/rand"
|
||||
"crypto/sha512"
|
||||
"encoding/base64"
|
||||
@ -14,6 +15,18 @@ import (
|
||||
|
||||
const StdNetmask = 80
|
||||
|
||||
var (
|
||||
collector_secret ed25519.PrivateKey
|
||||
)
|
||||
|
||||
func SetCollectorSecret(b []byte) {
|
||||
collector_secret = ed25519.NewKeyFromSeed(b)
|
||||
}
|
||||
|
||||
func GetCollectorPublic() ed25519.PublicKey {
|
||||
return collector_secret.Public().(ed25519.PublicKey)
|
||||
}
|
||||
|
||||
func StudentIP(idstd int64) net.IP {
|
||||
return net.ParseIP(fmt.Sprintf("2a01:e0a:2b:2252:%x::", idstd))
|
||||
}
|
||||
@ -36,6 +49,10 @@ type WGDump struct {
|
||||
KeepAlive string
|
||||
}
|
||||
|
||||
func (d *WGDump) GetPubKey() ([]byte, error) {
|
||||
return base64.StdEncoding.DecodeString(d.PubKey)
|
||||
}
|
||||
|
||||
var (
|
||||
wgDumpCache_data map[string]*WGDump = nil
|
||||
wgDumpCache_time time.Time
|
||||
@ -111,6 +128,14 @@ func (tt *TunnelToken) GetStudentIP() string {
|
||||
}
|
||||
}
|
||||
|
||||
func (tt *TunnelToken) GenKeySign() []byte {
|
||||
stdprivkey := ed25519.NewKeyFromSeed(tt.token[:ed25519.SeedSize])
|
||||
|
||||
stdpublic := []byte(stdprivkey.Public().(ed25519.PublicKey))
|
||||
|
||||
return ed25519.Sign(collector_secret, stdpublic)
|
||||
}
|
||||
|
||||
func TokenFromText(token string) []byte {
|
||||
sha := sha512.Sum512([]byte(token))
|
||||
return sha[:]
|
||||
@ -200,6 +225,23 @@ func (student *Student) GetActivesTunnels() (ts []*TunnelToken, err error) {
|
||||
}
|
||||
}
|
||||
|
||||
func (student *Student) GetActivesTunnelsPubKey() (ts []ed25519.PublicKey, err error) {
|
||||
var activeTuns []*TunnelToken
|
||||
activeTuns, err = student.GetActivesTunnels()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
for _, tun := range activeTuns {
|
||||
if tun.Dump != nil {
|
||||
pk := ed25519.NewKeyFromSeed(tun.token[:ed25519.SeedSize])
|
||||
ts = append(ts, pk.Public().(ed25519.PublicKey))
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (student *Student) GetTunnelToken(token []byte) (t *TunnelToken, err error) {
|
||||
t = new(TunnelToken)
|
||||
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)
|
||||
|
@ -2,6 +2,7 @@ package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
@ -16,7 +17,9 @@ import (
|
||||
"git.nemunai.re/lectures/adlin/libadlin"
|
||||
)
|
||||
|
||||
var baseURL string = "/"
|
||||
var (
|
||||
baseURL string = "/"
|
||||
)
|
||||
|
||||
type ResponseWriterPrefix struct {
|
||||
real http.ResponseWriter
|
||||
@ -59,6 +62,8 @@ func StripPrefix(prefix string, h http.Handler) http.Handler {
|
||||
}
|
||||
|
||||
func main() {
|
||||
var err error
|
||||
|
||||
if v, exists := os.LookupEnv("ADLIN_NS_HOST"); exists {
|
||||
ControlSocket = v
|
||||
}
|
||||
@ -68,6 +73,13 @@ func main() {
|
||||
if v, exists := os.LookupEnv("ADLIN_TSIG_SECRET"); exists {
|
||||
tsigSecret = v
|
||||
}
|
||||
if v, exists := os.LookupEnv("ADLIN_COLLECTOR_SECRET"); !exists {
|
||||
log.Fatal("Please define ADLIN_COLLECTOR_SECRET environment variable")
|
||||
} else if t, err := base64.StdEncoding.DecodeString(v); err != nil {
|
||||
log.Fatal("Error reading ADLIN_COLLECTOR_SECRET variable:", err)
|
||||
} else {
|
||||
adlin.SetCollectorSecret(t)
|
||||
}
|
||||
|
||||
var bind = flag.String("bind", ":8081", "Bind port/socket")
|
||||
var dsn = flag.String("dsn", adlin.DSNGenerator(), "DSN to connect to the MySQL server")
|
||||
@ -82,7 +94,6 @@ func main() {
|
||||
flag.Parse()
|
||||
|
||||
// Sanitize options
|
||||
var err error
|
||||
log.Println("Checking paths...")
|
||||
if err = sanitizeStaticOptions(); err != nil {
|
||||
log.Fatal(err)
|
||||
|
@ -17,6 +17,9 @@ import (
|
||||
)
|
||||
|
||||
func init() {
|
||||
router.GET("/api/collector_info", apiHandler(func(ps httprouter.Params, body []byte) (interface{}, error) {
|
||||
return "\"" + base64.StdEncoding.EncodeToString(adlin.GetCollectorPublic()) + "\"", nil
|
||||
}))
|
||||
router.GET("/api/wg.conf", func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
||||
w.Header().Set("Content-Type", "text/plain")
|
||||
|
||||
@ -149,7 +152,8 @@ PersistentKeepalive = 5
|
||||
# MyNetwork=%s/%d
|
||||
# GWIPv6=%s
|
||||
# MyLogin=%s
|
||||
`, base64.StdEncoding.EncodeToString(tinfo.SrvPubKey), "82.64.31.248", tinfo.SrvPort, tinfo.CltIPv6, token.SuffixIP, 64, tinfo.CltIPv6, tinfo.CltRange, tinfo.SrvGW6, student.Login)))
|
||||
# KeySign=%s
|
||||
`, base64.StdEncoding.EncodeToString(tinfo.SrvPubKey), "82.64.31.248", tinfo.SrvPort, tinfo.CltIPv6, token.SuffixIP, 64, tinfo.CltIPv6, tinfo.CltRange, tinfo.SrvGW6, student.Login, base64.StdEncoding.EncodeToString(token.GenKeySign()))))
|
||||
}
|
||||
|
||||
func updateWgTunnel(student *adlin.Student, ps httprouter.Params, body []byte) (interface{}, error) {
|
||||
|
Reference in New Issue
Block a user