Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/pr/347'
Browse files Browse the repository at this point in the history
* origin/pr/347:
  Make qubes-sync-time.service oneshot
  Better error message when 'date' fails
  Support nanosecond precision for dates
  • Loading branch information
marmarek committed Oct 14, 2022
2 parents 3400298 + e4c7b0b commit 3be6513
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 13 deletions.
44 changes: 36 additions & 8 deletions qubes-rpc/qubes-sync-clock
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,49 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#

import sys
import os
import re
import subprocess
import sys

def main():
stdin = sys.stdin.read(25)

untrusted_date_out = stdin.strip()

if not re.match(r'^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\+00:?00$', untrusted_date_out):
os.environ['LC_ALL'] = 'C'
untrusted_date_out = sys.stdin.buffer.read(36)
try:
untrusted_date_out.decode('ascii', 'strict')
except UnicodeDecodeError:
sys.stderr.write('Received non-ASCII date, aborting!\n')
sys.exit(1)
untrusted_date_len = len(untrusted_date_out)
if untrusted_date_len == 36: # new format, nanosecond precision
regexp = rb'\A\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2},[0-9]{9}\+00:00\n\Z'
precision = b'ns'
elif untrusted_date_len == 26: # old format, second precision
regexp = rb'\A\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\+00:00\n\Z'
precision = b'seconds'
else:
sys.stderr.write('Invalid date length (expected 26 or 36 bytes, got {})'
', aborting!\n'.format(untrusted_date_len))
sys.exit(1)
if untrusted_date_out[-7:] != b'+00:00\n':
sys.stderr.write('Date not in UTC, aborting!\n')
sys.exit(1)
if not re.match(regexp, untrusted_date_out):
sys.stderr.write('Invalid date received, aborting!\n')
sys.exit(1)
# this time is arbitrary, something better should be used instead
if untrusted_date_out[:19] <= b'2022-07-10T17:08:31':
sys.stderr.write('Received a date older than this program, aborting!\n')
sys.exit(1)
date_out = untrusted_date_out
subprocess.check_call(['date', '-u', '-Iseconds', '-s', date_out],
stdout=subprocess.DEVNULL)
try:
subprocess.check_call([b'date', b'-u', b'-I' + precision, b'-s',
date_out[:-1]],
stdout=subprocess.DEVNULL)
except subprocess.CalledProcessError as e:
# input is trusted here, so it can be safely printed
sys.stderr.write('Unable to set the date: process {!r} failed.\n'.format(e.cmd))
sys.exit(e.returncode)

if __name__ == '__main__':
main()
Expand Down
10 changes: 6 additions & 4 deletions qubes-rpc/qubes.GetDate
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/bin/sh
#!/bin/sh --
#
# The Qubes OS Project, http://www.qubes-os.org
#
Expand All @@ -16,7 +16,9 @@
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
#

date -u -Iseconds
export LC_ALL=C
case ${1-} in
'') exec date -u -Iseconds;;
nanosecond|nanoseconds|ns|*) exec date -u -Ins;;
esac
3 changes: 2 additions & 1 deletion qubes-rpc/qvm-sync-clock
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,5 @@
#

# shellcheck disable=SC2016
qrexec-client-vm '$default' qubes.GetDate /usr/lib/qubes/qubes-sync-clock
qrexec-client-vm --filter-escape-chars-stderr '@default' \
qubes.GetDate+nanoseconds /usr/lib/qubes/qubes-sync-clock
1 change: 1 addition & 0 deletions vm-systemd/qubes-sync-time.service
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ ConditionPathExists=!/var/run/qubes-service/clocksync

[Service]
ExecStart=/usr/bin/qvm-sync-clock
Type=oneshot
User=root

0 comments on commit 3be6513

Please sign in to comment.