Esempio n. 1
0
func getPermissions(driveFile *gdrive.File) (os.FileMode, error) {
	permStr, err := driveFile.GetProperty("Permissions")
	if err != nil {
		return 0, err
	}
	perm, err := strconv.ParseInt(permStr, 8, 16)
	return os.FileMode(perm), err
}
Esempio n. 2
0
// Returns the initialization vector (for encryption) for the given file.
// We store the initialization vector as a hex-encoded property in the
// file so that we don't need to download the file's contents to find the
// IV.
func getInitializationVector(driveFile *gdrive.File) ([]byte, error) {
	ivhex, err := driveFile.GetProperty("IV")
	if err != nil {
		return nil, err
	}
	iv, err := hex.DecodeString(ivhex)
	if err != nil {
		return nil, err
	}
	if len(iv) != aes.BlockSize {
		return nil, fmt.Errorf("unexpected length of IV %d", len(iv))
	}
	return iv, nil
}
Esempio n. 3
0
func checkFile(f *gdrive.File) int {
	hasSuffix := strings.HasSuffix(f.Path, encryptionSuffix)
	_, err := f.GetProperty("IV")
	hasIV := err == nil

	if hasSuffix && !hasIV {
		fmt.Fprintf(os.Stderr, "skicka: %s: has filename suffix \"%s\" but no IV property\n",
			f.Path, encryptionSuffix)
		return 1
	} else if hasIV && !hasSuffix {
		fmt.Fprintf(os.Stderr, "skicka: %s: has IV property but no filename suffix \"%s\"\n",
			f.Path, encryptionSuffix)
		return 1
	}
	return 0
}
Esempio n. 4
0
// If a file is encrypted, it should both have the initialization vector used
// to encrypt it stored as a Drive file property and have encryptionSuffix at the end
// of its filename. This function checks both of these and returns an error if
// these indicators are inconsistent; otherwise, it returns true/false
// accordingly.
func isEncrypted(file *gdrive.File) (bool, error) {
	if _, err := file.GetProperty("IV"); err == nil {
		if strings.HasSuffix(file.Path, encryptionSuffix) {
			return true, nil
		}
		return false, fmt.Errorf("has IV property but doesn't " +
			"end with .aes256 suffix")
	} else if strings.HasSuffix(file.Path, encryptionSuffix) {
		// This could actually happen with an interrupted upload
		// with 403 errors and the case where a file is created
		// even though a 403 happened, if we don't get to delete
		// the file before exiting...
		return false, fmt.Errorf("ends with .aes256 suffix but doesn't " +
			"have IV property")
	}
	return false, nil
}
Esempio n. 5
0
// If we didn't shut down cleanly before, there may be files that
// don't have the various properties we expect. Check for that now
// and patch things up as needed.
func createMissingProperties(f *gdrive.File, mode os.FileMode, encrypt bool) error {
	if !f.IsFolder() && encrypt {
		if _, err := f.GetProperty("IV"); err != nil {
			if f.FileSize == 0 {
				// Compute a unique IV for the file.
				iv := getRandomBytes(aes.BlockSize)
				ivhex := hex.EncodeToString(iv)

				debug.Printf("Creating IV property for file %s, "+
					"which doesn't have one.", f.Path)
				err := gd.AddProperty("IV", ivhex, f)
				if err != nil {
					return err
				}
			} else {
				// This is state of affairs really shouldn't ever happen, but
				// if somehow it does, it's important that we catch it: the
				// file is missing the IV property, but has some
				// contents. Presumably the IV is at the start of the file
				// contents and we could initialize the property from that
				// here, but any successfully created file should already have
				// the property, so we'll just error out, since it's not clear
				// what's going on here...
				return fmt.Errorf("encrypted file on Drive is missing" +
					"IV property, but has non-zero length. Can't create the IV " +
					"property without examining file contents.")
			}
		}
	}
	if _, err := f.GetProperty("Permissions"); err != nil {
		debug.Printf("Creating Permissions property for file %s, "+
			"which doesn't have one.", f.Path)
		err := gd.AddProperty("Permissions", fmt.Sprintf("%#o", mode&os.ModePerm), f)
		if err != nil {
			return err
		}
	}
	return nil
}