// AddMessageIDCache adds messageID to the message ID cache for the myID and // contactID pair. func (msgDB *MsgDB) AddMessageIDCache(myID, contactID, messageID string) error { if err := identity.IsMapped(myID); err != nil { return log.Error(err) } if contactID != "" { if err := identity.IsMapped(contactID); err != nil { return log.Error(err) } } if messageID == "" { return log.Error(ErrNilMessageID) } // get MyID var mID int if err := msgDB.getNymUIDQuery.QueryRow(myID).Scan(&mID); err != nil { return log.Error(err) } // get ContactID var cID int if contactID != "" { err := msgDB.getContactUIDQuery.QueryRow(mID, contactID).Scan(&cID) if err != nil { return log.Error(err) } } // add messageID to cache _, err := msgDB.addMessageIDCacheQuery.Exec(mID, cID, messageID) if err != nil { return log.Error(err) } return nil }
// GetAccountTime returns the account time for the given myID and contactID // combination. func (msgDB *MsgDB) GetAccountTime( myID, contactID string, ) (int64, error) { if err := identity.IsMapped(myID); err != nil { return 0, log.Error(err) } if contactID != "" { if err := identity.IsMapped(contactID); err != nil { return 0, log.Error(err) } } // get MyID var mID int if err := msgDB.getNymUIDQuery.QueryRow(myID).Scan(&mID); err != nil { return 0, log.Error(err) } // get ContactID var cID int if contactID != "" { err := msgDB.getContactUIDQuery.QueryRow(mID, contactID).Scan(&cID) if err != nil { return 0, log.Error(err) } } // get load time var loadTime int64 err := msgDB.getAccountTimeQuery.QueryRow(mID, cID).Scan(&loadTime) if err != nil { return 0, err } return loadTime, nil }
// SetAccountLastMsg sets the last message time and ID for the given myID and // contactID combination (contactID can be nil). func (msgDB *MsgDB) SetAccountLastMsg( myID, contactID string, lastMessageTime int64, ) error { if err := identity.IsMapped(myID); err != nil { return log.Error(err) } if contactID != "" { if err := identity.IsMapped(contactID); err != nil { return log.Error(err) } } // get MyID var mID int if err := msgDB.getNymUIDQuery.QueryRow(myID).Scan(&mID); err != nil { return log.Error(err) } // get ContactID var cID int if contactID != "" { err := msgDB.getContactUIDQuery.QueryRow(mID, contactID).Scan(&cID) if err != nil { return log.Error(err) } } // set account time _, err := msgDB.setAccountLastTimeQuery.Exec(lastMessageTime, mID, cID) if err != nil { return log.Error(err) } return nil }
// GetAccount returns the privkey and server of the account for myID. func (msgDB *MsgDB) GetAccount( myID, contactID string, ) ( privkey *[ed25519.PrivateKeySize]byte, server string, secret *[64]byte, minDelay, maxDelay int32, lastMessageTime int64, err error, ) { if err := identity.IsMapped(myID); err != nil { return nil, "", nil, 0, 0, 0, log.Error(err) } if contactID != "" { if err := identity.IsMapped(contactID); err != nil { return nil, "", nil, 0, 0, 0, log.Error(err) } } // get MyID var mID int if err := msgDB.getNymUIDQuery.QueryRow(myID).Scan(&mID); err != nil { return nil, "", nil, 0, 0, 0, log.Error(err) } // get ContactID var cID int if contactID != "" { err := msgDB.getContactUIDQuery.QueryRow(mID, contactID).Scan(&cID) if err != nil { return nil, "", nil, 0, 0, 0, log.Error(err) } } // get account data var pks string var scrts string err = msgDB.getAccountQuery.QueryRow(mID, cID).Scan(&pks, &server, &scrts, &minDelay, &maxDelay, &lastMessageTime) if err != nil { return nil, "", nil, 0, 0, 0, log.Error(err) } // decode private key pk, err := base64.Decode(pks) if err != nil { return nil, "", nil, 0, 0, 0, log.Error(err) } privkey = new([ed25519.PrivateKeySize]byte) copy(privkey[:], pk) // decode secret scrt, err := base64.Decode(scrts) if err != nil { return nil, "", nil, 0, 0, 0, log.Error(err) } secret = new([64]byte) copy(secret[:], scrt) return }
// AddMessage adds message between selfID and peerID to msgDB. If sent is // true, it is a sent message. Otherwise a received message. func (msgDB *MsgDB) AddMessage( selfID, peerID string, date int64, sent bool, message string, sign bool, minDelay, maxDelay int32, ) error { if err := identity.IsMapped(selfID); err != nil { return log.Error(err) } if err := identity.IsMapped(peerID); err != nil { return log.Error(err) } // get self var self int64 if err := msgDB.getNymUIDQuery.QueryRow(selfID).Scan(&self); err != nil { return log.Error(err) } // get peer var peer int64 err := msgDB.getContactUIDQuery.QueryRow(self, peerID).Scan(&peer) if err != nil { return log.Error(err) } // add message var d int64 if sent { d = 1 } var s int64 if sign { s = 1 } var from string var to string if sent { from = selfID to = peerID } else { from = peerID to = selfID } parts := strings.SplitN(message, "\n", 2) subject := parts[0] _, err = msgDB.addMsgQuery.Exec(self, peer, d, d, 0, from, to, date, subject, message, s, minDelay, maxDelay) if err != nil { return log.Error(err) } return nil }
// GetUndeliveredMessage returns the oldest undelivered message for myID from // msgDB. func (msgDB *MsgDB) GetUndeliveredMessage(myID string) ( msgNum int64, contactID string, msg []byte, sign bool, minDelay, maxDelay int32, err error, ) { if err := identity.IsMapped(myID); err != nil { return 0, "", nil, false, 0, 0, log.Error(err) } var mID int64 if err := msgDB.getNymUIDQuery.QueryRow(myID).Scan(&mID); err != nil { return 0, "", nil, false, 0, 0, log.Error(err) } var cID int64 var s int64 err = msgDB.getUndeliveredMsgQuery.QueryRow(mID).Scan(&msgNum, &cID, &msg, &s, &minDelay, &maxDelay) switch { case err == sql.ErrNoRows: return 0, "", nil, false, 0, 0, nil case err != nil: return 0, "", nil, false, 0, 0, log.Error(err) } if s > 0 { sign = true } err = msgDB.getContactMappedQuery.QueryRow(mID, cID).Scan(&contactID) if err != nil { return 0, "", nil, false, 0, 0, log.Error(err) } return }
// AddOutQueue adds the encrypted message encMsg corresponding to the the // plain text message with msgID to the outqueue. func (msgDB *MsgDB) AddOutQueue( myID string, msgID int64, encMsg, nymaddress string, minDelay, maxDelay int32, ) error { if err := identity.IsMapped(myID); err != nil { return log.Error(err) } var mID int64 if err := msgDB.getNymUIDQuery.QueryRow(myID).Scan(&mID); err != nil { return log.Error(err) } tx, err := msgDB.encDB.Begin() if err != nil { return log.Error(err) } if _, err := tx.Stmt(msgDB.updateDeliveryMsgQuery).Exec(0, msgID); err != nil { tx.Rollback() return log.Error(err) } _, err = tx.Stmt(msgDB.addOutQueueQuery).Exec(mID, msgID, encMsg, nymaddress, minDelay, maxDelay) if err != nil { tx.Rollback() return log.Error(err) } if err := tx.Commit(); err != nil { tx.Rollback() return log.Error(err) } return nil }
// GetOutQueue returns the first entry in the outqueue for myID. // Entries which need to be resend are ignored. func (msgDB *MsgDB) GetOutQueue(myID string) ( oqIdx int64, msg, nymaddress string, minDelay, maxDelay int32, envelope bool, err error, ) { if err := identity.IsMapped(myID); err != nil { return 0, "", "", 0, 0, false, log.Error(err) } var mID int64 if err := msgDB.getNymUIDQuery.QueryRow(myID).Scan(&mID); err != nil { return 0, "", "", 0, 0, false, log.Error(err) } var e int64 err = msgDB.getOutQueueQuery.QueryRow(mID).Scan(&oqIdx, &msg, &nymaddress, &minDelay, &maxDelay, &e) switch { case err == sql.ErrNoRows: return 0, "", "", 0, 0, false, nil case err != nil: return 0, "", "", 0, 0, false, log.Error(err) } if e > 0 { envelope = true } return }
// GetMsgIDs returns all message IDs (sqlite row IDs) for the user ID myID. func (msgDB *MsgDB) GetMsgIDs(myID string) ([]*MsgID, error) { if err := identity.IsMapped(myID); err != nil { return nil, log.Error(err) } var uid int if err := msgDB.getNymUIDQuery.QueryRow(myID).Scan(&uid); err != nil { return nil, log.Error(err) } rows, err := msgDB.getMsgsQuery.Query(uid) if err != nil { return nil, log.Error(err) } var msgIDs []*MsgID defer rows.Close() for rows.Next() { var ( id int64 from string to string d int64 s int64 date int64 subject string r int64 ) err = rows.Scan(&id, &from, &to, &d, &s, &date, &subject, &r) if err != nil { return nil, log.Error(err) } var ( incoming bool sent bool read bool ) if d == 0 { incoming = true } if s > 0 { sent = true } if r > 0 { read = true } msgIDs = append(msgIDs, &MsgID{ MsgID: id, From: from, To: to, Incoming: incoming, Sent: sent, Date: date, Subject: subject, Read: read, }) } if err := rows.Err(); err != nil { return nil, log.Error(err) } return msgIDs, nil }
// GetMessageIDCache retursn the message ID cache for the myID and contactID // pair. func (msgDB *MsgDB) GetMessageIDCache(myID, contactID string) ( map[string]bool, error, ) { if err := identity.IsMapped(myID); err != nil { return nil, log.Error(err) } if contactID != "" { if err := identity.IsMapped(contactID); err != nil { return nil, log.Error(err) } } // get MyID var mID int if err := msgDB.getNymUIDQuery.QueryRow(myID).Scan(&mID); err != nil { return nil, log.Error(err) } // get ContactID var cID int if contactID != "" { err := msgDB.getContactUIDQuery.QueryRow(mID, contactID).Scan(&cID) if err != nil { return nil, log.Error(err) } } // get cache rows, err := msgDB.getMessageIDCacheQuery.Query(mID, cID) if err != nil { return nil, log.Error(err) } cache := make(map[string]bool) defer rows.Close() for rows.Next() { var messageID string if err := rows.Scan(&messageID); err != nil { return nil, log.Error(err) } cache[messageID] = true } if err := rows.Err(); err != nil { return nil, log.Error(err) } return cache, nil }
// AddContact adds or updates a contact in msgDB. func (msgDB *MsgDB) AddContact( myID, mappedID, unmappedID, fullName string, contactType ContactType, ) error { if err := identity.IsMapped(myID); err != nil { return log.Error(err) } if err := identity.IsMapped(mappedID); err != nil { return log.Error(err) } if unmappedID == "" { return log.Error("msgdb: unmappedID must be defined") } // make sure mappedID and unmappedID fit together mID, err := identity.Map(unmappedID) if err != nil { return log.Error(err) } if mID != mappedID { return log.Errorf("msgdb: identity.Map(%s) != %s", unmappedID, mappedID) } // get MyID var uid int if err := msgDB.getNymUIDQuery.QueryRow(myID).Scan(&uid); err != nil { return log.Error(err) } // add contact res, err := msgDB.updateContactQuery.Exec(unmappedID, fullName, contactType, uid, mappedID) if err != nil { return log.Error(err) } nRows, err := res.RowsAffected() if err != nil { return log.Error(err) } if nRows == 0 { _, err := msgDB.insertContactQuery.Exec(uid, mappedID, unmappedID, fullName, contactType) if err != nil { return log.Error(err) } } return nil }
// RemoveContact removes a contact between myID and contactID (normal or // blocked) from the msgDB. func (msgDB *MsgDB) RemoveContact(myID, contactID string) error { if err := identity.IsMapped(myID); err != nil { return log.Error(err) } if err := identity.IsMapped(contactID); err != nil { return log.Error(err) } // get MyID var uid int if err := msgDB.getNymUIDQuery.QueryRow(myID).Scan(&uid); err != nil { return log.Error(err) } // delete contact (-> gray list) if _, err := msgDB.delContactQuery.Exec(uid, contactID); err != nil { return log.Error(err) } return nil }
// SetUpkeepAccounts sets the last execution time of 'upkeep accounts' to t. func (msgDB *MsgDB) SetUpkeepAccounts(myID string, t int64) error { if err := identity.IsMapped(myID); err != nil { return log.Error(err) } if _, err := msgDB.setUpkeepAccountsQuery.Exec(t, myID); err != nil { return log.Error(err) } return nil }
// GetUpkeepAccounts retrieves the last execution time of 'upkeep accounts'. func (msgDB *MsgDB) GetUpkeepAccounts(myID string) (int64, error) { if err := identity.IsMapped(myID); err != nil { return 0, log.Error(err) } var t int64 if err := msgDB.getUpkeepAccountsQuery.QueryRow(myID).Scan(&t); err != nil { return 0, log.Error(err) } return t, nil }
// RemoveMessageIDCache removes all entries from the message ID cache for the // myID and contactID pair which are older than messageID. func (msgDB *MsgDB) RemoveMessageIDCache( myID, contactID, messageID string, ) error { if err := identity.IsMapped(myID); err != nil { return log.Error(err) } if contactID != "" { if err := identity.IsMapped(contactID); err != nil { return log.Error(err) } } if messageID == "" { return log.Error(ErrNilMessageID) } // get MyID var mID int if err := msgDB.getNymUIDQuery.QueryRow(myID).Scan(&mID); err != nil { return log.Error(err) } // get ContactID var cID int if contactID != "" { err := msgDB.getContactUIDQuery.QueryRow(mID, contactID).Scan(&cID) if err != nil { return log.Error(err) } } // get entry for given messageID var entry int64 err := msgDB.getMessageIDCacheEntryQuery.QueryRow(mID, cID, messageID).Scan(&entry) if err != nil { return log.Error(err) } // remove all entries older than messageID _, err = msgDB.removeMessageIDCacheQuery.Exec(mID, cID, entry) if err != nil { return log.Error(err) } return nil }
// ClearResendOutQueue clears the resend status in the outqueue for myID. func (msgDB *MsgDB) ClearResendOutQueue(myID string) error { if err := identity.IsMapped(myID); err != nil { return log.Error(err) } var mID int64 if err := msgDB.getNymUIDQuery.QueryRow(myID).Scan(&mID); err != nil { return log.Error(err) } if _, err := msgDB.clearResendOutQueueQuery.Exec(mID); err != nil { return log.Error(err) } return nil }
// GetContact retrieves the (possibly blocked) contact contactID for myID. func (msgDB *MsgDB) GetContact(myID, contactID string) ( unmappedID, fullName string, contactType ContactType, err error, ) { if err := identity.IsMapped(myID); err != nil { return "", "", WhiteList, log.Error(err) } if err := identity.IsMapped(contactID); err != nil { return "", "", WhiteList, log.Error(err) } // get MyID var uid int if err := msgDB.getNymUIDQuery.QueryRow(myID).Scan(&uid); err != nil { return "", "", WhiteList, log.Error(err) } // get contacts var ct int64 err = msgDB.getContactQuery.QueryRow(uid, contactID).Scan(&unmappedID, &fullName, &ct) switch { case err == sql.ErrNoRows: return "", "", WhiteList, nil case err != nil: return "", "", WhiteList, log.Error(err) } switch ct { case 0: contactType = WhiteList case 1: contactType = GrayList case 2: contactType = BlackList default: return "", "", WhiteList, log.Error("msgdb: unknown contact type found") } return }
// AddAccount adds an account for myID and contactID (which can be nil) with // given privkey on server. func (msgDB *MsgDB) AddAccount( myID, contactID string, privkey *[ed25519.PrivateKeySize]byte, server string, secret *[64]byte, minDelay, maxDelay int32, ) error { if err := identity.IsMapped(myID); err != nil { return log.Error(err) } if contactID != "" { if err := identity.IsMapped(contactID); err != nil { return log.Error(err) } } // get MyID var mID int if err := msgDB.getNymUIDQuery.QueryRow(myID).Scan(&mID); err != nil { return log.Error(err) } // get ContactID var cID int if contactID != "" { err := msgDB.getContactUIDQuery.QueryRow(mID, contactID).Scan(&cID) if err != nil { return log.Error(err) } } // add account _, err := msgDB.addAccountQuery.Exec(mID, cID, base64.Encode(privkey[:]), server, base64.Encode(secret[:]), minDelay, maxDelay, 0, 0) if err != nil { return log.Error(err) } return nil }
// AddInQueue adds the given message corressponding to myID and contactID (can // be nil) to the inqueue. func (msgDB *MsgDB) AddInQueue(myID, contactID string, date int64, msg string) error { if err := identity.IsMapped(myID); err != nil { return log.Error(err) } if contactID != "" { if err := identity.IsMapped(contactID); err != nil { return log.Error(err) } } var mID int64 if err := msgDB.getNymUIDQuery.QueryRow(myID).Scan(&mID); err != nil { return log.Error(err) } var cID int64 if contactID != "" { if err := msgDB.getContactUIDQuery.QueryRow(mID, contactID).Scan(&cID); err != nil { return log.Error(err) } } if _, err := msgDB.addInQueueQuery.Exec(mID, cID, date, msg); err != nil { return log.Error(err) } return nil }
// RemoveInQueue remove the entry with index iqIdx from inqueue and adds the // descrypted message plainMsg to msgDB (if drop is not true). func (msgDB *MsgDB) RemoveInQueue( iqIdx int64, plainMsg, fromID string, drop bool, ) error { if err := identity.IsMapped(fromID); err != nil { return log.Error(err) } var mID int64 var cID int64 var date int64 err := msgDB.getInQueueIDsQuery.QueryRow(iqIdx).Scan(&mID, &cID, &date) if err != nil { return log.Error(err) } err = msgDB.getContactUIDQuery.QueryRow(mID, fromID).Scan(&cID) if err != nil { return log.Error(err) } tx, err := msgDB.encDB.Begin() if err != nil { return log.Error(err) } var to string if err := tx.Stmt(msgDB.getNymMappedQuery).QueryRow(mID).Scan(&to); err != nil { tx.Rollback() return log.Error(err) } // TODO: handle signatures parts := strings.SplitN(plainMsg, "\n", 2) subject := parts[0] if !drop { _, err = tx.Stmt(msgDB.addMsgQuery).Exec(mID, cID, 0, 0, 0, fromID, to, date, subject, plainMsg, 0, 0, 0) if err != nil { tx.Rollback() return log.Error(err) } } if _, err := tx.Stmt(msgDB.removeInQueueQuery).Exec(iqIdx); err != nil { tx.Rollback() return log.Error(err) } if err := tx.Commit(); err != nil { tx.Rollback() return log.Error(err) } return nil }
// DelNym deletes the nym mappedID and all associated contacts and messages! func (msgDB *MsgDB) DelNym(mappedID string) error { if err := identity.IsMapped(mappedID); err != nil { return log.Error(err) } unmappedID, _, err := msgDB.GetNym(mappedID) if err != nil { return err } if unmappedID == "" { return log.Errorf("msgdb: nym %s unkown", mappedID) } if _, err := msgDB.delNymQuery.Exec(mappedID); err != nil { return log.Error(err) } return nil }
// Check that the content of the UID message is consistent with it's version. func (msg *Message) Check() error { // we only support version 1.0 at this stage if msg.UIDContent.VERSION != "1.0" { return log.Errorf("uid: unknown UIDContent.VERSION: %s", msg.UIDContent.VERSION) } // generic checks optional := Optional.String() if msg.UIDContent.PREFERENCES.FORWARDSEC != optional { if msg.UIDContent.MIXADDRESS != "" { return log.Errorf("uid: MIXADDRESS must be null, if FORWARDSEC is not %q", optional) } if msg.UIDContent.NYMADDRESS != "" { return log.Errorf("uid: NYMADDRESS must be null, if FORWARDSEC is not %q", optional) } } if err := identity.IsMapped(msg.UIDContent.IDENTITY); err != nil { return log.Error(err) } // check SIGKEY if msg.UIDContent.SIGKEY.CIPHERSUITE != DefaultCiphersuite { return log.Error("uid: UIDContent.SIGKEY.CIPHERSUITE != DefaultCiphersuite") } if msg.UIDContent.SIGKEY.FUNCTION != "ED25519" { return log.Error("uid: UIDContent.SIGKEY.FUNCTION != \"ED25519\"") } // make sure LASTENTRY is parseable for a non-keyserver localpart. // For keyservers the LASTENTRY can be empty, iff this is the first entry // in the hashchain. lp, _, _ := identity.Split(msg.UIDContent.IDENTITY) if lp != "keyserver" { _, _, _, _, _, _, err := hashchain.SplitEntry(msg.UIDContent.LASTENTRY) if err != nil { return err } } // make sure ESCROWSIGNATURE and USERSIGNATURE are not set at the same time if msg.ESCROWSIGNATURE != "" && msg.USERSIGNATURE != "" { return log.Error("uid: USERSIGNATURE and ESCROWSIGNATURE cannot be set at the same time") } // version 1.0 specific checks return msg.checkV1_0() }
// GetNym gets the unmapped ID and (full) name for a mapped ID. func (msgDB *MsgDB) GetNym(mappedID string) ( unmappedID, fullName string, err error, ) { // make sure the mappedID is mapped if err := identity.IsMapped(mappedID); err != nil { return "", "", log.Error(err) } err = msgDB.getNymQuery.QueryRow(mappedID).Scan(&unmappedID, &fullName) switch { case err == sql.ErrNoRows: return "", "", nil case err != nil: return "", "", log.Error(err) default: return } }
// GetAccounts returns a list of contactIDs (including nil) of all accounts // that exist for myID. func (msgDB *MsgDB) GetAccounts(myID string) ([]string, error) { if err := identity.IsMapped(myID); err != nil { return nil, log.Error(err) } // get MyID var mID int if err := msgDB.getNymUIDQuery.QueryRow(myID).Scan(&mID); err != nil { return nil, log.Error(err) } // get contacts rows, err := msgDB.getAccountsQuery.Query(mID) if err != nil { return nil, log.Error(err) } defer rows.Close() var contacts []string var cIDs []int64 for rows.Next() { var cID int64 if err := rows.Scan(&cID); err != nil { return nil, log.Error(err) } if cID == 0 { contacts = append(contacts, "") } else { cIDs = append(cIDs, cID) } } if err := rows.Err(); err != nil { return nil, log.Error(err) } for _, cID := range cIDs { var contact string err := msgDB.getContactMappedQuery.QueryRow(mID, cID).Scan(&contact) if err != nil { return nil, log.Error(err) } contacts = append(contacts, contact) } return contacts, nil }
// NewNymAddress generates a new nym address. func NewNymAddress( domain string, secret []byte, expire int64, singleUse bool, minDelay, maxDelay int32, id string, pubkey *[ed25519.PublicKeySize]byte, server string, caCert []byte, ) (mixaddress, nymaddress string, err error) { if err := identity.IsMapped(id); err != nil { return "", "", log.Error(err) } if MixAddress == "" { return "", "", log.Error("util: MixAddress undefined") } mixAddresses, err := client.GetMixKeys(MixAddress, caCert) if err != nil { return "", "", log.Error(err) } tmp := nymaddr.AddressTemplate{ Secret: secret, System: 0, MixCandidates: mixAddresses.Addresses, Expire: expire, SingleUse: singleUse, MinDelay: minDelay, MaxDelay: maxDelay, } nymAddress, err := tmp.NewAddress(MailboxAddress(pubkey, server), cipher.SHA256([]byte(id))) if err != nil { return "", "", log.Error(err) } addr, err := nymaddr.ParseAddress(nymAddress) if err != nil { return "", "", log.Error(err) } return string(addr.MixAddress), base64.Encode(nymAddress), nil }
// DelMessage deletes the message from user myID with the given msgNum. func (msgDB *MsgDB) DelMessage(myID string, msgNum int64) error { if err := identity.IsMapped(myID); err != nil { return log.Error(err) } var self int if err := msgDB.getNymUIDQuery.QueryRow(myID).Scan(&self); err != nil { return log.Error(err) } res, err := msgDB.delMsgQuery.Exec(msgNum, self) if err != nil { return log.Error(err) } n, err := res.RowsAffected() if err != nil { return log.Error(err) } if n < 1 { return log.Errorf("msgdb: unknown msgnum %d for user ID %s", msgNum, myID) } return nil }
// GetContacts retrieves all the contacts list (or blacklist, if blocked // equals true) for the given ownID user ID. func (msgDB *MsgDB) GetContacts(myID string, blocked bool) ([]string, error) { if err := identity.IsMapped(myID); err != nil { return nil, log.Error(err) } // get MyID var uid int if err := msgDB.getNymUIDQuery.QueryRow(myID).Scan(&uid); err != nil { return nil, log.Error(err) } var b int if blocked { b = 2 } // get contacts rows, err := msgDB.getContactsQuery.Query(uid, b) if err != nil { return nil, log.Error(err) } var contacts []string defer rows.Close() for rows.Next() { var unmappedID, fullName string if err := rows.Scan(&unmappedID, &fullName); err != nil { return nil, log.Error(err) } if fullName == "" { contacts = append(contacts, unmappedID) } else { contacts = append(contacts, fullName+" <"+unmappedID+">") } } if err := rows.Err(); err != nil { return nil, log.Error(err) } return contacts, nil }
// AddNym adds or updates a mapping from a mapped ID to an unmapped ID and // full name. func (msgDB *MsgDB) AddNym(mappedID, unmappedID, fullName string) error { if mappedID == "" { return log.Error("msgdb: mappedID must be defined") } if unmappedID == "" { return log.Error("msgdb: unmappedID must be defined") } // make sure the mappedID is mapped if err := identity.IsMapped(mappedID); err != nil { return log.Error(err) } // make sure mappedID and unmappedID fit together mID, err := identity.Map(unmappedID) if err != nil { return log.Error(err) } if mID != mappedID { return log.Errorf("msgdb: identity.Map(%s) != %s", unmappedID, mappedID) } // fullName can be empty res, err := msgDB.updateNymQuery.Exec(unmappedID, fullName, mappedID) if err != nil { return log.Error(err) } nRows, err := res.RowsAffected() if err != nil { return log.Error(err) } if nRows == 0 { _, err := msgDB.insertNymQuery.Exec(mappedID, unmappedID, fullName) if err != nil { return log.Error(err) } } return nil }
func mutecryptEncrypt( c *cli.Context, from, to string, passphrase, msg []byte, sign bool, nymAddress string, ) (enc, nymaddress string, err error) { if err := identity.IsMapped(from); err != nil { return "", "", log.Error(err) } if err := identity.IsMapped(to); err != nil { return "", "", log.Error(err) } args := []string{ "--homedir", c.GlobalString("homedir"), "--loglevel", c.GlobalString("loglevel"), "--logdir", c.GlobalString("logdir"), "encrypt", "--from", from, "--to", to, "--nymaddress", nymAddress, } if sign { args = append(args, "--sign") } cmd := exec.Command("mutecrypt", args...) stdin, err := cmd.StdinPipe() if err != nil { return "", "", err } var outbuf bytes.Buffer cmd.Stdout = &outbuf var errbuf bytes.Buffer cmd.Stderr = &errbuf ppR, ppW, err := os.Pipe() if err != nil { return "", "", err } defer ppR.Close() ppW.Write(passphrase) ppW.Close() cmd.ExtraFiles = append(cmd.ExtraFiles, ppR) if err := cmd.Start(); err != nil { return "", "", err } if _, err := stdin.Write(msg); err != nil { return "", "", err } stdin.Close() if err := cmd.Wait(); err != nil { return "", "", fmt.Errorf("%s: %s", err, strings.TrimSpace(errbuf.String())) } // parse nymaddress parts := strings.Split(strings.TrimSpace(errbuf.String()), "\t") if len(parts) != 2 || parts[0] != "NYMADDRESS:" { return "", "", fmt.Errorf("ctrlengine: mutecrypt status output not parsable: %s", strings.TrimSpace(errbuf.String())) } enc = outbuf.String() nymaddress = parts[1] return }
// Create creates a new UID message for the given userID and self-signs it. // It automatically creates all necessary keys. If sigescrow is true, an // escrow key is included in the created UID message. // Necessary randomness is read from rand. func Create( userID string, sigescrow bool, mixaddress, nymaddress string, pfsPreference PFSPreference, lastEntry string, rand io.Reader, ) (*Message, error) { var msg Message var err error // check user ID (identity) if err := identity.IsMapped(userID); err != nil { return nil, log.Error(err) } msg.UIDContent.VERSION = ProtocolVersion msg.UIDContent.MSGCOUNT = 0 // this is the first UIDMessage msg.UIDContent.NOTAFTER = uint64(times.OneYearLater()) // TODO: make this settable! msg.UIDContent.NOTBEFORE = 0 // TODO: make this settable if pfsPreference == Optional { msg.UIDContent.MIXADDRESS = mixaddress msg.UIDContent.NYMADDRESS = nymaddress } else { msg.UIDContent.MIXADDRESS = "" msg.UIDContent.NYMADDRESS = "" } msg.UIDContent.IDENTITY = userID if err = msg.UIDContent.SIGKEY.initSigKey(rand); err != nil { return nil, err } msg.UIDContent.PUBKEYS = make([]KeyEntry, 1) if err := msg.UIDContent.PUBKEYS[0].InitDHKey(rand); err != nil { return nil, err } if sigescrow { msg.UIDContent.SIGESCROW = new(KeyEntry) if err = msg.UIDContent.SIGESCROW.initSigKey(rand); err != nil { return nil, err } } // make sure LASTENTRY is parseable for a non-keyserver localpart. // For keyservers the LASTENTRY can be empty, iff this is the first entry // in the hashchain. lp, domain, _ := identity.Split(msg.UIDContent.IDENTITY) if lp != "keyserver" { if _, _, _, _, _, _, err := hashchain.SplitEntry(lastEntry); err != nil { return nil, err } } msg.UIDContent.LASTENTRY = lastEntry // set REPOURIS to the domain of UIDContent.IDENTITY // TODO: support different KeyInit repository configurations msg.UIDContent.REPOURIS = []string{domain} msg.UIDContent.PREFERENCES.FORWARDSEC = pfsPreference.String() msg.UIDContent.PREFERENCES.CIPHERSUITES = []string{DefaultCiphersuite} // TODO: CHAINLINK (later protocol version) // theses signatures are always empty for messages the first UIDMessage msg.ESCROWSIGNATURE = "" msg.USERSIGNATURE = "" selfsig := msg.UIDContent.SIGKEY.ed25519Key.Sign(msg.UIDContent.JSON()) msg.SELFSIGNATURE = base64.Encode(selfsig) // TODO: LINKAUTHORITY return &msg, nil }