示例#1
0
文件: session.go 项目: robot0x/heim
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
}
示例#2
0
文件: message.go 项目: robot0x/heim
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
}
示例#3
0
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)
}
示例#4
0
文件: room.go 项目: ArkaneMoose/heim
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)
}
示例#5
0
文件: room.go 项目: logan/heim
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)
}
示例#6
0
文件: grants_test.go 项目: logan/heim
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")
	})
}