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 }
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 }
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 }
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 }
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) }
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 }
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 }