token-validator: fix ssh part and add support for ssh-piperd
This commit is contained in:
parent
20749da348
commit
ff9c6bacdf
|
@ -58,7 +58,8 @@ func main() {
|
|||
var dsn = flag.String("dsn", DSNGenerator(), "DSN to connect to the MySQL server")
|
||||
var baseURL = flag.String("baseurl", "/", "URL prepended to each URL")
|
||||
flag.StringVar(&sharedSecret, "sharedsecret", "adelina", "secret used to communicate with remote validator")
|
||||
flag.StringVar(&AuthorizedKeyLocation, "authorizedkeyslocation", Authorizedkeyslocation, "File for allowing user to SSH to the machine")
|
||||
flag.StringVar(&AuthorizedKeysLocation, "authorizedkeyslocation", AuthorizedKeysLocation, "File for allowing user to SSH to the machine")
|
||||
flag.StringVar(&SshPiperLocation, "sshPiperLocation", SshPiperLocation, "Directory containing directories for sshpiperd")
|
||||
flag.Parse()
|
||||
|
||||
// Sanitize options
|
||||
|
|
|
@ -10,12 +10,15 @@ import (
|
|||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"path"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/julienschmidt/httprouter"
|
||||
)
|
||||
|
||||
var AuthorizedKeyLocation = "/var/lib/adlin/.ssh/authorized_keys"
|
||||
var AuthorizedKeysLocation = "/var/lib/adlin/.ssh/authorized_keys"
|
||||
var SshPiperLocation = "/var/sshpiper/"
|
||||
|
||||
func init() {
|
||||
router.GET("/sshkeys/", apiHandler(
|
||||
|
@ -23,9 +26,23 @@ func init() {
|
|||
return getStudentKeys()
|
||||
}))
|
||||
router.POST("/sshkeys/", rawHandler(receiveKey))
|
||||
router.GET("/sshkeys/authorizedkey", func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
||||
router.GET("/sshkeys/authorizedkeys", func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
||||
dumpAuthorizedKeysFile(w)
|
||||
})
|
||||
router.GET("/api/students/:sid/authorizedkeys", func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
||||
if sid, err := strconv.Atoi(string(ps.ByName("sid"))); err != nil {
|
||||
if student, err := getStudentByLogin(ps.ByName("sid")); err != nil {
|
||||
http.Error(w, "Student doesn't exist.", http.StatusNotFound)
|
||||
} else {
|
||||
student.dumpAuthorizedKeysFile(w)
|
||||
}
|
||||
} else if student, err := getStudent(sid); err != nil {
|
||||
http.Error(w, "Student doesn't exist.", http.StatusNotFound)
|
||||
} else {
|
||||
student.dumpAuthorizedKeysFile(w)
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
type StudentKey struct {
|
||||
|
@ -56,6 +73,27 @@ func getStudentKeys() (keys []StudentKey, err error) {
|
|||
}
|
||||
}
|
||||
|
||||
func (s Student) getKeys() (keys []StudentKey, err error) {
|
||||
if rows, errr := DBQuery("SELECT id_key, id_student, sshkey, time FROM student_keys WHERE id_student = ?", s.Id); 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
|
||||
|
@ -130,16 +168,34 @@ func receiveKey(r *http.Request, ps httprouter.Params, body []byte) (interface{}
|
|||
|
||||
log.Printf("%s just pushed sshkey\n", std.Login)
|
||||
|
||||
if len(AuthorizedKeyLocation) > 0 {
|
||||
file, err := os.Create(AuthorizedKeyLocation)
|
||||
if len(AuthorizedKeysLocation) > 0 {
|
||||
file, err := os.Create(AuthorizedKeysLocation)
|
||||
if err != nil {
|
||||
log.Fatal("Cannot create file", err)
|
||||
goto sshpiperimport
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
dumpAuthorizedKeysFile(file)
|
||||
}
|
||||
|
||||
sshpiperimport:
|
||||
if len(SshPiperLocation) > 0 {
|
||||
if err := os.MkdirAll(path.Join(SshPiperLocation, std.Login), 0777); err != nil {
|
||||
log.Fatal("Cannot create sshpiper directory:", err)
|
||||
} else {
|
||||
file, err := os.Create(path.Join(SshPiperLocation, std.Login, "authorized_keys"))
|
||||
if err != nil {
|
||||
log.Fatal("Cannot create sshpiperd file", err)
|
||||
goto onerr
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
std.dumpAuthorizedKeysFile(file)
|
||||
}
|
||||
}
|
||||
|
||||
onerr:
|
||||
return "Key imported", nil
|
||||
}
|
||||
}
|
||||
|
@ -160,3 +216,20 @@ func dumpAuthorizedKeysFile(w io.Writer) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s Student) dumpAuthorizedKeysFile(w io.Writer) {
|
||||
seen := map[string]interface{}{}
|
||||
|
||||
if keys, _ := s.getKeys(); keys != nil {
|
||||
for _, k := range keys {
|
||||
if _, exists := seen[k.Key]; exists {
|
||||
continue
|
||||
} else {
|
||||
seen[k.Key] = true
|
||||
}
|
||||
|
||||
s, _ := k.GetStudent()
|
||||
w.Write([]byte("ssh-ed25519 " + k.Key + fmt.Sprintf(" Student#%d-%q\n", k.IdStudent, s.Login)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Reference in New Issue
Block a user