- Invoke optional AfterPersistentPreRun after root PersistentPreRunE setup so overlays can wire non-MCP clients (e.g. A2A gateway). - Add pkg/runtimetoken.ResolveAccessToken mirroring MCP auth resolution. - Export MCP identity headers via pkg/cli for auxiliary HTTP transports. - Fix staticcheck: SA1012 nil-context test guard, ST1005 error string in verify. Made-with: Cursor
67 lines
1.8 KiB
Go
67 lines
1.8 KiB
Go
// Copyright 2026 Alibaba Group
|
|
// Licensed under the Apache License, Version 2.0
|
|
|
|
package upgrade
|
|
|
|
import (
|
|
"crypto/sha256"
|
|
"encoding/hex"
|
|
"fmt"
|
|
"os"
|
|
"strings"
|
|
)
|
|
|
|
// VerifySHA256 verifies a file against its expected SHA256 hash.
|
|
func VerifySHA256(filePath, expectedHash string) error {
|
|
actual, err := ComputeSHA256(filePath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
expectedHash = strings.ToLower(strings.TrimSpace(expectedHash))
|
|
if actual != expectedHash {
|
|
return fmt.Errorf("SHA256 mismatch: want %s, got %s", expectedHash[:16], actual[:16])
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// ComputeSHA256 computes the SHA256 hash of a file.
|
|
func ComputeSHA256(filePath string) (string, error) {
|
|
data, err := os.ReadFile(filePath)
|
|
if err != nil {
|
|
return "", fmt.Errorf("读取文件失败: %w", err)
|
|
}
|
|
hash := sha256.Sum256(data)
|
|
return hex.EncodeToString(hash[:]), nil
|
|
}
|
|
|
|
// ParseChecksumFile parses a SHA256SUMS-style file.
|
|
// Each line: "hash filename" (two spaces or whitespace separated).
|
|
// Returns a map of filename -> lowercase hex hash.
|
|
func ParseChecksumFile(content string) map[string]string {
|
|
result := make(map[string]string)
|
|
for _, line := range strings.Split(content, "\n") {
|
|
line = strings.TrimSpace(line)
|
|
if line == "" {
|
|
continue
|
|
}
|
|
parts := strings.Fields(line)
|
|
if len(parts) >= 2 {
|
|
hash := strings.ToLower(parts[0])
|
|
filename := parts[1]
|
|
result[filename] = hash
|
|
}
|
|
}
|
|
return result
|
|
}
|
|
|
|
// VerifyFileFromChecksums verifies a downloaded file against checksums.txt content.
|
|
func VerifyFileFromChecksums(filePath, filename, checksumsContent string) error {
|
|
checksums := ParseChecksumFile(checksumsContent)
|
|
expectedHash, ok := checksums[filename]
|
|
if !ok {
|
|
return fmt.Errorf("在校验和文件中未找到 %s", filename)
|
|
}
|
|
return VerifySHA256(filePath, expectedHash)
|
|
}
|