Beispiel #1
0
// 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
}
Beispiel #2
0
// 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
}
Beispiel #3
0
// 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
}
Beispiel #4
0
// 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
}
Beispiel #5
0
// 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
}
Beispiel #6
0
// 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
}
Beispiel #7
0
// 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
}
Beispiel #8
0
// 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
}
Beispiel #9
0
// 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
}
Beispiel #10
0
// 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
}
Beispiel #11
0
// 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
}
Beispiel #12
0
// 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
}
Beispiel #13
0
// 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
}
Beispiel #14
0
// 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
}
Beispiel #15
0
// 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
}
Beispiel #16
0
// 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
}
Beispiel #17
0
// 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
}
Beispiel #18
0
// 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
}
Beispiel #19
0
// 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
}
Beispiel #20
0
// 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
}
Beispiel #21
0
// 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
}
Beispiel #22
0
// 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()
}
Beispiel #23
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
	}
}
Beispiel #24
0
// 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
}
Beispiel #25
0
// 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
}
Beispiel #26
0
// 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
}
Beispiel #27
0
// 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
}
Beispiel #28
0
// 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
}
Beispiel #29
0
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
}
Beispiel #30
0
// 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
}