Ejemplo n.º 1
0
// uploadSecrets encrypts and uploads the secrets to acd for safe keeping.
func (a *acdb) uploadSecrets() error {
	a.Log(acd.DebugTrace, "[TRC] uploadSecrets")

	fmt.Printf("Cloud Drive does not have a copy of the secrets.  Please enter " +
		"the password to encrypt the secrets.  Loss of this password is " +
		"unrecoverable!\n")

	p, err := shared.PromptPassword(true)
	if err != nil {
		return err
	}
	defer func() {
		goutil.Zero(p)
	}()

	blob, err := a.keys.Encrypt(p, 32768, 16, 2)
	if err != nil {
		return err
	}

	asset, err := a.c.UploadJSON(a.metadataID, secretsName, blob)
	if err != nil {
		if e, ok := acd.IsCombinedError(err); ok {
			if e.StatusCode != http.StatusConflict {
				return fmt.Errorf("secrets appeared unexpectedly")
			}
		}
	}

	a.Log(acd.DebugTrace, "[TRC] uploadSecrets object: %v", asset.ID)

	return nil
}
Ejemplo n.º 2
0
func (a *acdb) downloadSecrets() error {
	a.Log(acd.DebugTrace, "[TRC] downloadSecrets")

	asset, err := a.c.GetMetadataFS(metadataName + "/" + secretsName)
	if err != nil {
		if err == acd.ErrNotFound {
			return a.uploadSecrets()
		}
		return fmt.Errorf("remote object not found")
	}
	a.Log(acd.DebugTrace, "[TRC] found asset: %v -> %v\n",
		asset.ID,
		asset.Name)
	blob, err := a.c.DownloadJSON(asset.ID)
	if err != nil {
		return err
	}

	var p []byte
	defer func() {
		goutil.Zero(p)
	}()

	for {
		p, err = shared.ReadPassword()
		if err == nil {
			break
		}

		if !os.IsNotExist(err) {
			return err
		}

		fmt.Printf("There is no local password file.  Please enter " +
			"password to verify the integrity of the remote " +
			"secrets.\n")
		p, err = shared.PromptPassword(false)
		if err != nil {
			return err
		}
		err = a.verifySecrets(p, blob)
		if err != nil {
			fmt.Printf("invalid password: %v\n",
				err)
			continue
		}
		return shared.WritePassword(p)
	}

	return a.verifySecrets(p, blob)
}