Common stuff for all my devices' web server pages: css, login, log, ipv4, ipv6, firmware update, clock, reset info etc.

Dependents:   oldheating gps motorhome heating

Security

A password has to be set whenever there has been a software reset. Resets following faults or power on do not require a new password as the hash is restored from the RTC GPREG register.

The password is not saved on the device; instead a 32 bit hash of the password is saved. It would take 2^31 attempts to brute force the password: this could be done in under a month if an attempt were possible every millisecond. To prevent this a 200 ms delay is introduced in the reply to the login form, that gives a more reasonable 13 years to brute force the password.

Once the password is accepted a random session id is created. This is 36 bit to give six base 64 characters but without an extra delay. If an attempt could be made every ms then this would still take over a year to brute force.

The most likely attack would to use a dictionary with, say, 10 million entries against the password which would still take 20 days to do.

Committer:
andrewboyson
Date:
Wed Jul 31 15:09:15 2019 +0000
Revision:
127:bd6dd135009d
Parent:
110:8ab752842d25
Amalgamated Reply into Poll function

Who changed what in which revision?

UserRevisionLine numberNew contents of line
andrewboyson 94:d7226b2c14b6 1 "//Clock script\n"
andrewboyson 14:c3c43c8faf0e 2 "'use strict';\n"
andrewboyson 14:c3c43c8faf0e 3 "\n"
andrewboyson 95:8c9dda8a0caf 4 "let pseudo = new Clock();\n"
andrewboyson 95:8c9dda8a0caf 5 "let rtc = new Clock();\n"
andrewboyson 94:d7226b2c14b6 6 "\n"
andrewboyson 94:d7226b2c14b6 7 "let pseudoDisplay = false;\n"
andrewboyson 94:d7226b2c14b6 8 "let pseudoStartMs = 0;\n"
andrewboyson 94:d7226b2c14b6 9 "\n"
andrewboyson 94:d7226b2c14b6 10 "let diffMs = 0;\n"
andrewboyson 94:d7226b2c14b6 11 "let rtcIsSet = false;\n"
andrewboyson 94:d7226b2c14b6 12 "let clockIsSet = false;\n"
andrewboyson 94:d7226b2c14b6 13 "let sourceIsOk = false;\n"
andrewboyson 94:d7226b2c14b6 14 "let rateIsLocked = false;\n"
andrewboyson 94:d7226b2c14b6 15 "let timeIsLocked = false;\n"
andrewboyson 14:c3c43c8faf0e 16 "\n"
andrewboyson 94:d7226b2c14b6 17 "let ppb = 0;\n"
andrewboyson 94:d7226b2c14b6 18 "let ppbdivisor = 0;\n"
andrewboyson 94:d7226b2c14b6 19 "let ppbmaxchange = 0;\n"
andrewboyson 94:d7226b2c14b6 20 "let syncedlimitppb = 0;\n"
andrewboyson 94:d7226b2c14b6 21 "let syncedhysppb = 0;\n"
andrewboyson 94:d7226b2c14b6 22 "let slewdivisor = 0;\n"
andrewboyson 94:d7226b2c14b6 23 "let slewmax = 0;\n"
andrewboyson 94:d7226b2c14b6 24 "let syncedlimitns = 0;\n"
andrewboyson 94:d7226b2c14b6 25 "let syncedhysns = 0;\n"
andrewboyson 94:d7226b2c14b6 26 "let maxoffsetsecs = 0;\n"
andrewboyson 94:d7226b2c14b6 27 "let govTrace = false;\n"
andrewboyson 14:c3c43c8faf0e 28 "\n"
andrewboyson 94:d7226b2c14b6 29 "let ntpserver = '';\n"
andrewboyson 94:d7226b2c14b6 30 "let ntpinitial = 0;\n"
andrewboyson 94:d7226b2c14b6 31 "let ntpnormal = 0;\n"
andrewboyson 94:d7226b2c14b6 32 "let ntpretry = 0;\n"
andrewboyson 94:d7226b2c14b6 33 "let ntpoffset = 0;\n"
andrewboyson 94:d7226b2c14b6 34 "let ntpmaxdelay = 0;\n"
andrewboyson 94:d7226b2c14b6 35 "\n"
andrewboyson 94:d7226b2c14b6 36 "let scanavg = 0;\n"
andrewboyson 94:d7226b2c14b6 37 "let scanmax = 0;\n"
andrewboyson 94:d7226b2c14b6 38 "let scanmin = 0;\n"
andrewboyson 94:d7226b2c14b6 39 "\n"
andrewboyson 94:d7226b2c14b6 40 "const DISPLAY_LEAP_MS = 10000;\n"
andrewboyson 94:d7226b2c14b6 41 "\n"
andrewboyson 94:d7226b2c14b6 42 "function parseLinesTime(text)\n"
andrewboyson 14:c3c43c8faf0e 43 "{\n"
andrewboyson 94:d7226b2c14b6 44 " let lines = text.split('\\n');\n"
andrewboyson 96:eb2eb75bad0f 45 " rtc.ms = Ajax.date.getTime();\n"
andrewboyson 94:d7226b2c14b6 46 " rtc.ms += parseInt(lines[0], 16);\n"
andrewboyson 95:8c9dda8a0caf 47 " rtc.ms -= Ajax.ms;\n"
andrewboyson 95:8c9dda8a0caf 48 " diffMs = rtc.ms + Ajax.ms - Date.now();\n"
andrewboyson 95:8c9dda8a0caf 49 " rtcIsSet = Ajax.hexToBit(lines[1], 0);\n"
andrewboyson 95:8c9dda8a0caf 50 " clockIsSet = Ajax.hexToBit(lines[1], 1);\n"
andrewboyson 95:8c9dda8a0caf 51 " sourceIsOk = Ajax.hexToBit(lines[1], 2);\n"
andrewboyson 95:8c9dda8a0caf 52 " rateIsLocked = Ajax.hexToBit(lines[1], 3);\n"
andrewboyson 95:8c9dda8a0caf 53 " timeIsLocked = Ajax.hexToBit(lines[1], 4);\n"
andrewboyson 95:8c9dda8a0caf 54 " rtc.leapEnable = Ajax.hexToBit(lines[1], 5);\n"
andrewboyson 95:8c9dda8a0caf 55 " rtc.leapForward = Ajax.hexToBit(lines[1], 6);\n"
andrewboyson 95:8c9dda8a0caf 56 " govTrace = Ajax.hexToBit(lines[1], 7);\n"
andrewboyson 95:8c9dda8a0caf 57 " rtc.months1970 = parseInt(lines[2], 16);\n"
andrewboyson 94:d7226b2c14b6 58 " rtc.leaps = parseInt(lines[3], 16);\n"
andrewboyson 14:c3c43c8faf0e 59 "}\n"
andrewboyson 94:d7226b2c14b6 60 "function parseLinesGov(text)\n"
andrewboyson 14:c3c43c8faf0e 61 "{\n"
andrewboyson 94:d7226b2c14b6 62 " let lines = text.split('\\n');\n"
andrewboyson 94:d7226b2c14b6 63 " ppb = parseInt(lines[0], 16);\n"
andrewboyson 94:d7226b2c14b6 64 " ppbdivisor = parseInt(lines[1], 16);\n"
andrewboyson 94:d7226b2c14b6 65 " ppbmaxchange = parseInt(lines[2], 16);\n"
andrewboyson 94:d7226b2c14b6 66 " syncedlimitppb = parseInt(lines[3], 16);\n"
andrewboyson 94:d7226b2c14b6 67 " syncedhysppb = parseInt(lines[4], 16);\n"
andrewboyson 94:d7226b2c14b6 68 " slewdivisor = parseInt(lines[5], 16);\n"
andrewboyson 94:d7226b2c14b6 69 " slewmax = parseInt(lines[6], 16);\n"
andrewboyson 94:d7226b2c14b6 70 " syncedlimitns = parseInt(lines[7], 16);\n"
andrewboyson 94:d7226b2c14b6 71 " syncedhysns = parseInt(lines[8], 16);\n"
andrewboyson 94:d7226b2c14b6 72 " maxoffsetsecs = parseInt(lines[9], 16);\n"
andrewboyson 14:c3c43c8faf0e 73 "}\n"
andrewboyson 94:d7226b2c14b6 74 "function parseLinesNtp(text)\n"
andrewboyson 94:d7226b2c14b6 75 "{\n"
andrewboyson 94:d7226b2c14b6 76 " let lines = text.split('\\n');\n"
andrewboyson 94:d7226b2c14b6 77 " ntpserver = lines[0];\n"
andrewboyson 94:d7226b2c14b6 78 " ntpinitial = parseInt(lines[1], 16);\n"
andrewboyson 94:d7226b2c14b6 79 " ntpnormal = parseInt(lines[2], 16);\n"
andrewboyson 94:d7226b2c14b6 80 " ntpretry = parseInt(lines[3], 16);\n"
andrewboyson 94:d7226b2c14b6 81 " ntpoffset = parseInt(lines[4], 16);\n"
andrewboyson 94:d7226b2c14b6 82 " ntpmaxdelay = parseInt(lines[5], 16);\n"
andrewboyson 94:d7226b2c14b6 83 "}\n"
andrewboyson 94:d7226b2c14b6 84 "function parseLinesScan(text)\n"
andrewboyson 14:c3c43c8faf0e 85 "{\n"
andrewboyson 94:d7226b2c14b6 86 " let lines = text.split('\\n');\n"
andrewboyson 94:d7226b2c14b6 87 " scanavg = parseInt(lines[0], 16);\n"
andrewboyson 94:d7226b2c14b6 88 " scanmax = parseInt(lines[1], 16);\n"
andrewboyson 94:d7226b2c14b6 89 " scanmin = parseInt(lines[2], 16);\n"
andrewboyson 94:d7226b2c14b6 90 "}\n"
andrewboyson 95:8c9dda8a0caf 91 "function parse()\n"
andrewboyson 94:d7226b2c14b6 92 "{\n"
andrewboyson 95:8c9dda8a0caf 93 " let topics = Ajax.response.split('\\f');\n"
andrewboyson 94:d7226b2c14b6 94 " parseLinesTime(topics[0]);\n"
andrewboyson 94:d7226b2c14b6 95 " parseLinesGov (topics[1]);\n"
andrewboyson 94:d7226b2c14b6 96 " parseLinesNtp (topics[2]);\n"
andrewboyson 94:d7226b2c14b6 97 " parseLinesScan(topics[3]);\n"
andrewboyson 94:d7226b2c14b6 98 "}\n"
andrewboyson 95:8c9dda8a0caf 99 "function display()\n"
andrewboyson 94:d7226b2c14b6 100 "{\n"
andrewboyson 94:d7226b2c14b6 101 " let elem;\n"
andrewboyson 95:8c9dda8a0caf 102 " elem = Ajax.getElementOrNull('ajax-rtc-set' ); if (elem) elem.setAttribute('dir', rtcIsSet ? 'rtl' : 'ltr');\n"
andrewboyson 95:8c9dda8a0caf 103 " elem = Ajax.getElementOrNull('ajax-clock-set' ); if (elem) elem.setAttribute('dir', clockIsSet ? 'rtl' : 'ltr');\n"
andrewboyson 95:8c9dda8a0caf 104 " elem = Ajax.getElementOrNull('ajax-source-ok' ); if (elem) elem.setAttribute('dir', sourceIsOk ? 'rtl' : 'ltr');\n"
andrewboyson 95:8c9dda8a0caf 105 " elem = Ajax.getElementOrNull('ajax-rate-locked' ); if (elem) elem.setAttribute('dir', rateIsLocked ? 'rtl' : 'ltr');\n"
andrewboyson 95:8c9dda8a0caf 106 " elem = Ajax.getElementOrNull('ajax-time-locked' ); if (elem) elem.setAttribute('dir', timeIsLocked ? 'rtl' : 'ltr');\n"
andrewboyson 14:c3c43c8faf0e 107 " \n"
andrewboyson 95:8c9dda8a0caf 108 " elem = Ajax.getElementOrNull('ajax-leap-enable' ); if (elem) elem.setAttribute('dir', rtc.leapEnable ? 'rtl' : 'ltr');\n"
andrewboyson 95:8c9dda8a0caf 109 " elem = Ajax.getElementOrNull('ajax-leap-forward' ); if (elem) elem.setAttribute('dir', rtc.leapForward ? 'rtl' : 'ltr');\n"
andrewboyson 14:c3c43c8faf0e 110 " \n"
andrewboyson 95:8c9dda8a0caf 111 " elem = Ajax.getElementOrNull('ajax-leap-year' ); if (elem) elem.value = rtc.months1970 ? rtc.leapYear : '';\n"
andrewboyson 95:8c9dda8a0caf 112 " elem = Ajax.getElementOrNull('ajax-leap-month' ); if (elem) elem.value = rtc.months1970 ? rtc.leapMonth : '';\n"
andrewboyson 94:d7226b2c14b6 113 " \n"
andrewboyson 95:8c9dda8a0caf 114 " elem = Ajax.getElementOrNull('ajax-leap-count' ); if (elem) elem.value = rtc.leaps;\n"
andrewboyson 94:d7226b2c14b6 115 " \n"
andrewboyson 95:8c9dda8a0caf 116 " elem = Ajax.getElementOrNull('ajax-ppb' ); if (elem) elem.value = ppb;\n"
andrewboyson 95:8c9dda8a0caf 117 " elem = Ajax.getElementOrNull('ajax-ppb-divisor' ); if (elem) elem.value = ppbdivisor;\n"
andrewboyson 95:8c9dda8a0caf 118 " elem = Ajax.getElementOrNull('ajax-ppb-max-chg' ); if (elem) elem.value = ppbmaxchange;\n"
andrewboyson 95:8c9dda8a0caf 119 " elem = Ajax.getElementOrNull('ajax-ppb-syn-lim' ); if (elem) elem.value = syncedlimitppb;\n"
andrewboyson 95:8c9dda8a0caf 120 " elem = Ajax.getElementOrNull('ajax-ppb-syn-hys' ); if (elem) elem.value = syncedhysppb;\n"
andrewboyson 95:8c9dda8a0caf 121 " elem = Ajax.getElementOrNull('ajax-off-divisor' ); if (elem) elem.value = slewdivisor;\n"
andrewboyson 95:8c9dda8a0caf 122 " elem = Ajax.getElementOrNull('ajax-off-max' ); if (elem) elem.value = slewmax;\n"
andrewboyson 95:8c9dda8a0caf 123 " elem = Ajax.getElementOrNull('ajax-off-syn-lim' ); if (elem) elem.value = syncedlimitns / 1000000;\n"
andrewboyson 95:8c9dda8a0caf 124 " elem = Ajax.getElementOrNull('ajax-off-syn-hys' ); if (elem) elem.value = syncedhysns / 1000000;\n"
andrewboyson 95:8c9dda8a0caf 125 " elem = Ajax.getElementOrNull('ajax-off-rst-lim' ); if (elem) elem.value = maxoffsetsecs;\n"
andrewboyson 95:8c9dda8a0caf 126 " elem = Ajax.getElementOrNull('ajax-gov-trace' ); if (elem) elem.setAttribute('dir', govTrace ? 'rtl' : 'ltr');\n"
andrewboyson 94:d7226b2c14b6 127 " \n"
andrewboyson 95:8c9dda8a0caf 128 " elem = Ajax.getElementOrNull('ajax-ntp-server' ); if (elem) elem.value = ntpserver;\n"
andrewboyson 95:8c9dda8a0caf 129 " elem = Ajax.getElementOrNull('ajax-ntp-initial' ); if (elem) elem.value = ntpinitial;\n"
andrewboyson 95:8c9dda8a0caf 130 " elem = Ajax.getElementOrNull('ajax-ntp-normal' ); if (elem) elem.value = ntpnormal / 60;\n"
andrewboyson 95:8c9dda8a0caf 131 " elem = Ajax.getElementOrNull('ajax-ntp-retry' ); if (elem) elem.value = ntpretry;\n"
andrewboyson 95:8c9dda8a0caf 132 " elem = Ajax.getElementOrNull('ajax-ntp-offset' ); if (elem) elem.value = ntpoffset;\n"
andrewboyson 95:8c9dda8a0caf 133 " elem = Ajax.getElementOrNull('ajax-ntp-max-delay'); if (elem) elem.value = ntpmaxdelay;\n"
andrewboyson 94:d7226b2c14b6 134 " \n"
andrewboyson 95:8c9dda8a0caf 135 " elem = Ajax.getElementOrNull('ajax-scan-avg' ); if (elem) elem.textContent = scanavg;\n"
andrewboyson 95:8c9dda8a0caf 136 " elem = Ajax.getElementOrNull('ajax-scan-max' ); if (elem) elem.textContent = scanmax;\n"
andrewboyson 95:8c9dda8a0caf 137 " elem = Ajax.getElementOrNull('ajax-scan-min' ); if (elem) elem.textContent = scanmin;\n"
andrewboyson 94:d7226b2c14b6 138 " \n"
andrewboyson 95:8c9dda8a0caf 139 " elem = Ajax.getElementOrNull('ajax-date-diff' ); if (elem) elem.textContent = diffMs;\n"
andrewboyson 14:c3c43c8faf0e 140 "}\n"
andrewboyson 96:eb2eb75bad0f 141 "\n"
andrewboyson 95:8c9dda8a0caf 142 "function handleTick() //This typically called every 100ms\n"
andrewboyson 14:c3c43c8faf0e 143 "{\n"
andrewboyson 94:d7226b2c14b6 144 " if (pseudoDisplay)\n"
andrewboyson 14:c3c43c8faf0e 145 " {\n"
andrewboyson 95:8c9dda8a0caf 146 " pseudo.adjustLeap (Ajax.ms);\n"
andrewboyson 95:8c9dda8a0caf 147 " pseudo.displayTime(Ajax.ms);\n"
andrewboyson 95:8c9dda8a0caf 148 " if (Ajax.ms >= pseudoStartMs + DISPLAY_LEAP_MS + 500) pseudoDisplay = false;\n"
andrewboyson 14:c3c43c8faf0e 149 " }\n"
andrewboyson 94:d7226b2c14b6 150 " else\n"
andrewboyson 94:d7226b2c14b6 151 " {\n"
andrewboyson 95:8c9dda8a0caf 152 " rtc.adjustLeap (Ajax.ms);\n"
andrewboyson 95:8c9dda8a0caf 153 " rtc.displayTime(Ajax.ms);\n"
andrewboyson 94:d7226b2c14b6 154 " }\n"
andrewboyson 14:c3c43c8faf0e 155 "}\n"
andrewboyson 14:c3c43c8faf0e 156 "\n"
andrewboyson 95:8c9dda8a0caf 157 "function displayLeap() //Called by display leap button in HTML\n"
andrewboyson 14:c3c43c8faf0e 158 "{\n"
andrewboyson 94:d7226b2c14b6 159 " pseudoDisplay = true;\n"
andrewboyson 95:8c9dda8a0caf 160 " pseudoStartMs = Ajax.ms;\n"
andrewboyson 94:d7226b2c14b6 161 " \n"
andrewboyson 94:d7226b2c14b6 162 " pseudo.leapEnable = true;\n"
andrewboyson 94:d7226b2c14b6 163 " pseudo.leapForward = rtc.leapForward;\n"
andrewboyson 94:d7226b2c14b6 164 " pseudo.leaps = rtc.leaps;\n"
andrewboyson 94:d7226b2c14b6 165 " pseudo.leapMonth = rtc.leapMonth;\n"
andrewboyson 94:d7226b2c14b6 166 " pseudo.leapYear = rtc.leapYear;\n"
andrewboyson 95:8c9dda8a0caf 167 " pseudo.ms = Date.UTC(rtc.leapYear, rtc.leapMonth - 1, 1) - DISPLAY_LEAP_MS / 2 - Ajax.ms;\n"
andrewboyson 14:c3c43c8faf0e 168 "}\n"
andrewboyson 95:8c9dda8a0caf 169 "Ajax.server = '/clock-ajax';\n"
andrewboyson 95:8c9dda8a0caf 170 "Ajax.onResponse = function() { parse(); display(); };\n"
andrewboyson 95:8c9dda8a0caf 171 "Ajax.onTick = handleTick;\n"
andrewboyson 95:8c9dda8a0caf 172 "Ajax.init();"