mirror of
https://wget.la/https://github.com/leookun/cursor-byok
synced 2026-08-17 03:27:02 +08:00
133 lines
4.1 KiB
Go
133 lines
4.1 KiB
Go
//go:build darwin
|
|
|
|
package cursor
|
|
|
|
import (
|
|
"crypto/sha1"
|
|
"crypto/x509"
|
|
"encoding/pem"
|
|
"fmt"
|
|
"os/exec"
|
|
"strings"
|
|
|
|
"cursor/internal/logger"
|
|
)
|
|
|
|
const (
|
|
darwinSecurityExe = "security"
|
|
darwinLoginKeychainName = "login.keychain-db"
|
|
legacySharedCASHA1 = "C14B7488C5AB83F098BEB2603F1135595A381FC0"
|
|
)
|
|
|
|
func getCertSHA1Fingerprint(certPEM []byte) (string, error) {
|
|
block, _ := pem.Decode(certPEM)
|
|
if block == nil {
|
|
return "", fmt.Errorf("无法解析证书 PEM")
|
|
}
|
|
cert, err := x509.ParseCertificate(block.Bytes)
|
|
if err != nil {
|
|
return "", fmt.Errorf("解析证书失败: %w", err)
|
|
}
|
|
fingerprint := fmt.Sprintf("%X", sha1.Sum(cert.Raw))
|
|
return fingerprint, nil
|
|
}
|
|
|
|
func isCACertInstalled(certPEM []byte) (bool, error) {
|
|
fingerprint, err := getCertSHA1Fingerprint(certPEM)
|
|
if err != nil {
|
|
return false, fmt.Errorf("获取证书指纹失败: %w", err)
|
|
}
|
|
return isCACertFingerprintInstalled(fingerprint)
|
|
}
|
|
|
|
func isCACertFingerprintInstalled(fingerprint string) (bool, error) {
|
|
out, err := exec.Command(darwinSecurityExe, "find-certificate", "-a", "-Z", darwinLoginKeychainName).CombinedOutput()
|
|
if err != nil {
|
|
return false, fmt.Errorf("检查 macOS 登录钥匙串失败: %w: %s", err, strings.TrimSpace(string(out)))
|
|
}
|
|
installed := strings.Contains(strings.ToUpper(string(out)), fingerprint)
|
|
if installed {
|
|
logger.Infof("isCACertInstalled: cert found in macOS login keychain, fingerprint=%s", fingerprint)
|
|
} else {
|
|
logger.Infof("isCACertInstalled: cert not found in macOS login keychain, fingerprint=%s", fingerprint)
|
|
}
|
|
return installed, nil
|
|
}
|
|
|
|
// EnsureLegacySharedCACertRemoved removes the compromised CA shipped by older versions.
|
|
func EnsureLegacySharedCACertRemoved() error {
|
|
installed, err := isCACertFingerprintInstalled(legacySharedCASHA1)
|
|
if err != nil {
|
|
return fmt.Errorf("检查旧版共享 CA 失败: %w", err)
|
|
}
|
|
if !installed {
|
|
return nil
|
|
}
|
|
out, err := exec.Command(
|
|
darwinSecurityExe,
|
|
"delete-certificate",
|
|
"-Z", legacySharedCASHA1,
|
|
"-t",
|
|
darwinLoginKeychainName,
|
|
).CombinedOutput()
|
|
if err != nil {
|
|
return fmt.Errorf("从 macOS 登录钥匙串删除旧版共享 CA 失败: %w: %s", err, strings.TrimSpace(string(out)))
|
|
}
|
|
installed, err = isCACertFingerprintInstalled(legacySharedCASHA1)
|
|
if err != nil {
|
|
return fmt.Errorf("验证旧版共享 CA 删除状态失败: %w", err)
|
|
}
|
|
if installed {
|
|
return fmt.Errorf("删除命令已执行,但 macOS 登录钥匙串中仍存在旧版共享 CA")
|
|
}
|
|
logger.Infof("ensureLegacySharedCACertRemoved: legacy shared CA removed from macOS login keychain")
|
|
return nil
|
|
}
|
|
|
|
func installCACertToDarwinKeychain(certPEM []byte, certPath string) error {
|
|
fingerprint, err := getCertSHA1Fingerprint(certPEM)
|
|
if err != nil {
|
|
return fmt.Errorf("获取证书指纹失败: %w", err)
|
|
}
|
|
|
|
logger.Infof("installCACertToDarwinKeychain: installing cert into login keychain, path=%s fingerprint=%s", certPath, fingerprint)
|
|
out, err := exec.Command(
|
|
darwinSecurityExe,
|
|
"add-trusted-cert",
|
|
"-d",
|
|
"-r", "trustRoot",
|
|
"-p", "ssl",
|
|
"-k", darwinLoginKeychainName,
|
|
certPath,
|
|
).CombinedOutput()
|
|
if err != nil {
|
|
return fmt.Errorf("安装 CA 到 macOS 登录钥匙串失败: %w: %s", err, strings.TrimSpace(string(out)))
|
|
}
|
|
|
|
installed, err := isCACertInstalled(certPEM)
|
|
if err != nil {
|
|
return fmt.Errorf("验证 macOS 证书安装状态失败: %w", err)
|
|
}
|
|
if !installed {
|
|
return fmt.Errorf("证书导入命令已执行,但 macOS 登录钥匙串中未找到证书")
|
|
}
|
|
|
|
logger.Infof("installCACertToDarwinKeychain: cert installed successfully, fingerprint=%s", fingerprint)
|
|
return nil
|
|
}
|
|
|
|
// EnsureCACertInstalled 确保 CA 证书已安装到 macOS 登录钥匙串。
|
|
func EnsureCACertInstalled(certPEM []byte, certPath string) error {
|
|
installed, err := isCACertInstalled(certPEM)
|
|
if err != nil {
|
|
return fmt.Errorf("检查 macOS 证书安装状态失败: %w", err)
|
|
}
|
|
if installed {
|
|
logger.Infof("ensureCACertInstalled: cert already installed in macOS login keychain, skipping")
|
|
return nil
|
|
}
|
|
|
|
logger.Infof("ensureCACertInstalled: cert not installed in macOS login keychain, installing...")
|
|
return installCACertToDarwinKeychain(certPEM, certPath)
|
|
}
|