Ejemplo n.º 1
0
func (ce *CtrlEngine) upkeepAccounts(
	unmappedID, period, remaining string,
	statfp io.Writer,
) error {
	mappedID, err := identity.Map(unmappedID)
	if err != nil {
		return err
	}

	exec, now, err := checkExecution(mappedID, period,
		func(mappedID string) (int64, error) {
			return ce.msgDB.GetUpkeepAccounts(mappedID)
		})
	if err != nil {
		return err
	}
	if !exec {
		log.Info(statfp, "ctrlengine: upkeep accounts not due")
		fmt.Fprintf(statfp, "ctrlengine: upkeep accounts not due\n")
		return nil
	}

	remain, err := time.ParseDuration(remaining)
	if err != nil {
		return err
	}

	contacts, err := ce.msgDB.GetAccounts(mappedID)
	if err != nil {
		return err
	}

	for _, contact := range contacts {
		privkey, server, _, _, _, _, err := ce.msgDB.GetAccount(mappedID, contact)
		if err != nil {
			return err
		}
		last, err := ce.msgDB.GetAccountTime(mappedID, contact)
		if err != nil {
			return err
		}
		if last == 0 {
			last, err = mixclient.AccountStat(privkey, server, def.CACert)
			if err != nil {
				return err
			}
			err := ce.msgDB.SetAccountTime(mappedID, contact, last)
			if err != nil {
				return err
			}
		}
		if times.Now()+int64(remain.Seconds()) >= last {
			token, err := wallet.GetToken(ce.client, def.AccdUsage, def.AccdOwner)
			if err != nil {
				return err
			}
			_, err = mixclient.PayAccount(privkey, token.Token, server, def.CACert)
			if err != nil {
				ce.client.UnlockToken(token.Hash)
				return log.Error(err)
			}
			ce.client.DelToken(token.Hash)
			last, err = mixclient.AccountStat(privkey, server, def.CACert)
			if err != nil {
				return err
			}
			err = ce.msgDB.SetAccountTime(mappedID, contact, last)
			if err != nil {
				return err
			}
		}
	}

	// record time of execution
	if err := ce.msgDB.SetUpkeepAccounts(mappedID, now); err != nil {
		return err
	}

	return nil
}
Ejemplo n.º 2
0
func (ce *CtrlEngine) uidNew(
	c *cli.Context,
	minDelay, maxDelay int32,
	host string,
) error {
	// make sure the ID is well-formed
	unmapped := c.String("id")
	id, domain, err := identity.MapPlus(unmapped)
	if err != nil {
		return err
	}

	// sync corresponding hashchain
	if id != "keyserver" {
		if err := ce.upkeepHashchain(c, domain, c.String("host")); err != nil {
			return err
		}
	}

	// check that ID has not been registered already by the same user
	unmappedID, _, err := ce.msgDB.GetNym(id)
	if err != nil {
		return err
	}
	if unmappedID != "" {
		return log.Error(ErrUserIDOwned)
	}

	// check that ID has not been registered already by other user
	err = mutecryptHashchainSearch(c, id, c.String("host"), ce.passphrase)
	if err == nil {
		return log.Error(ErrUserIDTaken)
	}

	// get token from wallet
	token, err := wallet.GetToken(ce.client, def.AccdUsage, def.AccdOwner)
	if err != nil {
		return err
	}

	// register account for  UID
	_, privkey, err := ed25519.GenerateKey(cipher.RandReader)
	if err != nil {
		return log.Error(err)
	}
	server, err := mixclient.PayAccount(privkey, token.Token, "", def.CACert)
	if err != nil {
		ce.client.UnlockToken(token.Hash)
		return log.Error(err)
	}
	ce.client.DelToken(token.Hash)

	// generate secret for account
	var secret [64]byte
	if _, err := io.ReadFull(cipher.RandReader, secret[:]); err != nil {
		return err
	}

	// get mixaddress and nymaddress for KeyInit message
	expire := times.ThirtyDaysLater() // TODO: make this settable
	singleUse := false                // TODO correct?
	var pubkey [ed25519.PublicKeySize]byte
	copy(pubkey[:], privkey[32:])
	mixaddress, nymaddress, err := util.NewNymAddress(domain, secret[:], expire,
		singleUse, minDelay, maxDelay, id, &pubkey, server, def.CACert)
	if err != nil {
		return err
	}

	// generate UID
	err = mutecryptNewUID(c, ce.passphrase, id, domain, host, mixaddress,
		nymaddress, ce.client)
	if err != nil {
		return err
	}

	// save name mapping
	if err := ce.msgDB.AddNym(id, unmapped, c.String("full-name")); err != nil {
		return err
	}

	// register account for UID
	err = ce.msgDB.AddAccount(id, "", privkey, server, &secret,
		minDelay, maxDelay)
	if err != nil {
		return err
	}

	// set active UID, if this was the first UID
	active, err := ce.msgDB.GetValue(msgdb.ActiveUID)
	if err != nil {
		return err
	}
	if active == "" {
		if err := ce.msgDB.AddValue(msgdb.ActiveUID, unmapped); err != nil {
			return err
		}
	}
	return nil
}