A simple monitoring solution written in Go (work in progress)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

80 lines
1.4 KiB

  1. package api
  2. import (
  3. "crypto/hmac"
  4. "crypto/sha256"
  5. "encoding/json"
  6. "fmt"
  7. "time"
  8. )
  9. type Command struct {
  10. Expires time.Time `json:"exp"`
  11. Command string `json:"cmd"`
  12. Scheme string `json:"sch"`
  13. Signature []byte `json:"sig,omitempty"`
  14. }
  15. func NewCommand(cm string) *Command {
  16. return &Command{
  17. Expires: time.Now().Add(time.Second * 5),
  18. Command: cm,
  19. Scheme: "hmac-sha256",
  20. }
  21. }
  22. func ParseCommand(jsn []byte) (*Command, error) {
  23. cmd := &Command{}
  24. err := json.Unmarshal(jsn, cmd)
  25. if err != nil {
  26. return nil, err
  27. }
  28. return cmd, nil
  29. }
  30. func (c *Command) JSON() ([]byte, error) {
  31. return json.Marshal(c)
  32. }
  33. func (c *Command) Sign(key []byte) error {
  34. switch c.Scheme {
  35. case "hmac-sha256":
  36. j, err := c.JSON()
  37. if err != nil {
  38. return fmt.Errorf("json encoding error")
  39. }
  40. mac := hmac.New(sha256.New, key)
  41. mac.Write(j)
  42. c.Signature = mac.Sum(nil)
  43. case "":
  44. return fmt.Errorf("scheme may not be empty")
  45. default:
  46. return fmt.Errorf("unsupported scheme: %s", c.Scheme)
  47. }
  48. return nil
  49. }
  50. func (c *Command) Validate(key []byte) error {
  51. cpy := &Command{
  52. Expires: c.Expires,
  53. Command: c.Command,
  54. Scheme: c.Scheme,
  55. }
  56. err := cpy.Sign(key)
  57. if err != nil {
  58. return err
  59. }
  60. if !hmac.Equal(cpy.Signature, c.Signature) {
  61. return fmt.Errorf("invalid signature")
  62. }
  63. if time.Now().After(c.Expires) {
  64. return fmt.Errorf("command expired")
  65. }
  66. return nil
  67. }