mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-05-11 21:28:15 +00:00
Security Enhancements: - Add TLS fingerprint verification for Proxmox and PBS clients - Create shared tlsutil package for secure TLS handling - Implement proper CORS checking for WebSocket connections - Add configurable allowed origins for WebSocket hub Type Safety Improvements: - Replace all TypeScript 'any' types with proper interfaces - Add proper types for connectionHealth, apiCallDuration, metrics values - Create typed BackupTask and StorageBackup interfaces - Ensure all TypeScript code passes strict type checking Error Handling Enhancements: - Add comprehensive error handling middleware for API routes - Implement structured error responses with proper status codes - Add error boundaries to critical frontend components - Fix WebSocket upgrade issues by preserving http.Hijacker interface - Implement storage details endpoint (was TODO) Code Quality: - Fix Go vet mutex copy issues by creating StateSnapshot type - Update ToFrontend() to use pointer receiver - Ensure all code compiles without warnings - Add proper error recovery and retry mechanisms All changes tested and verified to work correctly.
59 lines
No EOL
1.7 KiB
Go
59 lines
No EOL
1.7 KiB
Go
package tlsutil
|
|
|
|
import (
|
|
"crypto/sha256"
|
|
"crypto/tls"
|
|
"crypto/x509"
|
|
"encoding/hex"
|
|
"fmt"
|
|
"net/http"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
// FingerprintVerifier creates a custom TLS config that verifies server certificate fingerprint
|
|
func FingerprintVerifier(fingerprint string) *tls.Config {
|
|
// Normalize fingerprint (remove colons, convert to lowercase)
|
|
expectedFingerprint := strings.ToLower(strings.ReplaceAll(fingerprint, ":", ""))
|
|
|
|
return &tls.Config{
|
|
InsecureSkipVerify: true, // We'll do our own verification
|
|
VerifyPeerCertificate: func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error {
|
|
if len(rawCerts) == 0 {
|
|
return fmt.Errorf("no certificates presented by server")
|
|
}
|
|
|
|
// Calculate SHA256 fingerprint of the leaf certificate
|
|
fingerprint := sha256.Sum256(rawCerts[0])
|
|
actualFingerprint := hex.EncodeToString(fingerprint[:])
|
|
|
|
if actualFingerprint != expectedFingerprint {
|
|
return fmt.Errorf("certificate fingerprint mismatch: expected %s, got %s",
|
|
expectedFingerprint, actualFingerprint)
|
|
}
|
|
|
|
return nil
|
|
},
|
|
}
|
|
}
|
|
|
|
// CreateHTTPClient creates an HTTP client with appropriate TLS configuration
|
|
func CreateHTTPClient(verifySSL bool, fingerprint string) *http.Client {
|
|
transport := &http.Transport{
|
|
Proxy: http.ProxyFromEnvironment,
|
|
}
|
|
|
|
if !verifySSL && fingerprint == "" {
|
|
// Insecure mode - skip all verification
|
|
transport.TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
|
|
} else if fingerprint != "" {
|
|
// Fingerprint verification mode
|
|
transport.TLSClientConfig = FingerprintVerifier(fingerprint)
|
|
}
|
|
// else: default secure mode with system CA verification
|
|
|
|
return &http.Client{
|
|
Transport: transport,
|
|
Timeout: 30 * time.Second,
|
|
}
|
|
} |