func (h *Handler) auth(r *http.Request, client string) (*authRequest, error) { var msg wire.Message dec := json.NewDecoder(r.Body) err := dec.Decode(&msg) if err != nil { return nil, errgo.Mask(err) } clientKey, err := sf.DecodePublicKey(client) if err != nil { return nil, errgo.Mask(err) } nonce, err := sf.DecodeNonce(msg.ID) if err != nil { return nil, errgo.Mask(err) } out, ok := box.Open(nil, msg.Contents, (*[24]byte)(nonce), (*[32]byte)(clientKey), (*[32]byte)(h.keyPair.PrivateKey)) if !ok { return nil, errgo.New("authentication failed") } return &authRequest{ Handler: h, ClientKey: clientKey, Nonce: nonce, Contents: out, }, nil }
// Push implements storage.Service. func (s *service) Push(msg *storage.AddressedMessage) error { rcptKey, err := sf.DecodePublicKey(msg.Recipient) if err != nil { return errgo.Notef(err, "invalid recipient %q", msg.Recipient) } senderKey, err := sf.DecodePublicKey(msg.Sender) if err != nil { return errgo.Notef(err, "invalid sender %q", msg.Sender) } nonce, err := sf.DecodeNonce(msg.ID) if err != nil { return errgo.Notef(err, "invalid nonce %q", msg.ID) } return s.db.Update(func(tx *bolt.Tx) error { rcptBucket, err := tx.CreateBucketIfNotExists(rcptKey[:]) if err != nil { return errgo.Mask(err) } senderBucket, err := rcptBucket.CreateBucketIfNotExists(senderKey[:]) if err != nil { return errgo.Mask(err) } err = senderBucket.Put(nonce[:], msg.Contents) if err != nil { return errgo.Mask(err) } return nil }) }
// Pop retrieves messages addressed to the client. func (c *Client) Pop() ([]*PopMessage, error) { respContents, err := c.Request("DELETE", "/inbox/"+c.keyPair.PublicKey.Encode(), nil) if err != nil { return nil, errgo.Mask(err) } var wireMessages []wire.PopMessage err = json.Unmarshal(respContents, &wireMessages) if err != nil { return nil, errgo.Mask(err) } var popMessages []*PopMessage var errors errorSlice for _, msg := range wireMessages { nonce, err := sf.DecodeNonce(msg.ID) if err != nil { errors = append(errors, errgo.Notef(err, "ID=%q Sender=%q", msg.ID, msg.Sender)) continue } senderKey, err := sf.DecodePublicKey(msg.Sender) if err != nil { errors = append(errors, errgo.Notef(err, "ID=%q Sender=%q", msg.ID, msg.Sender)) continue } contents, ok := box.Open(nil, msg.Contents, (*[24]byte)(nonce), (*[32]byte)(senderKey), (*[32]byte)(c.keyPair.PrivateKey)) if !ok { errors = append(errors, errgo.Newf("invalid message contents: ID=%q Sender=%q", msg.ID, msg.Sender)) continue } popMessages = append(popMessages, &PopMessage{ ID: msg.ID, Contents: contents, Sender: msg.Sender, }) } if len(errors) > 0 { return popMessages, errors } return popMessages, nil }