コード例 #1
0
ファイル: bmail.go プロジェクト: DanielKrawisz/bmagent
// MsgRead creates a Bitmessage object from an unencrypted wire.MsgMsg.
func MsgRead(msg *cipher.Message, toAddress string, ofChan bool) (*Bmail, error) {
	data := msg.Bitmessage()
	object := msg.Object()
	header := object.Header()

	sign, _ := data.SigningKey.ToBtcec()
	encr, _ := data.EncryptionKey.ToBtcec()
	from := identity.NewPublic(sign, encr, data.Pow, data.FromAddressVersion, data.FromStreamNumber)
	fromAddress, err := from.Address.Encode()
	if err != nil {
		return nil, err
	}

	return &Bmail{
		From:       bmToEmail(fromAddress),
		To:         bmToEmail(toAddress),
		Expiration: header.Expiration(),
		Ack:        msg.Ack(),
		OfChannel:  ofChan,
		Content:    data.Content,
		object:     object.MsgObject(),
	}, nil
}
コード例 #2
0
ファイル: server.go プロジェクト: DanielKrawisz/bmagent
// newMessage is called when a new message is received by the RPC client.
// Messages are guaranteed to be received in ascending order of counter value.
func (s *server) newMessage(counter uint64, object []byte) {
	// Store counter value.
	atomic.StoreUint64(&s.msgCounter, counter)

	msg := &obj.Message{}
	err := msg.Decode(bytes.NewReader(object))
	if err != nil {
		serverLog.Errorf("Failed to decode message #%d from bytes: %v", counter,
			err)
		return // Ignore message.
	}

	// Check if message is smaller than expected.
	// IV + Curve params/X/Y + 1 block + HMAC-256
	if len(msg.Encrypted) <= aes.BlockSize+70+aes.BlockSize+sha256.Size {
		return
	}

	// Is this an ack message we are expecting?
	for _, user := range s.imapUser {
		err = user.DeliverAckReply(object)
		if err == nil {
			return
		}
	}

	// Contains the address of the identity used to decrypt the message.
	var address string
	// Whether the message was received from a channel.
	var ofChan bool

	var id uint32
	var message *cipher.Message

	// Try decrypting with all available identities.
	for uid, user := range s.users {
		err = user.Keys.ForEach(func(id *keymgr.PrivateID) error {
			var decryptErr error
			message, decryptErr = cipher.TryDecryptAndVerifyMessage(msg, &id.Private)
			if decryptErr == nil {
				address = id.Address()
				ofChan = id.IsChan
				//id = uid
				return errSuccessCode
			}
			return nil
		})

		if err != nil {
			id = uid
			// Decryption successful.
			break
		}
	}

	if message == nil {
		// Decryption unsuccessful.
		return
	}

	// Decryption was successful. Add message to store.

	// TODO Store public key of the sender in bmagent

	// Read message.
	bmsg, err := email.MsgRead(message, address, ofChan)
	if err != nil {
		log.Errorf("Failed to decode message #%d: %v", counter, err)
		return
	}

	rpccLog.Trace("Bitmessage received from " + bmsg.From + " to " + bmsg.To)

	err = s.imapUser[id].DeliverFromBMNet(bmsg)
	if err != nil {
		log.Errorf("Failed to save message #%d: %v", counter, err)
		return
	}

	// Check if length of Ack is correct and message isn't from a channel.
	if message.Ack() == nil || len(message.Ack()) < wire.MessageHeaderSize || ofChan {
		return
	}

	// Send out ack if necessary.
	ack := message.Ack()[wire.MessageHeaderSize:]
	err = (&wire.MsgObject{}).Decode(bytes.NewReader(ack))
	if err != nil { // Can't send invalid Ack.
		return
	}
	_, err = s.bmd.SendObject(ack)
	if err != nil {
		log.Infof("Failed to send ack for message #%d: %v", counter, err)
		return
	}

}