mirror of
https://github.com/rclone/rclone.git
synced 2025-02-04 05:08:23 +02:00
crypt: get rid of the unused Cipher interface as it obfuscated the code
This commit is contained in:
parent
bbb6f94377
commit
44b1a591a8
@ -71,30 +71,6 @@ type ReadSeekCloser interface {
|
|||||||
// OpenRangeSeek opens the file handle at the offset with the limit given
|
// OpenRangeSeek opens the file handle at the offset with the limit given
|
||||||
type OpenRangeSeek func(ctx context.Context, offset, limit int64) (io.ReadCloser, error)
|
type OpenRangeSeek func(ctx context.Context, offset, limit int64) (io.ReadCloser, error)
|
||||||
|
|
||||||
// Cipher is used to swap out the encryption implementations
|
|
||||||
type Cipher interface {
|
|
||||||
// EncryptFileName encrypts a file path
|
|
||||||
EncryptFileName(string) string
|
|
||||||
// DecryptFileName decrypts a file path, returns error if decrypt was invalid
|
|
||||||
DecryptFileName(string) (string, error)
|
|
||||||
// EncryptDirName encrypts a directory path
|
|
||||||
EncryptDirName(string) string
|
|
||||||
// DecryptDirName decrypts a directory path, returns error if decrypt was invalid
|
|
||||||
DecryptDirName(string) (string, error)
|
|
||||||
// EncryptData
|
|
||||||
EncryptData(io.Reader) (io.Reader, error)
|
|
||||||
// DecryptData
|
|
||||||
DecryptData(io.ReadCloser) (io.ReadCloser, error)
|
|
||||||
// DecryptDataSeek decrypt at a given position
|
|
||||||
DecryptDataSeek(ctx context.Context, open OpenRangeSeek, offset, limit int64) (ReadSeekCloser, error)
|
|
||||||
// EncryptedSize calculates the size of the data when encrypted
|
|
||||||
EncryptedSize(int64) int64
|
|
||||||
// DecryptedSize calculates the size of the data when decrypted
|
|
||||||
DecryptedSize(int64) (int64, error)
|
|
||||||
// NameEncryptionMode returns the used mode for name handling
|
|
||||||
NameEncryptionMode() NameEncryptionMode
|
|
||||||
}
|
|
||||||
|
|
||||||
// NameEncryptionMode is the type of file name encryption in use
|
// NameEncryptionMode is the type of file name encryption in use
|
||||||
type NameEncryptionMode int
|
type NameEncryptionMode int
|
||||||
|
|
||||||
@ -136,7 +112,8 @@ func (mode NameEncryptionMode) String() (out string) {
|
|||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
type cipher struct {
|
// Cipher defines an encoding and decoding cipher for the crypt backend
|
||||||
|
type Cipher struct {
|
||||||
dataKey [32]byte // Key for secretbox
|
dataKey [32]byte // Key for secretbox
|
||||||
nameKey [32]byte // 16,24 or 32 bytes
|
nameKey [32]byte // 16,24 or 32 bytes
|
||||||
nameTweak [nameCipherBlockSize]byte // used to tweak the name crypto
|
nameTweak [nameCipherBlockSize]byte // used to tweak the name crypto
|
||||||
@ -148,8 +125,8 @@ type cipher struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// newCipher initialises the cipher. If salt is "" then it uses a built in salt val
|
// newCipher initialises the cipher. If salt is "" then it uses a built in salt val
|
||||||
func newCipher(mode NameEncryptionMode, password, salt string, dirNameEncrypt bool) (*cipher, error) {
|
func newCipher(mode NameEncryptionMode, password, salt string, dirNameEncrypt bool) (*Cipher, error) {
|
||||||
c := &cipher{
|
c := &Cipher{
|
||||||
mode: mode,
|
mode: mode,
|
||||||
cryptoRand: rand.Reader,
|
cryptoRand: rand.Reader,
|
||||||
dirNameEncrypt: dirNameEncrypt,
|
dirNameEncrypt: dirNameEncrypt,
|
||||||
@ -172,7 +149,7 @@ func newCipher(mode NameEncryptionMode, password, salt string, dirNameEncrypt bo
|
|||||||
//
|
//
|
||||||
// Note that empty passsword makes all 0x00 keys which is used in the
|
// Note that empty passsword makes all 0x00 keys which is used in the
|
||||||
// tests.
|
// tests.
|
||||||
func (c *cipher) Key(password, salt string) (err error) {
|
func (c *Cipher) Key(password, salt string) (err error) {
|
||||||
const keySize = len(c.dataKey) + len(c.nameKey) + len(c.nameTweak)
|
const keySize = len(c.dataKey) + len(c.nameKey) + len(c.nameTweak)
|
||||||
var saltBytes = defaultSalt
|
var saltBytes = defaultSalt
|
||||||
if salt != "" {
|
if salt != "" {
|
||||||
@ -196,12 +173,12 @@ func (c *cipher) Key(password, salt string) (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// getBlock gets a block from the pool of size blockSize
|
// getBlock gets a block from the pool of size blockSize
|
||||||
func (c *cipher) getBlock() []byte {
|
func (c *Cipher) getBlock() []byte {
|
||||||
return c.buffers.Get().([]byte)
|
return c.buffers.Get().([]byte)
|
||||||
}
|
}
|
||||||
|
|
||||||
// putBlock returns a block to the pool of size blockSize
|
// putBlock returns a block to the pool of size blockSize
|
||||||
func (c *cipher) putBlock(buf []byte) {
|
func (c *Cipher) putBlock(buf []byte) {
|
||||||
if len(buf) != blockSize {
|
if len(buf) != blockSize {
|
||||||
panic("bad blocksize returned to pool")
|
panic("bad blocksize returned to pool")
|
||||||
}
|
}
|
||||||
@ -246,7 +223,7 @@ func decodeFileName(in string) ([]byte, error) {
|
|||||||
// This means that
|
// This means that
|
||||||
// * filenames with the same name will encrypt the same
|
// * filenames with the same name will encrypt the same
|
||||||
// * filenames which start the same won't have a common prefix
|
// * filenames which start the same won't have a common prefix
|
||||||
func (c *cipher) encryptSegment(plaintext string) string {
|
func (c *Cipher) encryptSegment(plaintext string) string {
|
||||||
if plaintext == "" {
|
if plaintext == "" {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
@ -256,7 +233,7 @@ func (c *cipher) encryptSegment(plaintext string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// decryptSegment decrypts a path segment
|
// decryptSegment decrypts a path segment
|
||||||
func (c *cipher) decryptSegment(ciphertext string) (string, error) {
|
func (c *Cipher) decryptSegment(ciphertext string) (string, error) {
|
||||||
if ciphertext == "" {
|
if ciphertext == "" {
|
||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
@ -283,7 +260,7 @@ func (c *cipher) decryptSegment(ciphertext string) (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Simple obfuscation routines
|
// Simple obfuscation routines
|
||||||
func (c *cipher) obfuscateSegment(plaintext string) string {
|
func (c *Cipher) obfuscateSegment(plaintext string) string {
|
||||||
if plaintext == "" {
|
if plaintext == "" {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
@ -370,7 +347,7 @@ func (c *cipher) obfuscateSegment(plaintext string) string {
|
|||||||
return result.String()
|
return result.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *cipher) deobfuscateSegment(ciphertext string) (string, error) {
|
func (c *Cipher) deobfuscateSegment(ciphertext string) (string, error) {
|
||||||
if ciphertext == "" {
|
if ciphertext == "" {
|
||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
@ -457,7 +434,7 @@ func (c *cipher) deobfuscateSegment(ciphertext string) (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// encryptFileName encrypts a file path
|
// encryptFileName encrypts a file path
|
||||||
func (c *cipher) encryptFileName(in string) string {
|
func (c *Cipher) encryptFileName(in string) string {
|
||||||
segments := strings.Split(in, "/")
|
segments := strings.Split(in, "/")
|
||||||
for i := range segments {
|
for i := range segments {
|
||||||
// Skip directory name encryption if the user chose to
|
// Skip directory name encryption if the user chose to
|
||||||
@ -475,7 +452,7 @@ func (c *cipher) encryptFileName(in string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// EncryptFileName encrypts a file path
|
// EncryptFileName encrypts a file path
|
||||||
func (c *cipher) EncryptFileName(in string) string {
|
func (c *Cipher) EncryptFileName(in string) string {
|
||||||
if c.mode == NameEncryptionOff {
|
if c.mode == NameEncryptionOff {
|
||||||
return in + encryptedSuffix
|
return in + encryptedSuffix
|
||||||
}
|
}
|
||||||
@ -483,7 +460,7 @@ func (c *cipher) EncryptFileName(in string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// EncryptDirName encrypts a directory path
|
// EncryptDirName encrypts a directory path
|
||||||
func (c *cipher) EncryptDirName(in string) string {
|
func (c *Cipher) EncryptDirName(in string) string {
|
||||||
if c.mode == NameEncryptionOff || !c.dirNameEncrypt {
|
if c.mode == NameEncryptionOff || !c.dirNameEncrypt {
|
||||||
return in
|
return in
|
||||||
}
|
}
|
||||||
@ -491,7 +468,7 @@ func (c *cipher) EncryptDirName(in string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// decryptFileName decrypts a file path
|
// decryptFileName decrypts a file path
|
||||||
func (c *cipher) decryptFileName(in string) (string, error) {
|
func (c *Cipher) decryptFileName(in string) (string, error) {
|
||||||
segments := strings.Split(in, "/")
|
segments := strings.Split(in, "/")
|
||||||
for i := range segments {
|
for i := range segments {
|
||||||
var err error
|
var err error
|
||||||
@ -514,7 +491,7 @@ func (c *cipher) decryptFileName(in string) (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// DecryptFileName decrypts a file path
|
// DecryptFileName decrypts a file path
|
||||||
func (c *cipher) DecryptFileName(in string) (string, error) {
|
func (c *Cipher) DecryptFileName(in string) (string, error) {
|
||||||
if c.mode == NameEncryptionOff {
|
if c.mode == NameEncryptionOff {
|
||||||
remainingLength := len(in) - len(encryptedSuffix)
|
remainingLength := len(in) - len(encryptedSuffix)
|
||||||
if remainingLength > 0 && strings.HasSuffix(in, encryptedSuffix) {
|
if remainingLength > 0 && strings.HasSuffix(in, encryptedSuffix) {
|
||||||
@ -526,14 +503,14 @@ func (c *cipher) DecryptFileName(in string) (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// DecryptDirName decrypts a directory path
|
// DecryptDirName decrypts a directory path
|
||||||
func (c *cipher) DecryptDirName(in string) (string, error) {
|
func (c *Cipher) DecryptDirName(in string) (string, error) {
|
||||||
if c.mode == NameEncryptionOff || !c.dirNameEncrypt {
|
if c.mode == NameEncryptionOff || !c.dirNameEncrypt {
|
||||||
return in, nil
|
return in, nil
|
||||||
}
|
}
|
||||||
return c.decryptFileName(in)
|
return c.decryptFileName(in)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *cipher) NameEncryptionMode() NameEncryptionMode {
|
func (c *Cipher) NameEncryptionMode() NameEncryptionMode {
|
||||||
return c.mode
|
return c.mode
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -601,7 +578,7 @@ func (n *nonce) add(x uint64) {
|
|||||||
type encrypter struct {
|
type encrypter struct {
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
in io.Reader
|
in io.Reader
|
||||||
c *cipher
|
c *Cipher
|
||||||
nonce nonce
|
nonce nonce
|
||||||
buf []byte
|
buf []byte
|
||||||
readBuf []byte
|
readBuf []byte
|
||||||
@ -611,7 +588,7 @@ type encrypter struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// newEncrypter creates a new file handle encrypting on the fly
|
// newEncrypter creates a new file handle encrypting on the fly
|
||||||
func (c *cipher) newEncrypter(in io.Reader, nonce *nonce) (*encrypter, error) {
|
func (c *Cipher) newEncrypter(in io.Reader, nonce *nonce) (*encrypter, error) {
|
||||||
fh := &encrypter{
|
fh := &encrypter{
|
||||||
in: in,
|
in: in,
|
||||||
c: c,
|
c: c,
|
||||||
@ -683,7 +660,7 @@ func (fh *encrypter) finish(err error) (int, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Encrypt data encrypts the data stream
|
// Encrypt data encrypts the data stream
|
||||||
func (c *cipher) EncryptData(in io.Reader) (io.Reader, error) {
|
func (c *Cipher) EncryptData(in io.Reader) (io.Reader, error) {
|
||||||
in, wrap := accounting.UnWrap(in) // unwrap the accounting off the Reader
|
in, wrap := accounting.UnWrap(in) // unwrap the accounting off the Reader
|
||||||
out, err := c.newEncrypter(in, nil)
|
out, err := c.newEncrypter(in, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -698,7 +675,7 @@ type decrypter struct {
|
|||||||
rc io.ReadCloser
|
rc io.ReadCloser
|
||||||
nonce nonce
|
nonce nonce
|
||||||
initialNonce nonce
|
initialNonce nonce
|
||||||
c *cipher
|
c *Cipher
|
||||||
buf []byte
|
buf []byte
|
||||||
readBuf []byte
|
readBuf []byte
|
||||||
bufIndex int
|
bufIndex int
|
||||||
@ -709,7 +686,7 @@ type decrypter struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// newDecrypter creates a new file handle decrypting on the fly
|
// newDecrypter creates a new file handle decrypting on the fly
|
||||||
func (c *cipher) newDecrypter(rc io.ReadCloser) (*decrypter, error) {
|
func (c *Cipher) newDecrypter(rc io.ReadCloser) (*decrypter, error) {
|
||||||
fh := &decrypter{
|
fh := &decrypter{
|
||||||
rc: rc,
|
rc: rc,
|
||||||
c: c,
|
c: c,
|
||||||
@ -737,7 +714,7 @@ func (c *cipher) newDecrypter(rc io.ReadCloser) (*decrypter, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// newDecrypterSeek creates a new file handle decrypting on the fly
|
// newDecrypterSeek creates a new file handle decrypting on the fly
|
||||||
func (c *cipher) newDecrypterSeek(ctx context.Context, open OpenRangeSeek, offset, limit int64) (fh *decrypter, err error) {
|
func (c *Cipher) newDecrypterSeek(ctx context.Context, open OpenRangeSeek, offset, limit int64) (fh *decrypter, err error) {
|
||||||
var rc io.ReadCloser
|
var rc io.ReadCloser
|
||||||
doRangeSeek := false
|
doRangeSeek := false
|
||||||
setLimit := false
|
setLimit := false
|
||||||
@ -1012,7 +989,7 @@ func (fh *decrypter) finishAndClose(err error) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// DecryptData decrypts the data stream
|
// DecryptData decrypts the data stream
|
||||||
func (c *cipher) DecryptData(rc io.ReadCloser) (io.ReadCloser, error) {
|
func (c *Cipher) DecryptData(rc io.ReadCloser) (io.ReadCloser, error) {
|
||||||
out, err := c.newDecrypter(rc)
|
out, err := c.newDecrypter(rc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -1025,7 +1002,7 @@ func (c *cipher) DecryptData(rc io.ReadCloser) (io.ReadCloser, error) {
|
|||||||
// The open function must return a ReadCloser opened to the offset supplied
|
// The open function must return a ReadCloser opened to the offset supplied
|
||||||
//
|
//
|
||||||
// You must use this form of DecryptData if you might want to Seek the file handle
|
// You must use this form of DecryptData if you might want to Seek the file handle
|
||||||
func (c *cipher) DecryptDataSeek(ctx context.Context, open OpenRangeSeek, offset, limit int64) (ReadSeekCloser, error) {
|
func (c *Cipher) DecryptDataSeek(ctx context.Context, open OpenRangeSeek, offset, limit int64) (ReadSeekCloser, error) {
|
||||||
out, err := c.newDecrypterSeek(ctx, open, offset, limit)
|
out, err := c.newDecrypterSeek(ctx, open, offset, limit)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -1034,7 +1011,7 @@ func (c *cipher) DecryptDataSeek(ctx context.Context, open OpenRangeSeek, offset
|
|||||||
}
|
}
|
||||||
|
|
||||||
// EncryptedSize calculates the size of the data when encrypted
|
// EncryptedSize calculates the size of the data when encrypted
|
||||||
func (c *cipher) EncryptedSize(size int64) int64 {
|
func (c *Cipher) EncryptedSize(size int64) int64 {
|
||||||
blocks, residue := size/blockDataSize, size%blockDataSize
|
blocks, residue := size/blockDataSize, size%blockDataSize
|
||||||
encryptedSize := int64(fileHeaderSize) + blocks*(blockHeaderSize+blockDataSize)
|
encryptedSize := int64(fileHeaderSize) + blocks*(blockHeaderSize+blockDataSize)
|
||||||
if residue != 0 {
|
if residue != 0 {
|
||||||
@ -1044,7 +1021,7 @@ func (c *cipher) EncryptedSize(size int64) int64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// DecryptedSize calculates the size of the data when decrypted
|
// DecryptedSize calculates the size of the data when decrypted
|
||||||
func (c *cipher) DecryptedSize(size int64) (int64, error) {
|
func (c *Cipher) DecryptedSize(size int64) (int64, error) {
|
||||||
size -= int64(fileHeaderSize)
|
size -= int64(fileHeaderSize)
|
||||||
if size < 0 {
|
if size < 0 {
|
||||||
return 0, ErrorEncryptedFileTooShort
|
return 0, ErrorEncryptedFileTooShort
|
||||||
@ -1063,7 +1040,6 @@ func (c *cipher) DecryptedSize(size int64) (int64, error) {
|
|||||||
|
|
||||||
// check interfaces
|
// check interfaces
|
||||||
var (
|
var (
|
||||||
_ Cipher = (*cipher)(nil)
|
|
||||||
_ io.ReadCloser = (*decrypter)(nil)
|
_ io.ReadCloser = (*decrypter)(nil)
|
||||||
_ io.Seeker = (*decrypter)(nil)
|
_ io.Seeker = (*decrypter)(nil)
|
||||||
_ fs.RangeSeeker = (*decrypter)(nil)
|
_ fs.RangeSeeker = (*decrypter)(nil)
|
||||||
|
@ -90,7 +90,7 @@ names, or for debugging purposes.`,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// newCipherForConfig constructs a Cipher for the given config name
|
// newCipherForConfig constructs a Cipher for the given config name
|
||||||
func newCipherForConfig(opt *Options) (Cipher, error) {
|
func newCipherForConfig(opt *Options) (*Cipher, error) {
|
||||||
mode, err := NewNameEncryptionMode(opt.FilenameEncryption)
|
mode, err := NewNameEncryptionMode(opt.FilenameEncryption)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -117,7 +117,7 @@ func newCipherForConfig(opt *Options) (Cipher, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewCipher constructs a Cipher for the given config
|
// NewCipher constructs a Cipher for the given config
|
||||||
func NewCipher(m configmap.Mapper) (Cipher, error) {
|
func NewCipher(m configmap.Mapper) (*Cipher, error) {
|
||||||
// Parse config into Options struct
|
// Parse config into Options struct
|
||||||
opt := new(Options)
|
opt := new(Options)
|
||||||
err := configstruct.Set(m, opt)
|
err := configstruct.Set(m, opt)
|
||||||
@ -203,7 +203,7 @@ type Fs struct {
|
|||||||
root string
|
root string
|
||||||
opt Options
|
opt Options
|
||||||
features *fs.Features // optional features
|
features *fs.Features // optional features
|
||||||
cipher Cipher
|
cipher *Cipher
|
||||||
}
|
}
|
||||||
|
|
||||||
// Name of the remote (as passed into NewFs)
|
// Name of the remote (as passed into NewFs)
|
||||||
@ -572,7 +572,7 @@ func (f *Fs) ComputeHash(ctx context.Context, o *Object, src fs.Object, hashType
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return "", errors.Wrap(err, "failed to open object to read nonce")
|
return "", errors.Wrap(err, "failed to open object to read nonce")
|
||||||
}
|
}
|
||||||
d, err := f.cipher.(*cipher).newDecrypter(in)
|
d, err := f.cipher.newDecrypter(in)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
_ = in.Close()
|
_ = in.Close()
|
||||||
return "", errors.Wrap(err, "failed to open object to read nonce")
|
return "", errors.Wrap(err, "failed to open object to read nonce")
|
||||||
@ -605,7 +605,7 @@ func (f *Fs) ComputeHash(ctx context.Context, o *Object, src fs.Object, hashType
|
|||||||
defer fs.CheckClose(in, &err)
|
defer fs.CheckClose(in, &err)
|
||||||
|
|
||||||
// Now encrypt the src with the nonce
|
// Now encrypt the src with the nonce
|
||||||
out, err := f.cipher.(*cipher).newEncrypter(in, &nonce)
|
out, err := f.cipher.newEncrypter(in, &nonce)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", errors.Wrap(err, "failed to make encrypter")
|
return "", errors.Wrap(err, "failed to make encrypter")
|
||||||
}
|
}
|
||||||
|
@ -60,7 +60,7 @@ use it like this
|
|||||||
}
|
}
|
||||||
|
|
||||||
// cryptDecode returns the unencrypted file name
|
// cryptDecode returns the unencrypted file name
|
||||||
func cryptDecode(cipher crypt.Cipher, args []string) error {
|
func cryptDecode(cipher *crypt.Cipher, args []string) error {
|
||||||
output := ""
|
output := ""
|
||||||
|
|
||||||
for _, encryptedFileName := range args {
|
for _, encryptedFileName := range args {
|
||||||
@ -78,7 +78,7 @@ func cryptDecode(cipher crypt.Cipher, args []string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// cryptEncode returns the encrypted file name
|
// cryptEncode returns the encrypted file name
|
||||||
func cryptEncode(cipher crypt.Cipher, args []string) error {
|
func cryptEncode(cipher *crypt.Cipher, args []string) error {
|
||||||
output := ""
|
output := ""
|
||||||
|
|
||||||
for _, fileName := range args {
|
for _, fileName := range args {
|
||||||
|
@ -81,7 +81,7 @@ type ListJSONOpt struct {
|
|||||||
|
|
||||||
// ListJSON lists fsrc using the options in opt calling callback for each item
|
// ListJSON lists fsrc using the options in opt calling callback for each item
|
||||||
func ListJSON(ctx context.Context, fsrc fs.Fs, remote string, opt *ListJSONOpt, callback func(*ListJSONItem) error) error {
|
func ListJSON(ctx context.Context, fsrc fs.Fs, remote string, opt *ListJSONOpt, callback func(*ListJSONItem) error) error {
|
||||||
var cipher crypt.Cipher
|
var cipher *crypt.Cipher
|
||||||
if opt.ShowEncrypted {
|
if opt.ShowEncrypted {
|
||||||
fsInfo, _, _, config, err := fs.ConfigFs(fsrc.Name() + ":" + fsrc.Root())
|
fsInfo, _, _, config, err := fs.ConfigFs(fsrc.Name() + ":" + fsrc.Root())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user