token-validator: check key before importing it

This commit is contained in:
nemunaire 2019-02-28 09:41:10 +01:00
parent 4ca1c4c3ca
commit 9eaa2bf4e8

View File

@ -1,6 +1,7 @@
package main package main
import ( import (
"bytes"
"crypto/hmac" "crypto/hmac"
"encoding/json" "encoding/json"
"encoding/hex" "encoding/hex"
@ -10,14 +11,16 @@ import (
"log" "log"
"net/http" "net/http"
"os" "os"
"os/exec"
"path" "path"
"strconv" "strconv"
"strings"
"time" "time"
"github.com/julienschmidt/httprouter" "github.com/julienschmidt/httprouter"
) )
var AuthorizedKeysLocation = "/var/lib/adlin/.ssh/authorized_keys" var AuthorizedKeysLocation = "/root/.ssh/authorized_keys"
var SshPiperLocation = "/var/sshpiper/" var SshPiperLocation = "/var/sshpiper/"
func init() { func init() {
@ -100,6 +103,42 @@ func getStudentKey(id int) (k StudentKey, err error) {
} }
func (s Student) NewKey(key string) (k StudentKey, err error) { func (s Student) NewKey(key string) (k StudentKey, err error) {
// Check key before importing it
cmd := exec.Command("ssh-keygen", "-l", "-f", "-")
cmd.Stdin = strings.NewReader(key)
var stdoutStderr []byte
stdoutStderr, err = cmd.CombinedOutput()
if err != nil {
if _, ok := err.(*exec.ExitError); ok {
err = errors.New(string(stdoutStderr))
}
return
}
chunks := bytes.Fields(stdoutStderr)
keytype := string(chunks[len(chunks)-1])
minkeysize := 2048
if keytype == "(ED25519)" || keytype == "(ECDSA)" {
minkeysize = 256
}
var bits int
if bits, err = strconv.Atoi(string(chunks[0])); err != nil {
return
} else if bits < minkeysize {
err = errors.New("Keysize too small")
return
}
// Sanitize the given key
keyf := strings.Fields(key)
if len(keyf) < 2 {
err = errors.New("Unexpected key file, this should never happen")
return
}
key = keyf[0] + " " + keyf[1]
if res, err := DBExec("INSERT INTO student_keys (id_student, sshkey, time) VALUES (?, ?, ?)", s.Id, key, time.Now()); err != nil { if res, err := DBExec("INSERT INTO student_keys (id_student, sshkey, time) VALUES (?, ?, ?)", s.Id, key, time.Now()); err != nil {
return StudentKey{}, err return StudentKey{}, err
} else if kid, err := res.LastInsertId(); err != nil { } else if kid, err := res.LastInsertId(); err != nil {
@ -212,7 +251,7 @@ func dumpAuthorizedKeysFile(w io.Writer) {
} }
s, _ := k.GetStudent() s, _ := k.GetStudent()
w.Write([]byte("command=\"/adlin.sh " + fmt.Sprintf("%d", k.IdStudent) + " '" + s.Login + "'\",no-pty,no-agent-forwarding,no-port-forwarding ssh-ed25519 " + k.Key + fmt.Sprintf(" Student#%d-%q\n", k.IdStudent, s.Login))) w.Write([]byte("command=\"/root/adlin.sh " + fmt.Sprintf("%d", k.IdStudent) + " '" + s.Login + "'\",restrict " + k.Key + fmt.Sprintf(" Student#%d-%q\n", k.IdStudent, s.Login)))
} }
} }
} }
@ -229,7 +268,7 @@ func (s Student) dumpAuthorizedKeysFile(w io.Writer) {
} }
s, _ := k.GetStudent() s, _ := k.GetStudent()
w.Write([]byte("ssh-ed25519 " + k.Key + fmt.Sprintf(" Student#%d-%q\n", k.IdStudent, s.Login))) w.Write([]byte(k.Key + fmt.Sprintf(" Student#%d-%q\n", k.IdStudent, s.Login)))
} }
} }
} }