func checkManifestSignature(mr *mig.ManifestResponse) (err error) { defer func() { if e := recover(); e != nil { err = fmt.Errorf("checkManifestSignature() -> %v", e) } }() var keys [][]byte for _, pk := range MANIFESTPGPKEYS { keys = append(keys, []byte(pk)) } keyring, _, err := pgp.ArmoredKeysToKeyring(keys) if err != nil { panic(err) } cnt, err := mr.VerifySignatures(keyring) if err != nil { panic(err) } logInfo("%v valid signatures in manifest", cnt) if cnt < REQUIREDSIGNATURES { err = fmt.Errorf("Not enough valid signatures (got %v, need %v), rejecting", cnt, REQUIREDSIGNATURES) panic(err) } return }
// makeKeyring retrieves GPG keys of active investigators from the database and makes // a GPG keyring out of it func makeKeyring() (keyring io.ReadSeeker, err error) { defer func() { if e := recover(); e != nil { err = fmt.Errorf("makeKeyring() -> %v", e) } ctx.Channels.Log <- mig.Log{Desc: "leaving makeKeyring()"}.Debug() }() keys, err := ctx.DB.ActiveInvestigatorsKeys() if err != nil { panic(err) } keyring, keycount, err := pgp.ArmoredKeysToKeyring(keys) if err != nil { panic(err) } ctx.Channels.Log <- mig.Log{Desc: fmt.Sprintf("loaded %d keys from active investigators", keycount)}.Debug() return }
// checkActionAuthorization verifies the PGP signatures of a given action // against the Access Control List of the agent. func checkActionAuthorization(a mig.Action, ctx *Context) (err error) { defer func() { if e := recover(); e != nil { err = fmt.Errorf("checkActionAuthorization() -> %v", e) } ctx.Channels.Log <- mig.Log{ActionID: a.ID, Desc: "leaving checkActionAuthorization()"}.Debug() }() var keys [][]byte for _, pk := range PUBLICPGPKEYS { keys = append(keys, []byte(pk)) } // get an io.Reader from the public pgp key keyring, keycount, err := pgp.ArmoredKeysToKeyring(keys) if err != nil { panic(err) } ctx.Channels.Log <- mig.Log{ActionID: a.ID, Desc: fmt.Sprintf("loaded %d keys", keycount)}.Debug() // Check the action syntax and signature err = a.Validate() if err != nil { desc := fmt.Sprintf("action validation failed: %v", err) ctx.Channels.Log <- mig.Log{ActionID: a.ID, Desc: desc}.Err() panic(desc) } // Validate() checks that the action hasn't expired, but we need to // check the start time ourselves if time.Now().Before(a.ValidFrom) { ctx.Channels.Log <- mig.Log{ActionID: a.ID, Desc: "action is scheduled for later"}.Err() panic("Action ValidFrom date is in the future") } // check ACLs, includes verifying signatures err = a.VerifyACL(ctx.ACL, keyring) if err != nil { desc := fmt.Sprintf("action ACL verification failed: %v", err) ctx.Channels.Log <- mig.Log{ActionID: a.ID, Desc: desc}.Err() panic(desc) } ctx.Channels.Log <- mig.Log{ActionID: a.ID, Desc: "ACL verification succeeded."}.Debug() return }
// makeSecring retrieves the GPG private key of the scheduler from the database // and makes a GPG keyring out of it func makeSecring(ctx Context) (secring io.ReadSeeker, err error) { defer func() { if e := recover(); e != nil { err = fmt.Errorf("makeSecring() -> %v", e) } ctx.Channels.Log <- mig.Log{Desc: "leaving makeSecring()"}.Debug() }() key, err := ctx.DB.GetSchedulerPrivKey() if err != nil { panic(err) } keys := make([][]byte, 1) keys[0] = key secring, _, err = pgp.ArmoredKeysToKeyring(keys) if err != nil { panic(err) } ctx.Channels.Log <- mig.Log{Desc: "loaded scheduler private key from database"}.Debug() return }