func (s *session) sendPing() error { logger := Logger(s.ctx) now := time.Now() cmd, err := proto.MakeEvent(&proto.PingEvent{ UnixTime: proto.Time(now), NextUnixTime: proto.Time(now.Add(3 * KeepAlive / 2)), }) if err != nil { logger.Printf("error: ping event: %s", err) return err } data, err := cmd.Encode() if err != nil { logger.Printf("error: ping event encode: %s", err) return err } if err := s.conn.WriteMessage(websocket.TextMessage, data); err != nil { logger.Printf("error: write ping event: %s", err) return err } s.expectedPingReply = now.Unix() s.outstandingPings++ return nil }
func (m *Message) ToBackend() proto.Message { msg := proto.Message{ UnixTime: proto.Time(m.Posted), Sender: &proto.SessionView{ IdentityView: &proto.IdentityView{ ID: proto.UserID(m.SenderID), Name: m.SenderName, ServerID: m.ServerID, ServerEra: m.ServerEra, }, SessionID: m.SessionID, }, Content: m.Content, } // ignore id parsing errors _ = msg.ID.FromString(m.ID) _ = msg.Parent.FromString(m.Parent) if m.PreviousEditID.Valid { _ = msg.PreviousEditID.FromString(m.PreviousEditID.String) } // other optionals if m.EncryptionKeyID.Valid { msg.EncryptionKeyID = m.EncryptionKeyID.String } if m.Deleted.Valid { msg.Deleted = proto.Time(m.Deleted.Time) } if m.Edited.Valid { msg.Edited = proto.Time(m.Edited.Time) } return msg }
func (s *BotSuite) TestPingHandle(c *C) { b, conn, err := BasicMockBot() c.Check(err, IsNil) c.Check(b, NotNil) defer b.Stop() go b.Rooms["test"].Run() time.Sleep(time.Second) packet := proto.Packet{ Type: proto.PingEventType, } t := time.Now().Unix() payload := proto.PingCommand{ UnixTime: proto.Time(time.Unix(t, 0)), } marshalled, err := json.Marshal(payload) packet.Data.UnmarshalJSON(marshalled) conn.incoming <- &packet msg := <-conn.outgoing p, err := msg.Payload() c.Check(err, IsNil) pingreply, ok := p.(*proto.PingReply) c.Check(ok, Equals, true) c.Check(time.Time(pingreply.UnixTime).Unix(), Equals, t) }
func (r *memRoom) Send(ctx scope.Context, session proto.Session, message proto.Message) ( proto.Message, error) { r.m.Lock() defer r.m.Unlock() msg := proto.Message{ ID: message.ID, UnixTime: proto.Time(message.ID.Time()), Parent: message.Parent, Sender: message.Sender, Content: message.Content, EncryptionKeyID: message.EncryptionKeyID, } r.log.post(&msg) return msg, r.broadcast(ctx, proto.SendType, msg, session) }
func (r *RoomBase) Send(ctx scope.Context, session proto.Session, message proto.Message) ( proto.Message, error) { r.m.Lock() defer r.m.Unlock() msg := &proto.Message{ ID: message.ID, UnixTime: proto.Time(message.ID.Time()), Parent: message.Parent, Sender: message.Sender, Content: message.Content, EncryptionKeyID: message.EncryptionKeyID, } r.log.post(msg) msg = maybeTruncate(msg) event := (*proto.SendEvent)(msg) return *msg, r.broadcast(ctx, proto.SendType, event, session) }
func TestGrants(t *testing.T) { Convey("Grant a capability on a room", t, func() { kms := security.LocalKMS() kms.SetMasterKey(make([]byte, security.AES256.KeySize())) ctx := scope.New() client := &proto.Client{Agent: &proto.Agent{}} client.FromRequest(ctx, &http.Request{}) backend := &mock.TestBackend{} room, err := backend.CreateRoom(ctx, kms, true, "test") So(err, ShouldBeNil) rkey, err := room.MessageKey(ctx) So(err, ShouldBeNil) mkey := rkey.ManagedKey() So(kms.DecryptKey(&mkey), ShouldBeNil) // Sign in as alice and send an encrypted message with aliceSendTime // as the nonce. aliceSendTime := time.Now() msgNonce := []byte(snowflake.NewFromTime(aliceSendTime).String()) aliceKey := &security.ManagedKey{ KeyType: security.AES256, Plaintext: make([]byte, security.AES256.KeySize()), } grant, err := security.GrantSharedSecretCapability(aliceKey, rkey.Nonce(), nil, mkey.Plaintext) So(err, ShouldBeNil) alice := mock.TestSession("Alice", "A1", "ip1") _, err = room.Join(ctx, alice) So(err, ShouldBeNil) msg := proto.Message{ ID: snowflake.NewFromTime(aliceSendTime), UnixTime: proto.Time(aliceSendTime), Content: "hello", } iv, err := base64.URLEncoding.DecodeString(grant.CapabilityID()) So(err, ShouldBeNil) payload := grant.EncryptedPayload() So(aliceKey.BlockCrypt(iv, aliceKey.Plaintext, payload, false), ShouldBeNil) key := &security.ManagedKey{ KeyType: security.AES128, } So(json.Unmarshal(aliceKey.Unpad(payload), &key.Plaintext), ShouldBeNil) digest, ciphertext, err := security.EncryptGCM( key, msgNonce, []byte(msg.Content), []byte("Alice")) So(err, ShouldBeNil) digestStr := base64.URLEncoding.EncodeToString(digest) cipherStr := base64.URLEncoding.EncodeToString(ciphertext) msg.Content = digestStr + "/" + cipherStr _, err = room.Send(ctx, alice, msg) So(err, ShouldBeNil) // Now sign in as bob and decrypt the message. bobKey := &security.ManagedKey{ KeyType: security.AES256, Plaintext: make([]byte, security.AES256.KeySize()), } //bobKey.Plaintext[0] = 1 grant, err = security.GrantSharedSecretCapability(bobKey, rkey.Nonce(), nil, mkey.Plaintext) So(err, ShouldBeNil) iv, err = base64.URLEncoding.DecodeString(grant.CapabilityID()) So(err, ShouldBeNil) payload = grant.EncryptedPayload() So(bobKey.BlockCrypt(iv, bobKey.Plaintext, payload, false), ShouldBeNil) key = &security.ManagedKey{ KeyType: security.AES128, } So(json.Unmarshal(bobKey.Unpad(payload), &key.Plaintext), ShouldBeNil) bob := mock.TestSession("Bob", "B1", "ip2") _, err = room.Join(ctx, bob) So(err, ShouldBeNil) log, err := room.Latest(ctx, 1, 0) So(err, ShouldBeNil) So(len(log), ShouldEqual, 1) msg = log[0] parts := strings.Split(msg.Content, "/") So(len(parts), ShouldEqual, 2) digest, err = base64.URLEncoding.DecodeString(parts[0]) So(err, ShouldBeNil) ciphertext, err = base64.URLEncoding.DecodeString(parts[1]) So(err, ShouldBeNil) plaintext, err := security.DecryptGCM(key, msgNonce, digest, ciphertext, []byte("Alice")) So(err, ShouldBeNil) So(string(plaintext), ShouldEqual, "hello") }) }