예제 #1
0
func (a *acdb) makeDirectories() error {
	a.Log(acd.DebugTrace, "[TRC] makeDirectories")

	asset, err := a.c.MkdirJSON(a.c.GetRoot(), dataName)
	if err != nil {
		if e, ok := acd.IsCombinedError(err); ok {
			if e.StatusCode != http.StatusConflict {
				return err
			}
		} else {
			return err
		}
	} else {
		a.dataID = asset.ID
	}

	asset, err = a.c.MkdirJSON(a.c.GetRoot(), metadataName)
	if err != nil {
		if e, ok := acd.IsCombinedError(err); ok {
			if e.StatusCode != http.StatusConflict {
				return err
			}
		} else {
			return err
		}
	} else {
		a.metadataID = asset.ID
	}

	return nil
}
예제 #2
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
}
예제 #3
0
func (a *acdb) walk(path string, info os.FileInfo, errIn error) error {
	a.Log(acd.DebugLoud, "[TRC] walk")

	if errIn != nil {
		fmt.Printf("skipping %v error: %v\n", path, errIn)
		return nil
	}

	var (
		payload []byte
		digest  *[sha256.Size]byte
		err     error
	)

	switch {
	case info.Mode()&os.ModeDir == os.ModeDir:
		// dir
		err = a.me.Dir(path, info)
		if err != nil {
			break
		}

	case info.Mode()&os.ModeSymlink == os.ModeSymlink:
		// symlink
		err = a.me.Symlink(path, info)
		if err != nil {
			break
		}

	case info.Mode().IsRegular() && info.Size() == 0:
		// zero sized file
		err = a.me.File(path, info, "", nil)
		if err != nil {
			break
		}

	case info.Mode().IsRegular():
		// regular file

		// external pointer AND digest
		digest, err = goutil.FileHMACSHA256(path, a.keys.Dedup[:])
		if err != nil {
			break
		}

		payload, err = shared.FileNaClEncrypt(path, a.compress,
			&a.keys.Data)
		if err != nil {
			break
		}

		mime, _, err := goutil.FileCompressible(path)
		if err != nil {
			break
		}

		err = a.me.File(path, info, mime, digest)
		if err != nil {
			break
		}

	default:
		fmt.Printf("skipping %v: unsuported file type\n", path)

		return nil
	}

	if err != nil {
		fmt.Printf("skipping %v: %v\n", path, err)
		return nil
	}

	var d, ds string
	if digest != nil {
		d = hex.EncodeToString(digest[:])
	}

	if digest != nil {
		asset, err := a.c.UploadJSON(a.dataID, d, payload)
		if err != nil {
			if e, ok := acd.IsCombinedError(err); ok {
				if e.StatusCode != http.StatusConflict {
					fmt.Printf("skipping %v: %v\n",
						path, err)
					return nil
				}
				ds += " deduped "
			} else {
				fmt.Printf("should not happen %T: %v\n",
					err, err)
				return nil
			}
		} else {
			ds += " new "
		}

		_ = asset
	}

	if a.verbose {
		if digest != nil {
			ds += "=> " + d
		}
		fmt.Printf("%v %15v %v%v\n",
			info.Mode(),
			info.Size(),
			path,
			ds)
	}

	return nil
}