Esempio n. 1
0
// NewDigestVerifier returns a verifier that compares the written bytes
// against a passed in digest.
func NewDigestVerifier(d Digest) (Verifier, error) {
	if err := d.Validate(); err != nil {
		return nil, err
	}

	alg := d.Algorithm()
	switch alg {
	case "sha256", "sha384", "sha512":
		return hashVerifier{
			hash:   alg.Hash(),
			digest: d,
		}, nil
	default:
		// Assume we have a tarsum.
		version, err := tarsum.GetVersionFromTarsum(string(d))
		if err != nil {
			return nil, err
		}

		pr, pw := io.Pipe()

		// TODO(stevvooe): We may actually want to ban the earlier versions of
		// tarsum. That decision may not be the place of the verifier.

		ts, err := tarsum.NewTarSum(pr, true, version)
		if err != nil {
			return nil, err
		}

		// TODO(sday): Ick! A goroutine per digest verification? We'll have to
		// get the tarsum library to export an io.Writer variant.
		go func() {
			if _, err := io.Copy(ioutil.Discard, ts); err != nil {
				pr.CloseWithError(err)
			} else {
				pr.Close()
			}
		}()

		return &tarsumVerifier{
			digest: d,
			ts:     ts,
			pr:     pr,
			pw:     pw,
		}, nil
	}
}
Esempio n. 2
0
// ReadChecks takes the input and loads the hash/id to be checked
func ReadChecks(input io.Reader) (Checks, error) {
	rdr := bufio.NewReader(input)
	checks := Checks{}
	for {
		line, err := rdr.ReadString('\n')
		if err != nil {
			if err == io.EOF {
				break
			}
			return checks, err
		}
		v, err := tarsum.GetVersionFromTarsum(line)
		if err != nil {
			continue
		}
		// tarsum+sha256:7b0ade22d5bba35d1e88389c005376f441e7d83bf5f363f2d7c70be9286163aa  ./busybox.tar:120e218dd395ec314e7b6249f39d2853911b3d6def6ea164ae05722649f34b16
		chunks := strings.SplitN(line, DefaultSpacer, 2)
		sum, source := chunks[0], chunks[1]
		i := strings.LastIndex(source, ":")
		checks = append(checks, Check{Hash: sum, Source: source[:i], Id: strings.TrimSpace(source[i+1:]), Version: v})
	}
	return checks, nil
}
Esempio n. 3
0
func main() {
	var jobs []job

	flag.Usage = usage
	flag.Parse()
	if showVersion {
		version.PrintVersion()
		return
	}

	var fail bool // if we fail on one item, foul the exit code
	if flag.NArg() > 0 {
		for _, path := range flag.Args() {
			fp, err := os.Open(path)

			if err != nil {
				log.Printf("%s: %v", path, err)
				fail = true
				continue
			}
			defer fp.Close()

			jobs = append(jobs, job{name: path, reader: fp})
		}
	} else {
		// just read stdin
		jobs = append(jobs, job{name: "-", reader: os.Stdin})
	}

	digestFn := algorithm.FromReader

	if !algorithm.Available() {
		// we cannot digest if is not available. An exception is made for
		// tarsum.
		if !strings.HasPrefix(algorithm.String(), "tarsum") {
			unsupported()
		}

		var version tarsum.Version
		if algorithm == "tarsum" {
			// small hack: if we just have tarsum, use latest
			version = tarsum.Version1
		} else {
			var err error
			version, err = tarsum.GetVersionFromTarsum(algorithm.String())
			if err != nil {
				unsupported()
			}
		}

		digestFn = func(rd io.Reader) (digest.Digest, error) {
			ts, err := tarsum.NewTarSum(rd, true, version)
			if err != nil {
				return "", err
			}

			if _, err := io.Copy(ioutil.Discard, ts); err != nil {
				return "", err
			}

			return digest.Digest(ts.Sum(nil)), nil
		}
	}

	for _, job := range jobs {
		dgst, err := digestFn(job.reader)
		if err != nil {
			log.Printf("%s: %v", job.name, err)
			fail = true
			continue
		}

		fmt.Printf("%v\t%s\n", dgst, job.name)
	}

	if fail {
		os.Exit(1)
	}
}