"sync"
"go.cypherpunks.ru/ucspi"
+ "go.stargrave.org/tofuproxy/caches"
"go.stargrave.org/tofuproxy/fifos"
)
CmdCerttool = "certtool"
CmdWish = "wish8.6"
- Certs string
- accepted = make(map[string]string)
- acceptedM sync.RWMutex
- rejected = make(map[string]string)
- rejectedM sync.RWMutex
- VerifyM sync.Mutex
+ Certs string
+ VerifyM sync.Mutex
)
func spkiHash(cert *x509.Certificate) string {
return hex.EncodeToString(hsh[:])
}
-func acceptedAdd(addr, h string) {
- acceptedM.Lock()
- accepted[addr] = h
- acceptedM.Unlock()
-}
-
-func rejectedAdd(addr, h string) {
- rejectedM.Lock()
- rejected[addr] = h
- rejectedM.Unlock()
-}
-
type ErrRejected struct {
addr string
}
certTheirHash := spkiHash(certTheir)
VerifyM.Lock()
defer VerifyM.Unlock()
- acceptedM.RLock()
- certOurHash := accepted[host]
- acceptedM.RUnlock()
+ caches.AcceptedM.RLock()
+ certOurHash := caches.Accepted[host]
+ caches.AcceptedM.RUnlock()
if certTheirHash == certOurHash {
return nil
}
- rejectedM.RLock()
- certOurHash = rejected[host]
- rejectedM.RUnlock()
+ caches.RejectedM.RLock()
+ certOurHash = caches.Rejected[host]
+ caches.RejectedM.RUnlock()
if certTheirHash == certOurHash {
return ErrRejected{host}
}
daneExists, daneMatched := dane(host, certTheir)
if daneExists {
if daneMatched {
- fifos.SinkDANE <- fmt.Sprintf("%s\tmatched", host)
+ fifos.LogDANE <- fmt.Sprintf("%s\tACK", host)
} else {
- fifos.SinkDANE <- fmt.Sprintf("%s\tNOT matched", host)
+ fifos.LogDANE <- fmt.Sprintf("%s\tNAK", host)
}
}
fn := filepath.Join(Certs, host)
certsOur, _, err := ucspi.CertPoolFromFile(fn)
if err == nil || dialErr != nil || (daneExists && !daneMatched) {
if certsOur != nil && certTheirHash == spkiHash(certsOur[0]) {
- acceptedAdd(host, certTheirHash)
+ caches.AcceptedM.Lock()
+ caches.Accepted[host] = certTheirHash
+ caches.AcceptedM.Unlock()
if bytes.Compare(certsOur[0].Raw, rawCerts[0]) != 0 {
- fifos.SinkCert <- fmt.Sprintf("Refresh\t%s\t%s", host, certTheirHash)
+ fifos.LogCert <- fmt.Sprintf("Refresh\t%s\t%s", host, certTheirHash)
goto CertUpdate
}
return nil
proc doOnce {} { exit 11 }
proc doReject {} { exit 12 }
button .bAccept -text "Accept" -bg green -command doAccept
-button .bOnce -text "Once" -command doOnce
+button .bOnce -text "Once" -bg green -command doOnce
button .bReject -text "Reject" -bg red -command doReject
grid .bAccept .bOnce .bReject
grid rowconfigure . 0 -weight 1
err = cmd.Run()
exitError, ok := err.(*exec.ExitError)
if !ok {
- fifos.SinkCert <- fmt.Sprintf("DENY\t%s\t%s", host, certTheirHash)
+ fifos.LogCert <- fmt.Sprintf("Reject\t%s\t%s", host, certTheirHash)
return ErrRejected{host}
}
switch exitError.ExitCode() {
case 10:
- fifos.SinkCert <- fmt.Sprintf("ADD\t%s\t%s", host, certTheirHash)
+ fifos.LogCert <- fmt.Sprintf("Accept\t%s\t%s", host, certTheirHash)
goto CertUpdate
case 11:
- fifos.SinkCert <- fmt.Sprintf("ONCE\t%s\t%s", host, certTheirHash)
- acceptedAdd(host, certTheirHash)
+ fifos.LogCert <- fmt.Sprintf("Once\t%s\t%s", host, certTheirHash)
+ caches.AcceptedM.Lock()
+ caches.Accepted[host] = certTheirHash
+ caches.AcceptedM.Unlock()
return nil
case 12:
- rejectedAdd(host, certTheirHash)
+ caches.RejectedM.Lock()
+ caches.Rejected[host] = certTheirHash
+ caches.RejectedM.Unlock()
fallthrough
default:
- fifos.SinkCert <- fmt.Sprintf("DENY\t%s\t%s", host, certTheirHash)
+ fifos.LogCert <- fmt.Sprintf("Reject\t%s\t%s", host, certTheirHash)
return ErrRejected{host}
}
} else {
if !os.IsNotExist(err) {
return err
}
- fifos.SinkCert <- fmt.Sprintf("TOFU\t%s\t%s", host, certTheirHash)
+ fifos.LogCert <- fmt.Sprintf("TOFU\t%s\t%s", host, certTheirHash)
}
CertUpdate:
tmp, err := os.CreateTemp(Certs, "")
}
tmp.Close()
os.Rename(tmp.Name(), fn)
- acceptedAdd(host, certTheirHash)
+ caches.AcceptedM.Lock()
+ caches.Accepted[host] = certTheirHash
+ caches.AcceptedM.Unlock()
return nil
}