authelia/internal/ntp/ntp.go
James Elliott 3695aa8140
feat(storage): primary key for all tables and general qol refactoring (#2431)
This is a massive overhaul to the SQL Storage for Authelia. It facilitates a whole heap of utility commands to help manage the database, primary keys, ensures all database requests use a context for cancellations, and paves the way for a few other PR's which improve the database.

Fixes #1337
2021-11-23 20:45:38 +11:00

72 lines
1.8 KiB
Go

package ntp
import (
"encoding/binary"
"errors"
"net"
"time"
"github.com/authelia/authelia/v4/internal/configuration/schema"
"github.com/authelia/authelia/v4/internal/logging"
"github.com/authelia/authelia/v4/internal/utils"
)
// NewProvider instantiate a ntp provider given a configuration.
func NewProvider(config *schema.NTPConfiguration) *Provider {
return &Provider{
config: config,
log: logging.Logger(),
}
}
// StartupCheck implements the startup check provider interface.
func (p *Provider) StartupCheck() (err error) {
conn, err := net.Dial("udp", p.config.Address)
if err != nil {
p.log.Warnf("Could not connect to NTP server to validate the system time is properly synchronized: %+v", err)
return nil
}
defer conn.Close()
if err := conn.SetDeadline(time.Now().Add(5 * time.Second)); err != nil {
p.log.Warnf("Could not connect to NTP server to validate the system time is properly synchronized: %+v", err)
return nil
}
version := ntpV4
if p.config.Version == 3 {
version = ntpV3
}
req := &ntpPacket{LeapVersionMode: ntpLeapVersionClientMode(false, version)}
if err := binary.Write(conn, binary.BigEndian, req); err != nil {
p.log.Warnf("Could not write to the NTP server socket to validate the system time is properly synchronized: %+v", err)
return nil
}
now := time.Now()
resp := &ntpPacket{}
if err := binary.Read(conn, binary.BigEndian, resp); err != nil {
p.log.Warnf("Could not read from the NTP server socket to validate the system time is properly synchronized: %+v", err)
return nil
}
maxOffset, _ := utils.ParseDurationString(p.config.MaximumDesync)
ntpTime := ntpPacketToTime(resp)
if result := ntpIsOffsetTooLarge(maxOffset, now, ntpTime); result {
return errors.New("the system clock is not synchronized accurately enough with the configured NTP server")
}
return nil
}