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:
Fri Mar 01 08:32:14 2019 +0000
Revision:
51:c605b2794b44
Parent:
50:edd44fe9320f
Child:
53:27d56a22a450
Added list of local files to the ajax response so that the firmware page updated correctly after uploading new firmware.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
andrewboyson 50:edd44fe9320f 1 'use strict';
andrewboyson 50:edd44fe9320f 2
andrewboyson 48:4e678727c4c9 3 var file;
andrewboyson 46:1822fdbe6c0c 4 var xhr;
andrewboyson 48:4e678727c4c9 5 var fr;
andrewboyson 48:4e678727c4c9 6 var checksum;
andrewboyson 48:4e678727c4c9 7
andrewboyson 50:edd44fe9320f 8 function log(text)
andrewboyson 50:edd44fe9320f 9 {
andrewboyson 50:edd44fe9320f 10 document.getElementById('result').textContent = text;
andrewboyson 50:edd44fe9320f 11 }
andrewboyson 51:c605b2794b44 12 function displayResponse()
andrewboyson 51:c605b2794b44 13 {
andrewboyson 51:c605b2794b44 14 var topics = xhr.responseText.split('\f');
andrewboyson 51:c605b2794b44 15 log(topics[0]);
andrewboyson 51:c605b2794b44 16 if (topics.length > 1) document.getElementById('list').textContent = topics[1];
andrewboyson 51:c605b2794b44 17 }
andrewboyson 46:1822fdbe6c0c 18 function xhrOnLoad()
andrewboyson 46:1822fdbe6c0c 19 {
andrewboyson 51:c605b2794b44 20 if (xhr.status == 200) displayResponse();
andrewboyson 50:edd44fe9320f 21 else log('Upload failed');
andrewboyson 46:1822fdbe6c0c 22 }
andrewboyson 46:1822fdbe6c0c 23 function xhrOnError()
andrewboyson 46:1822fdbe6c0c 24 {
andrewboyson 50:edd44fe9320f 25 log('Upload error');
andrewboyson 46:1822fdbe6c0c 26 }
andrewboyson 48:4e678727c4c9 27 function startXhr()
andrewboyson 48:4e678727c4c9 28 {
andrewboyson 50:edd44fe9320f 29 log('Uploading...');
andrewboyson 48:4e678727c4c9 30
andrewboyson 48:4e678727c4c9 31 xhr = new XMLHttpRequest();
andrewboyson 48:4e678727c4c9 32
andrewboyson 48:4e678727c4c9 33 xhr.onload = xhrOnLoad;
andrewboyson 48:4e678727c4c9 34 xhr.onerror = xhrOnError;
andrewboyson 48:4e678727c4c9 35
andrewboyson 49:66f5471a19dc 36 xhr.open('POST', '/firmware-ajax?checksum=' + checksum, true);
andrewboyson 48:4e678727c4c9 37 xhr.send(file);
andrewboyson 48:4e678727c4c9 38 }
andrewboyson 48:4e678727c4c9 39
andrewboyson 48:4e678727c4c9 40 function frOnLoad()
andrewboyson 48:4e678727c4c9 41 {
andrewboyson 48:4e678727c4c9 42 var arrayBuffer = fr.result;
andrewboyson 48:4e678727c4c9 43 var bytes = new Uint8Array(arrayBuffer);
andrewboyson 50:edd44fe9320f 44 for (var i = 0; i < bytes.length; ++i )
andrewboyson 48:4e678727c4c9 45 {
andrewboyson 48:4e678727c4c9 46 checksum = (checksum + bytes[i]) >>> 0;
andrewboyson 48:4e678727c4c9 47 }
andrewboyson 48:4e678727c4c9 48 startXhr();
andrewboyson 48:4e678727c4c9 49 }
andrewboyson 48:4e678727c4c9 50 function frOnError()
andrewboyson 48:4e678727c4c9 51 {
andrewboyson 50:edd44fe9320f 52 log('Check sum calculation error');
andrewboyson 48:4e678727c4c9 53 }
andrewboyson 48:4e678727c4c9 54 function startChecksumCalculation()
andrewboyson 48:4e678727c4c9 55 {
andrewboyson 50:edd44fe9320f 56 log('Calculating checksum...');
andrewboyson 48:4e678727c4c9 57
andrewboyson 48:4e678727c4c9 58 checksum = 0;
andrewboyson 48:4e678727c4c9 59
andrewboyson 48:4e678727c4c9 60 fr = new FileReader();
andrewboyson 48:4e678727c4c9 61 fr.onload = frOnLoad;
andrewboyson 48:4e678727c4c9 62 fr.onerror = frOnError;
andrewboyson 48:4e678727c4c9 63
andrewboyson 48:4e678727c4c9 64 fr.readAsArrayBuffer(file);
andrewboyson 48:4e678727c4c9 65 }
andrewboyson 46:1822fdbe6c0c 66
andrewboyson 46:1822fdbe6c0c 67 function startUpload()
andrewboyson 46:1822fdbe6c0c 68 {
andrewboyson 46:1822fdbe6c0c 69 var fileInput = document.getElementById('fileInput');
andrewboyson 46:1822fdbe6c0c 70
andrewboyson 46:1822fdbe6c0c 71 if (fileInput.files.length == 0)
andrewboyson 46:1822fdbe6c0c 72 {
andrewboyson 50:edd44fe9320f 73 log('Please choose a file');
andrewboyson 46:1822fdbe6c0c 74 return;
andrewboyson 46:1822fdbe6c0c 75 }
andrewboyson 46:1822fdbe6c0c 76
andrewboyson 46:1822fdbe6c0c 77 if (fileInput.files.length > 1)
andrewboyson 46:1822fdbe6c0c 78 {
andrewboyson 50:edd44fe9320f 79 log('Please choose just one file');
andrewboyson 46:1822fdbe6c0c 80 return;
andrewboyson 46:1822fdbe6c0c 81 }
andrewboyson 48:4e678727c4c9 82
andrewboyson 48:4e678727c4c9 83 file = fileInput.files[0];
andrewboyson 47:cf7d4c34158e 84
andrewboyson 48:4e678727c4c9 85 startChecksumCalculation();
andrewboyson 48:4e678727c4c9 86 }