// Md5HashValue gets the md5 hash value func Md5HashValue(log log.T, filePath string) (hash string, err error) { var exists = false exists, err = fileutil.LocalFileExist(filePath) if err != nil || exists == false { return } var f *os.File f, err = os.Open(filePath) if err != nil { log.Error(err) } defer f.Close() hasher := md5.New() if _, err = io.Copy(hasher, f); err != nil { log.Error(err) } hash = hex.EncodeToString(hasher.Sum(nil)) log.Debugf("Hash=%v, FilePath=%v", hash, filePath) return }
// Download is a generic utility which attempts to download smartly. func Download(log log.T, input DownloadInput) (output DownloadOutput, err error) { // parse the url var fileURL *url.URL fileURL, err = url.Parse(input.SourceURL) if err != nil { err = fmt.Errorf("url parsing failed. %v", err) return } // create destination directory var destinationDir = input.DestinationDirectory if destinationDir == "" { destinationDir = appconfig.DownloadRoot } // create directory where artifacts are downloaded. err = fileutil.MakeDirs(destinationDir) if err != nil { err = fmt.Errorf("failed to create directory=%v, err=%v", destinationDir, err) return } // process if the url is local file or it has already been downloaded. var isLocalFile = false isLocalFile, err = fileutil.LocalFileExist(input.SourceURL) if err != nil { err = fmt.Errorf("check for local file exists returned %v", err) err = nil } if isLocalFile == true { err = fmt.Errorf("source is a local file, skipping download. %v", input.SourceURL) output.LocalFilePath = input.SourceURL output.IsUpdated = false output.IsHashMatched, err = VerifyHash(log, input, output) } else { err = fmt.Errorf("source file wasn't found locally, will attempt as web download. %v", input.SourceURL) // compute the local filename which is hash of url_filename // Generating a hash_filename will also help against attackers // from specifying a directory and filename to overwrite any ami/built-in files. urlHash := md5.Sum([]byte(fileURL.String())) fileName := filepath.Base(fileURL.String()) output.LocalFilePath = filepath.Join(destinationDir, fmt.Sprintf("%x_%v", urlHash, fileName)) amazonS3URL := s3util.ParseAmazonS3URL(log, fileURL) if amazonS3URL.IsBucketAndKeyPresent() { // source is s3 output, err = s3Download(log, amazonS3URL, output.LocalFilePath) } else { // simple httphttps download output, err = httpDownload(log, input.SourceURL, output.LocalFilePath) } if err != nil { return } isLocalFile, err = fileutil.LocalFileExist(output.LocalFilePath) if isLocalFile == true { output.IsHashMatched, err = VerifyHash(log, input, output) } } return }