github.com/u-root/u-root@v7.0.1-0.20200915234505-ad7babab0a8e+incompatible/cmds/boot/stboot/time.go (about)

     1  // Copyright 2018 the u-root Authors. All rights reserved
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package main
     6  
     7  import (
     8  	"errors"
     9  	"io/ioutil"
    10  	"log"
    11  	"strconv"
    12  	"strings"
    13  	"time"
    14  
    15  	"github.com/beevik/ntp"
    16  	"github.com/u-root/u-root/pkg/rtc"
    17  )
    18  
    19  const (
    20  	timestampPath string = "/etc/timestamp"
    21  	ntpTimePool   string = "0.beevik-ntp.pool.ntp.org"
    22  )
    23  
    24  func readRTCTime() (time.Time, error) {
    25  	rtc, err := rtc.OpenRTC()
    26  	if err != nil {
    27  		return time.Time{}, err
    28  	}
    29  	return rtc.Read()
    30  }
    31  
    32  func writeRTCTime(t time.Time) error {
    33  	rtc, err := rtc.OpenRTC()
    34  	if err != nil {
    35  		return err
    36  	}
    37  	return rtc.Set(t)
    38  }
    39  
    40  // validateSystemTime sets RTC and OS time according to
    41  // realtime clock, timestamp and ntp
    42  func validateSystemTime() error {
    43  	data, err := ioutil.ReadFile(timestampPath)
    44  	if err != nil {
    45  		return err
    46  	}
    47  	unixTime, err := strconv.Atoi(strings.Trim(string(data), "\n"))
    48  	if err != nil {
    49  		return err
    50  	}
    51  	stampTime := time.Unix(int64(unixTime), 0)
    52  	if err != nil {
    53  		return err
    54  	}
    55  	rtcTime, err := readRTCTime()
    56  	if err != nil {
    57  		return err
    58  	}
    59  	log.Printf("Systemtime: %v", rtcTime.UTC())
    60  	if rtcTime.UTC().Before(stampTime.UTC()) {
    61  		log.Printf("Systemtime is invalid: %v", rtcTime.UTC())
    62  		log.Printf("Receive time via NTP from %s", ntpTimePool)
    63  		ntpTime, err := ntp.Time(ntpTimePool)
    64  		if err != nil {
    65  			return err
    66  		}
    67  		if ntpTime.UTC().Before(stampTime.UTC()) {
    68  			return errors.New("NTP spoof may happened")
    69  		}
    70  		log.Printf("Update RTC to %v", ntpTime.UTC())
    71  		err = writeRTCTime(ntpTime)
    72  		if err != nil {
    73  			return err
    74  		}
    75  		reboot("Set system time. Need reboot.")
    76  	}
    77  	return nil
    78  }