fix: NTP syncs as soon as DHCP has a lease, random origin cookie instead of the unsynced local clock, TLS validates certificates against UTC

This commit is contained in:
daniel committed 2026-10-26 08:19:48 +01:00
1 parent 1d00c1c016
commit 7e036c94e7
13 files changed
+51 -59

No files matched your search

+3
View File
@@ -317,6 +317,9 @@ namespace montauk::abi {
and returns 1 while more remains, 0 once done. CAP_STORAGE_ADMIN. */
static constexpr uint64_t SYS_FS_GROW = 208; // (drive, FsGrowStatus*, apply) -> 1 / 0 / status
/* Time.hpp -- wall clock as UTC unix seconds (SYS_GETTIME is local time). */
static constexpr uint64_t SYS_GETUNIXTIME = 209; // () -> seconds
/* Kernel-owned process capabilities. User identities may namespace
per-user resources, but never participate in authorization decisions. */
static constexpr uint64_t CAP_PROCESS_ADMIN = 1ULL << 0;
+5
View File
@@ -232,6 +232,7 @@ extern "C" {
#define MTK_SYS_WIN_DRAG_FORMATS 206
#define MTK_SYS_WIN_DRAG_GET_DATA 207
#define MTK_SYS_FS_GROW 208
#define MTK_SYS_GETUNIXTIME 209
/* @SYSCALLS-END */
/* Syscall status codes (montauk/statuscodes.h for C++). */
@@ -805,6 +806,10 @@ static inline void mtk_gettime(mtk_datetime *out) {
_mtk_syscall1(MTK_SYS_GETTIME, (long)out);
}
static inline int64_t mtk_get_unix_time(void) {
return (int64_t)_mtk_syscall0(MTK_SYS_GETUNIXTIME);
}
static inline int mtk_set_unix_time(int64_t unix_seconds) {
return (int)_mtk_syscall1(MTK_SYS_SETUNIXTIME, (long)unix_seconds);
}
+6 -41
View File
@@ -51,42 +51,6 @@ inline uint32_t read_be32(const uint8_t* p) {
((uint32_t)p[2] << 8) | (uint32_t)p[3];
}
inline void write_be64(uint8_t* p, uint64_t value) {
for (int i = 7; i >= 0; i--) {
p[i] = (uint8_t)value;
value >>= 8;
}
}
inline bool is_leap_year(int year) {
return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
}
inline int days_in_month(int month, int year) {
static const int days[] = {0, 31, 28, 31, 30, 31, 30,
31, 31, 30, 31, 30, 31};
return month == 2 && is_leap_year(year) ? 29 : days[month];
}
inline int64_t current_unix_seconds() {
montauk::abi::DateTime now = {};
montauk::gettime(&now);
if (now.Year < 1970 || now.Month < 1 || now.Month > 12 ||
now.Day < 1 || now.Day > days_in_month(now.Month, now.Year))
return 0;
int64_t days = 0;
for (int year = 1970; year < (int)now.Year; year++)
days += is_leap_year(year) ? 366 : 365;
for (int month = 1; month < (int)now.Month; month++)
days += days_in_month(month, now.Year);
days += now.Day - 1;
int64_t local = days * 86400 + (int64_t)now.Hour * 3600 +
(int64_t)now.Minute * 60 + now.Second;
return local - (int64_t)montauk::gettz() * 60;
}
inline bool same_bytes(const uint8_t* a, const uint8_t* b, int count) {
for (int i = 0; i < count; i++) {
if (a[i] != b[i]) return false;
@@ -115,14 +79,15 @@ inline int synchronize(const char* server, uint32_t timeout_ms = 5000,
request[2] = 6; // poll exponent: 2^6 = 64 seconds
request[3] = 0xEC; // precision: approximately 2^-20 seconds
int64_t unix_now = current_unix_seconds();
if (unix_now <= 0) {
// The transmit timestamp only has to come back in the reply's origin
// field, so send a random cookie rather
// than the local clock, which may still be invalid before the first sync.
uint8_t cookie[8];
if (montauk::getrandom(cookie, sizeof(cookie)) != (int64_t)sizeof(cookie)) {
montauk::closesocket(fd);
return CLOCK_ERROR;
}
uint64_t transmit_timestamp =
((uint64_t)unix_now + UNIX_EPOCH_DELTA) << 32;
write_be64(request + 40, transmit_timestamp);
for (int i = 0; i < 8; i++) request[40 + i] = cookie[i];
progress(progress_callback, "Sending NTP request...");
if (montauk::sendto(fd, request, sizeof(request), server_ip, SERVER_PORT) < 0) {
+2
View File
@@ -505,6 +505,8 @@ namespace montauk {
// Timekeeping (wall-clock)
inline void gettime(montauk::abi::DateTime* out) { syscall1(montauk::abi::SYS_GETTIME, (uint64_t)out); }
// UTC seconds since 1970 (gettime() is local time).
inline int64_t get_unix_time() { return syscall0(montauk::abi::SYS_GETUNIXTIME); }
inline int set_unix_time(int64_t unix_seconds) {
return (int)syscall1(montauk::abi::SYS_SETUNIXTIME, (uint64_t)unix_seconds);
}