diff --git a/filehelper/fileHelper.go b/filehelper/fileHelper.go index c436bfb936a25a2e99f8c13c7c828fa6c1a932f9..e7df1f655437eb6bb2256a90e72a6d54f45ca49a 100644 --- a/filehelper/fileHelper.go +++ b/filehelper/fileHelper.go @@ -567,3 +567,74 @@ func CleanPath(path string) string { return normalizedPath } + +//UnzipWithDefaultModifiedTime - unzips and sets access time and modified time to time set during zipping files +func UnzipWithDefaultModifiedTime(archive, target string) error { + reader, err := zip.OpenReader(archive) + if err != nil { + logginghelper.LogError(err) + return err + } + mkcDirError := os.MkdirAll(target, 0755) + if mkcDirError != nil { + logginghelper.LogError(mkcDirError) + return mkcDirError + } + for _, file := range reader.File { + filePath := filepath.Join(target, file.Name) + parentPath := path.Dir(CleanPath(filePath)) + + fileInfo := file.FileInfo() + timeHeader := fileInfo.ModTime() + + if !FileAvailabilityCheck(parentPath) { + CreateDirectoryRecursive(parentPath) + } + + if fileInfo.IsDir() { + os.MkdirAll(filePath, file.Mode()) + continue + } + + fileReader, openError := file.Open() + if openError != nil { + logginghelper.LogError(openError) + return openError + } + + targetFile, targetOpenError := os.OpenFile(filePath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, file.Mode()) + if targetOpenError != nil { + logginghelper.LogError(targetOpenError) + return targetOpenError + } + + _, copyError := io.Copy(targetFile, fileReader) + if copyError != nil { + logginghelper.LogError(copyError) + return copyError + } + + targetCloseError := targetFile.Close() + if targetCloseError != nil { + logginghelper.LogError(targetCloseError) + return targetCloseError + } + + fileCloseError := fileReader.Close() + if fileCloseError != nil { + logginghelper.LogError(fileCloseError) + return fileCloseError + } + changeError := os.Chtimes(filePath, timeHeader.Local(), timeHeader.Local()) + if changeError != nil { + logginghelper.LogError(changeError) + return changeError + } + } + closeError := reader.Close() + if closeError != nil { + logginghelper.LogError(closeError) + return closeError + } + return nil +} diff --git a/securityhelper/securityHelper.go b/securityhelper/securityHelper.go index cc904f39c315bb2fd2d90b78ea6a4a45be0b6c37..a9faf70e198217fd059892d83e2fe71779bf7d85 100644 --- a/securityhelper/securityHelper.go +++ b/securityhelper/securityHelper.go @@ -9,6 +9,7 @@ import ( "errors" "os" "strconv" + "time" "corelab.mkcl.org/MKCLOS/coredevelopmentplatform/coreospackage/filehelper" "corelab.mkcl.org/MKCLOS/coredevelopmentplatform/coreospackage/logginghelper" @@ -69,11 +70,11 @@ func AESDecrypt(encodedData, key []byte) ([]byte, error) { } cbc := cipher.NewCBCDecrypter(block, []byte(IV)) - + if len(cipherText)%cbc.BlockSize() != 0 { return nil, errors.New("crypto/cipher: input not full blocks") } - + cbc.CryptBlocks(cipherText, cipherText) length := len(cipherText) @@ -128,16 +129,34 @@ func GetAttributeBasedHash(filePath string) (string, error) { return customFileHash, nil } - // GetAttributeBasedHashBasedOnParameters - return custom hash based on file attributes +// func GetAttributeBasedHashByParameters(fileModTime string, fileSize string) (string, error) { +// modTime, _ := strconv.ParseInt(fileModTime, 10, 64) +// fSize, _ := strconv.ParseInt(fileSize, 10, 64) +// customFileHash := strconv.FormatInt((modTime + fSize), 10) +// return customFileHash, nil +// } + +//GetAttributeBasedHashBasedOnParameters - return custom hash based on file attributes func GetAttributeBasedHashByParameters(fileModTime string, fileSize string) (string, error) { - modTime, _ := strconv.ParseInt(fileModTime, 10, 64) - fSize, _ := strconv.ParseInt(fileSize, 10, 64) - customFileHash := strconv.FormatInt((modTime + fSize), 10) + modTime, parseError := strconv.ParseInt(fileModTime, 10, 64) + if parseError != nil { + logginghelper.LogError("error occured while parsing fileModTime : ", parseError) + return "", parseError + } + cModTime := time.Unix(modTime, 0) + date, time := TimeToMsDosTime(cModTime) + newModTime := MsDosTimeToTime(date, time) + fSize, parseFileSizeError := strconv.ParseInt(fileSize, 10, 64) + if parseFileSizeError != nil { + logginghelper.LogError("error occured while parsing fileModTime : ", parseFileSizeError) + return "", parseFileSizeError + } + // customFileHash := strconv.FormatInt((newModTime + fSize), 10) + customFileHash := strconv.FormatInt(newModTime.Unix(), 10) + strconv.FormatInt(fSize, 10) return customFileHash, nil } - //AESEncryptDefault method to encrypt with default config (securityKey) func AESEncryptDefault(plainText []byte) ([]byte, error) { compressedText, compressionError := Compress(plainText) @@ -173,3 +192,40 @@ func Get128BitHash(data []byte) [16]byte { // hashString := strconv.FormatUint(sum, 6) // return []byte(hashString) // } + +// GetAttributeBasedHashWithRoundedModTime - rounds of the mod time similar to rounding done during zipping +func GetAttributeBasedHashWithRoundedModTime(filePath string) (string, error) { + fileInfo, statErr := os.Stat(filePath) + if statErr != nil { + logginghelper.LogError("error occured while getting stats of file : ", filePath, " : ", statErr) + return "", statErr + } + date, time := TimeToMsDosTime(fileInfo.ModTime()) + newModTime := MsDosTimeToTime(date, time) + fileLength := fileInfo.Size() + customFileHash := strconv.FormatInt(newModTime.Unix(), 10) + strconv.FormatInt(fileLength, 10) + return customFileHash, nil +} + +func TimeToMsDosTime(t time.Time) (fDate uint16, fTime uint16) { + fDate = uint16(t.Day() + int(t.Month())<<5 + (t.Year()-1980)<<9) + fTime = uint16(t.Second()/2 + t.Minute()<<5 + t.Hour()<<11) + return +} + +func MsDosTimeToTime(dosDate, dosTime uint16) time.Time { + return time.Date( + // date bits 0-4: day of month; 5-8: month; 9-15: years since 1980 + int(dosDate>>9+1980), + time.Month(dosDate>>5&0xf), + int(dosDate&0x1f), + + // time bits 0-4: second/2; 5-10: minute; 11-15: hour + int(dosTime>>11), + int(dosTime>>5&0x3f), + int(dosTime&0x1f*2), + 0, // nanoseconds + + time.UTC, + ) +}