cacert-gosigner/client/main.go

145 lines
3.0 KiB
Go

package main
import (
"flag"
"os"
"os/signal"
"sync"
"syscall"
"time"
log "github.com/sirupsen/logrus"
"go.bug.st/serial"
"git.cacert.org/cacert-gosigner/client/processing"
"git.cacert.org/cacert-gosigner/client/protocol"
"git.cacert.org/cacert-gosigner/datastructures"
)
const mainLoopSleep = 2700
func main() {
var configFile string
flag.StringVar(&configFile, "c", "client.yaml", "client configuration file in YAML format")
flag.Parse()
var (
clientConfig *ClientConfig
serialConfig *serial.Mode
err error
)
if clientConfig, err = readConfig(configFile); err != nil {
log.Panic(err)
}
serialConfig = fillSerialMode(clientConfig)
if clientConfig.Debug {
log.SetLevel(log.TraceLevel)
}
log.Infof("connecting to %s using %+v", clientConfig.SerialAddress, serialConfig)
port, err := serial.Open(clientConfig.SerialAddress, serialConfig)
if err != nil {
log.Fatal(err)
}
log.Debug("serial port connected")
requestChannel := protocol.NewSignerProtocolRequestChannel()
responseChannel := make(chan *datastructures.SignerResponse, 1)
clientProtocolConfig := protocol.NewSignerProtocolConfig()
if clientConfig.BufferSize != 0 {
clientProtocolConfig.BufferSize = int(clientConfig.BufferSize)
}
protocolHandler := protocol.NewProtocolHandler(
requestChannel, &responseChannel, port, clientProtocolConfig,
)
cancelChannel := make(chan os.Signal, 1)
signal.Notify(cancelChannel, syscall.SIGTERM, syscall.SIGINT)
const goRoutines = 2
wg := sync.WaitGroup{}
wg.Add(goRoutines)
go func() {
if err := protocolHandler.HandleSignerProtocol(); err != nil {
log.Errorf("terminating because of %v", err)
close(cancelChannel)
}
wg.Done()
}()
go func() {
runMainLoop(requestChannel, &responseChannel)
wg.Done()
}()
sig := <-cancelChannel
if sig != nil {
log.Infof("caught %+v", sig)
}
if err := protocolHandler.Close(); err != nil {
log.Error(err)
} else {
log.Infof("protocol handler closed")
}
if err := port.Close(); err != nil {
log.Error(err)
} else {
log.Infof("serial port closed")
}
wg.Wait()
}
func runMainLoop(
requestChannel *protocol.SignerProtocolRequestChannel,
responseChannel *chan *datastructures.SignerResponse,
) {
crlCheck := 0
log.Debug("starting main loop")
go func() {
for response := range *responseChannel {
if err := processing.Process(response); err != nil {
log.Error(err)
}
}
log.Trace("processing goroutine terminated")
}()
for {
log.Debug("handling GPG database ...") // HandleGPG(&requestChannel)
log.Debug("issuing certificates ...") // HandleCertificates(&requestChannel)
log.Debug("revoking certificates ...") // RevokeCertificates(&requestChannel)
crlCheck++
if crlCheck%100 == 0 {
log.Debug("refresh CRLs ...") // RefreshCRLs(&requestChannel)
}
if requestChannel.IsClosed() {
return
}
log.Debug("send NUL request to keep connection open")
requestChannel.C <- datastructures.NewNulRequest()
log.Debug("sleep for 2.7 seconds")
time.Sleep(mainLoopSleep * time.Millisecond)
}
}