Beispiel #1
0
func AddUpdateMessage(msg *objects.FullMessage, box int) error {
	localMutex.Lock()
	defer localMutex.Unlock()

	var err error

	if Contains(msg.MetaMessage.TxidHash) > SENDBOX { // Insert Message Into Database!

		err = LocalDB.Exec("INSERT INTO msg VALUES (?, ?, ?, ?, ?, ?, ?, ?)", msg.MetaMessage.TxidHash.GetBytes(), encryption.StringToAddress(msg.MetaMessage.Recipient),
			msg.MetaMessage.Timestamp.Unix(), box, msg.Encrypted.GetBytes(), msg.Decrypted.GetBytes(), msg.MetaMessage.Purged, encryption.StringToAddress(msg.MetaMessage.Sender))
		if err != nil {
			return err
		}

	} else { // Update recipient, sender, purged, encrypted, decrypted, box
		if box < 0 {
			err = LocalDB.Exec("UPDATE msg SET purged=? WHERE txid_hash=?", msg.MetaMessage.Purged, msg.MetaMessage.TxidHash.GetBytes())
			if err != nil {
				return err
			}
		} else {
			err = LocalDB.Exec("UPDATE msg SET box=?, purged=? WHERE txid_hash=?", box, msg.MetaMessage.Purged, msg.MetaMessage.TxidHash.GetBytes())
			if err != nil {
				return err
			}
		}

		if len(msg.MetaMessage.Sender) > 0 {
			err = LocalDB.Exec("UPDATE msg SET sender=? WHERE txid_hash=?", encryption.StringToAddress(msg.MetaMessage.Sender), msg.MetaMessage.TxidHash.GetBytes())
			if err != nil {
				return err
			}
		}

		if len(msg.MetaMessage.Recipient) > 0 {
			err = LocalDB.Exec("UPDATE msg SET recipient=? WHERE txid_hash=?", encryption.StringToAddress(msg.MetaMessage.Recipient), msg.MetaMessage.TxidHash.GetBytes())
			if err != nil {
				return err
			}
		}

		if msg.Encrypted != nil {
			err = LocalDB.Exec("UPDATE msg SET encrypted=? WHERE txid_hash=?", msg.Encrypted.GetBytes(), msg.MetaMessage.TxidHash.GetBytes())
			if err != nil {
				return err
			}
		}

		if msg.Decrypted != nil {
			err = LocalDB.Exec("UPDATE msg SET decrypted=? WHERE txid_hash=?", msg.Decrypted.GetBytes(), msg.MetaMessage.TxidHash.GetBytes())
			if err != nil {
				return err
			}
		}

	}

	Add(msg.MetaMessage.TxidHash, box)
	return nil
}
Beispiel #2
0
func (service *EMPService) GetLabel(r *http.Request, args *string, reply *string) error {
	if !basicAuth(service.Config, r) {
		service.Config.Log <- fmt.Sprintf("Unauthorized RPC Request from: %s", r.RemoteAddr)
		return errors.New("Unauthorized")
	}

	var err error

	address := encryption.StringToAddress(*args)
	if len(address) != 25 {
		return errors.New(fmt.Sprintf("Invalid Address: %s", address))
	}

	addrHash := objects.MakeHash(address)

	detail, err := localdb.GetAddressDetail(addrHash)
	if err != nil {
		return err
	}

	if len(detail.Label) > 0 {
		*reply = detail.Label
	} else {
		*reply = *args
	}
	return nil
}
Beispiel #3
0
func (service *EMPService) GetAddress(r *http.Request, args *string, reply *objects.AddressDetail) error {

	if !basicAuth(service.Config, r) {
		service.Config.Log <- fmt.Sprintf("Unauthorized RPC Request from: %s", r.RemoteAddr)
		return errors.New("Unauthorized")
	}

	var err error

	address := encryption.StringToAddress(*args)
	if len(address) != 25 {
		return errors.New(fmt.Sprintf("Invalid Address: %s", address))
	}

	addrHash := objects.MakeHash(address)

	detail, err := localdb.GetAddressDetail(addrHash)
	if err != nil {
		return err
	}

	// Check for pubkey
	if len(detail.Pubkey) == 0 {
		detail.Pubkey = checkPubkey(service.Config, objects.MakeHash(detail.Address))
	}

	*reply = *detail

	return nil
}
Beispiel #4
0
func AddUpdateAddress(address *objects.AddressDetail) error {
	localMutex.Lock()
	defer localMutex.Unlock()

	var err error

	if address.Address == nil {
		address.Address = encryption.StringToAddress(address.String)
	}

	if address.Address == nil {
		return errors.New("Invalid Address!")
	}

	addrHash := objects.MakeHash(address.Address)

	if Contains(addrHash) == ADDRESS { // Exists in message database, update pubkey, privkey, and registration
		err = LocalDB.Exec("UPDATE addressbook SET registered=?, subscribed=?, label=? WHERE hash=?", address.IsRegistered, address.IsSubscribed, address.Label, addrHash.GetBytes())
		if err != nil {
			return err
		}

		if address.Pubkey != nil {
			err = LocalDB.Exec("UPDATE addressbook SET pubkey=? WHERE hash=?", address.Pubkey, addrHash.GetBytes())
			if err != nil {
				return err
			}
		}

		if address.Privkey != nil {
			err = LocalDB.Exec("UPDATE addressbook SET privkey=? WHERE hash=?", address.Privkey, addrHash.GetBytes())
			if err != nil {
				return err
			}
		}

		if address.EncPrivkey != nil {
			err = LocalDB.Exec("UPDATE addressbook SET encprivkey=? WHERE hash=?", address.EncPrivkey, addrHash.GetBytes())
			if err != nil {
				return err
			}
		}

	} else { // Doesn't exist yet, insert it!
		err = LocalDB.Exec("INSERT INTO addressbook VALUES (?, ?, ?, ?, ?, ?, ?, ?)", addrHash.GetBytes(), address.Address, address.IsRegistered, address.Pubkey, address.Privkey, address.Label, address.IsSubscribed, address.EncPrivkey)
		if err != nil {
			return err
		}
		Add(addrHash, ADDRESS)
	}

	return nil
}
Beispiel #5
0
func (service *EMPService) ForgetAddress(r *http.Request, args *string, reply *NilParam) error {
	if !basicAuth(service.Config, r) {
		service.Config.Log <- fmt.Sprintf("Unauthorized RPC Request from: %s", r.RemoteAddr)
		return errors.New("Unauthorized")
	}

	address := encryption.StringToAddress(*args)
	if len(address) != 25 {
		return errors.New(fmt.Sprintf("Invalid Address: %s", address))
	}

	addrHash := objects.MakeHash(address)

	return localdb.DeleteAddress(&addrHash)
}
Beispiel #6
0
func (service *EMPService) PublishMessage(r *http.Request, args *SendMsg, reply *SendResponse) error {
	if !basicAuth(service.Config, r) {
		service.Config.Log <- fmt.Sprintf("Unauthorized RPC Request from: %s", r.RemoteAddr)
		return errors.New("Unauthorized")
	}

	// Nil Check
	if len(args.Sender) == 0 || len(args.Plaintext) == 0 {
		return errors.New("All fields required.")
	}

	var err error

	// Get Addresses
	sendAddr := encryption.StringToAddress(args.Sender)
	if len(sendAddr) == 0 {
		return errors.New("Invalid sender address!")
	}

	sender, err := localdb.GetAddressDetail(objects.MakeHash(sendAddr))
	if err != nil {
		return errors.New(fmt.Sprintf("Error pulling send address from Database: %s", err))
	}
	if sender.Privkey == nil {
		return errors.New("Private Key Required to Publish Message")
	}

	// Create New Message
	msg := new(objects.FullMessage)
	msg.Decrypted = new(objects.DecryptedMessage)
	msg.Encrypted = nil

	txid := make([]byte, len(msg.Decrypted.Txid), cap(msg.Decrypted.Txid))

	// Fill out decrypted message
	n, err := rand.Read(txid)
	if n < len(msg.Decrypted.Txid[:]) || err != nil {
		return errors.New(fmt.Sprintf("Problem with random reader: %s", err))
	}
	copy(msg.Decrypted.Pubkey[:], sender.Pubkey)
	msg.Decrypted.Subject = args.Subject
	msg.Decrypted.MimeType = "text/plain"
	msg.Decrypted.Content = args.Plaintext
	msg.Decrypted.Length = uint32(len(msg.Decrypted.Content))

	// Fill Out Meta Message (save timestamp)
	msg.MetaMessage.Purged = false
	msg.MetaMessage.TxidHash = objects.MakeHash(txid)
	msg.MetaMessage.Sender = sender.String
	msg.MetaMessage.Recipient = "<Subscription Message>"

	// Get Signature
	priv := new(ecdsa.PrivateKey)
	priv.PublicKey.Curve = encryption.GetCurve()
	priv.D = new(big.Int)
	priv.D.SetBytes(sender.Privkey)

	sign := msg.Decrypted.GetBytes()
	sign = sign[:len(sign)-65]
	signHash := objects.MakeHash(sign)

	x, y, err := ecdsa.Sign(rand.Reader, priv, signHash.GetBytes())
	if err != nil {
		return err
	}

	copy(msg.Decrypted.Signature[:], encryption.MarshalPubkey(x, y))

	// Send message and add to sendbox...
	msg.Encrypted = encryption.EncryptPub(service.Config.Log, sender.Privkey, string(msg.Decrypted.GetBytes()))
	msg.MetaMessage.Timestamp = time.Now().Round(time.Second)

	// Now Add Txid
	copy(msg.Decrypted.Txid[:], txid)

	err = localdb.AddUpdateMessage(msg, localdb.SENDBOX)
	if err != nil {
		return err
	}

	sendMsg := new(objects.Message)
	sendMsg.TxidHash = msg.MetaMessage.TxidHash
	sendMsg.AddrHash = objects.MakeHash(sender.Address)
	sendMsg.Timestamp = msg.MetaMessage.Timestamp
	sendMsg.Content = *msg.Encrypted

	service.Config.RecvQueue <- *objects.MakeFrame(objects.PUB, objects.BROADCAST, sendMsg)

	reply.IsSent = true

	// Finish by setting msg's txid
	reply.TxidHash = msg.MetaMessage.TxidHash.GetBytes()
	return nil

}
Beispiel #7
0
func (service *EMPService) OpenMessage(r *http.Request, args *[]byte, reply *objects.FullMessage) error {
	if !basicAuth(service.Config, r) {
		service.Config.Log <- fmt.Sprintf("Unauthorized RPC Request from: %s", r.RemoteAddr)
		return errors.New("Unauthorized")
	}

	var txidHash objects.Hash
	txidHash.FromBytes(*args)

	// Get Message from Database
	msg, err := localdb.GetMessageDetail(txidHash)
	if err != nil {
		return err
	}

	if msg.Encrypted == nil {
		*reply = *msg
		return nil
	}

	// If not decrypted, decrypt message and purge
	if msg.Decrypted == nil {
		recipient, err := localdb.GetAddressDetail(objects.MakeHash(encryption.StringToAddress(msg.MetaMessage.Recipient)))
		if err != nil {
			return err
		}

		if recipient.Privkey == nil {
			*reply = *msg
			return nil
		}

		// Decrypt Message
		decrypted := encryption.Decrypt(service.Config.Log, recipient.Privkey, msg.Encrypted)
		if len(decrypted) == 0 {
			*reply = *msg
			return nil
		}
		msg.Decrypted = new(objects.DecryptedMessage)
		msg.Decrypted.FromBytes(decrypted)

		// Update Sender

		x, y := encryption.UnmarshalPubkey(msg.Decrypted.Pubkey[:])
		address := encryption.GetAddress(service.Config.Log, x, y)
		addrStr := encryption.AddressToString(address)
		addrHash := objects.MakeHash(address)

		detail, _ := localdb.GetAddressDetail(addrHash)
		if detail == nil {
			detail = new(objects.AddressDetail)
		}
		detail.Address = address
		detail.String = addrStr
		detail.Pubkey = msg.Decrypted.Pubkey[:]

		localdb.AddUpdateAddress(detail)
		msg.MetaMessage.Sender = detail.String

		// Send Purge Request
		purge := new(objects.Purge)
		purge.Txid = msg.Decrypted.Txid

		service.Config.RecvQueue <- *objects.MakeFrame(objects.PURGE, objects.BROADCAST, purge)
		msg.MetaMessage.Purged = true

		localdb.AddUpdateMessage(msg, localdb.Contains(msg.MetaMessage.TxidHash))
	} else {
		if msg.MetaMessage.Purged == false && localdb.Contains(txidHash) == localdb.INBOX {
			msg.MetaMessage.Purged = true
			localdb.AddUpdateMessage(msg, localdb.Contains(msg.MetaMessage.TxidHash))
		}
	}

	*reply = *msg
	return nil
}