From 8d2d707daaaa4597ee736828289e82313d790726 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Thu, 22 Feb 2018 06:42:21 +0100 Subject: [PATCH] token-validator: add sshkeys management --- token-validator/ssh.go | 122 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 token-validator/ssh.go diff --git a/token-validator/ssh.go b/token-validator/ssh.go new file mode 100644 index 0000000..0cb9d77 --- /dev/null +++ b/token-validator/ssh.go @@ -0,0 +1,122 @@ +package main + +import ( + "crypto/hmac" + "encoding/json" + "encoding/hex" + "errors" + "net/http" + "log" + "time" + + "github.com/julienschmidt/httprouter" +) + +func init() { + router.GET("/sshkeys/", apiHandler( + func(httprouter.Params, []byte) (interface{}, error) { + return getStudentKeys() + })) + router.POST("/sshkeys/", rawHandler(receiveKey)) +} + +type StudentKey struct { + Id int64 `json:"id"` + IdStudent int64 `json:"id_student"` + Key string `json:"key"` + Time time.Time `json:"time"` +} + +func getStudentKeys() (keys []StudentKey, err error) { + if rows, errr := DBQuery("SELECT id_key, id_student, sshkey, time FROM student_keys"); errr != nil { + return nil, errr + } else { + defer rows.Close() + + for rows.Next() { + var k StudentKey + if err = rows.Scan(&k.Id, &k.IdStudent, &k.Key, &k.Time); err != nil { + return + } + keys = append(keys, k) + } + if err = rows.Err(); err != nil { + return + } + + return + } +} + +func getStudentKey(id int) (k StudentKey, err error) { + err = DBQueryRow("SELECT id_key, id_student, sshkey, time FROM student_keys WHERE id_key=?", id).Scan(&k.Id, &k.IdStudent, &k.Key, &k.Time) + return +} + +func (s Student) NewKey(key string) (k StudentKey, err error) { + if res, err := DBExec("INSERT INTO student_keys (id_student, sshkey, time) VALUES (?, ?, ?)", s.Id, key, time.Now()); err != nil { + return StudentKey{}, err + } else if kid, err := res.LastInsertId(); err != nil { + return StudentKey{}, err + } else { + return StudentKey{kid, s.Id, key, time.Now()}, nil + } +} + +func (k StudentKey) Update() (int64, error) { + if res, err := DBExec("UPDATE student_keys SET id_student = ?, sshkey = ?, time = ? WHERE id_key = ?", k.IdStudent, k.Key, k.Time, k.Id); err != nil { + return 0, err + } else if nb, err := res.RowsAffected(); err != nil { + return 0, err + } else { + return nb, err + } +} + +func (k StudentKey) Delete() (int64, error) { + if res, err := DBExec("DELETE FROM student_keys WHERE id_key = ?", k.Id); err != nil { + return 0, err + } else if nb, err := res.RowsAffected(); err != nil { + return 0, err + } else { + return nb, err + } +} + +func receiveKey(r *http.Request, ps httprouter.Params, body []byte) (interface{}, error) { + var gt givenToken + if err := json.Unmarshal(body, >); err != nil { + return nil, err + } + + gt.token = make([]byte, hex.DecodedLen(len(gt.Token))) + if _, err := hex.Decode(gt.token, []byte(gt.Token)); err != nil { + return nil, err + } + + if std, err := getStudentByLogin(gt.Login); err != nil { + return nil, err + } else if len(gt.Data) < 2 { + return nil, errors.New("No key found!") + } else { + pkey := std.GetPKey() + + data := [][]byte{} + for _, d := range gt.Data { + data = append(data, []byte(d)) + } + + if expectedToken, err := GenerateToken(pkey, 0, data...); err != nil { + return nil, err + } else if ! hmac.Equal(expectedToken, gt.token) { + return nil, errors.New("This is not the expected token.") + } + + if _, err := std.NewKey(gt.Data[1]); err != nil { + return nil, err + } + + log.Printf("%s just pushed sshkey\n", std.Login) + return "Key imported", nil + } +}