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:
Sat Apr 24 09:51:26 2021 +0000
Revision:
159:bda5b89e8c19
Parent:
130:9a5b8fe308f1
Added HttpAddTextN to allow a length limited addition.; Updated HttpQueryValueAsInt and HttpQueryUnencode to mot fail if passed a NUL.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
andrewboyson 130:9a5b8fe308f1 1 #include <time.h>
andrewboyson 130:9a5b8fe308f1 2 #include <stdio.h>
andrewboyson 130:9a5b8fe308f1 3 #include <stdbool.h>
andrewboyson 130:9a5b8fe308f1 4 #include <stdint.h>
andrewboyson 130:9a5b8fe308f1 5 #include <stdarg.h>
andrewboyson 130:9a5b8fe308f1 6
andrewboyson 130:9a5b8fe308f1 7 static uint32_t currentPositionInMessage;
andrewboyson 130:9a5b8fe308f1 8 static uint32_t bufferPositionInMessage;
andrewboyson 130:9a5b8fe308f1 9 static int bufferLength;
andrewboyson 130:9a5b8fe308f1 10 static char* pBuffer;
andrewboyson 130:9a5b8fe308f1 11 static char* p;
andrewboyson 130:9a5b8fe308f1 12
andrewboyson 130:9a5b8fe308f1 13 void HttpAddStart(uint32_t position, int mss, char *pData)
andrewboyson 130:9a5b8fe308f1 14 {
andrewboyson 130:9a5b8fe308f1 15 currentPositionInMessage = 0;
andrewboyson 130:9a5b8fe308f1 16 bufferPositionInMessage = position;
andrewboyson 130:9a5b8fe308f1 17 bufferLength = mss;
andrewboyson 130:9a5b8fe308f1 18 pBuffer = pData;
andrewboyson 130:9a5b8fe308f1 19 p = pData;
andrewboyson 130:9a5b8fe308f1 20 }
andrewboyson 130:9a5b8fe308f1 21 int HttpAddLength()
andrewboyson 130:9a5b8fe308f1 22 {
andrewboyson 130:9a5b8fe308f1 23 return p - pBuffer;
andrewboyson 130:9a5b8fe308f1 24 }
andrewboyson 130:9a5b8fe308f1 25 bool HttpAddFilled()
andrewboyson 130:9a5b8fe308f1 26 {
andrewboyson 130:9a5b8fe308f1 27 return p - pBuffer >= bufferLength;
andrewboyson 130:9a5b8fe308f1 28 }
andrewboyson 130:9a5b8fe308f1 29
andrewboyson 130:9a5b8fe308f1 30 void HttpAddChar(char c)
andrewboyson 130:9a5b8fe308f1 31 {
andrewboyson 130:9a5b8fe308f1 32 //Add character if the current position is within the buffer
andrewboyson 130:9a5b8fe308f1 33 if (currentPositionInMessage >= bufferPositionInMessage &&
andrewboyson 130:9a5b8fe308f1 34 currentPositionInMessage < bufferPositionInMessage + bufferLength) *p++ = c;
andrewboyson 130:9a5b8fe308f1 35
andrewboyson 130:9a5b8fe308f1 36 currentPositionInMessage++;
andrewboyson 130:9a5b8fe308f1 37 }
andrewboyson 130:9a5b8fe308f1 38
andrewboyson 130:9a5b8fe308f1 39 void HttpAddFillChar (char c, int length)
andrewboyson 130:9a5b8fe308f1 40 {
andrewboyson 130:9a5b8fe308f1 41 while (length > 0)
andrewboyson 130:9a5b8fe308f1 42 {
andrewboyson 130:9a5b8fe308f1 43 HttpAddChar(c);
andrewboyson 130:9a5b8fe308f1 44 length--;
andrewboyson 130:9a5b8fe308f1 45 }
andrewboyson 130:9a5b8fe308f1 46 }
andrewboyson 130:9a5b8fe308f1 47 int HttpAddText (const char* text)
andrewboyson 130:9a5b8fe308f1 48 {
andrewboyson 130:9a5b8fe308f1 49 const char* start = text;
andrewboyson 130:9a5b8fe308f1 50 while (*text)
andrewboyson 130:9a5b8fe308f1 51 {
andrewboyson 130:9a5b8fe308f1 52 HttpAddChar(*text);
andrewboyson 130:9a5b8fe308f1 53 text++;
andrewboyson 130:9a5b8fe308f1 54 }
andrewboyson 130:9a5b8fe308f1 55 return text - start;
andrewboyson 130:9a5b8fe308f1 56 }
andrewboyson 159:bda5b89e8c19 57 int HttpAddTextN (const char* text, int bufferLength)
andrewboyson 159:bda5b89e8c19 58 {
andrewboyson 159:bda5b89e8c19 59 const char* start = text;
andrewboyson 159:bda5b89e8c19 60 while (*text && text - start < bufferLength)
andrewboyson 159:bda5b89e8c19 61 {
andrewboyson 159:bda5b89e8c19 62 HttpAddChar(*text);
andrewboyson 159:bda5b89e8c19 63 text++;
andrewboyson 159:bda5b89e8c19 64 }
andrewboyson 159:bda5b89e8c19 65 return text - start;
andrewboyson 159:bda5b89e8c19 66 }
andrewboyson 130:9a5b8fe308f1 67 int HttpAddV (char *fmt, va_list argptr)
andrewboyson 130:9a5b8fe308f1 68 {
andrewboyson 130:9a5b8fe308f1 69 int size = vsnprintf(NULL, 0, fmt, argptr); //Find the size required
andrewboyson 130:9a5b8fe308f1 70 char text[size + 1]; //Allocate enough memory for the size required with an extra byte for the terminating null
andrewboyson 130:9a5b8fe308f1 71 vsprintf(text, fmt, argptr); //Fill the new buffer
andrewboyson 130:9a5b8fe308f1 72 return HttpAddText(text); //Add the text
andrewboyson 130:9a5b8fe308f1 73 }
andrewboyson 130:9a5b8fe308f1 74 int HttpAddF (char *fmt, ...)
andrewboyson 130:9a5b8fe308f1 75 {
andrewboyson 130:9a5b8fe308f1 76 va_list argptr;
andrewboyson 130:9a5b8fe308f1 77 va_start(argptr, fmt);
andrewboyson 130:9a5b8fe308f1 78 int size = HttpAddV(fmt, argptr);
andrewboyson 130:9a5b8fe308f1 79 va_end(argptr);
andrewboyson 130:9a5b8fe308f1 80 return size;
andrewboyson 130:9a5b8fe308f1 81 }
andrewboyson 130:9a5b8fe308f1 82 void HttpAddData (const char* data, int length)
andrewboyson 130:9a5b8fe308f1 83 {
andrewboyson 130:9a5b8fe308f1 84 while (length > 0)
andrewboyson 130:9a5b8fe308f1 85 {
andrewboyson 130:9a5b8fe308f1 86 HttpAddChar(*data);
andrewboyson 130:9a5b8fe308f1 87 data++;
andrewboyson 130:9a5b8fe308f1 88 length--;
andrewboyson 130:9a5b8fe308f1 89 }
andrewboyson 130:9a5b8fe308f1 90 }
andrewboyson 130:9a5b8fe308f1 91 void HttpAddStream(void (*startFunction)(void), int (*enumerateFunction)(void))
andrewboyson 130:9a5b8fe308f1 92 {
andrewboyson 130:9a5b8fe308f1 93 startFunction();
andrewboyson 130:9a5b8fe308f1 94 while (true)
andrewboyson 130:9a5b8fe308f1 95 {
andrewboyson 130:9a5b8fe308f1 96 int c = enumerateFunction();
andrewboyson 130:9a5b8fe308f1 97 if (c == EOF) break;
andrewboyson 130:9a5b8fe308f1 98 HttpAddChar(c);
andrewboyson 130:9a5b8fe308f1 99 }
andrewboyson 130:9a5b8fe308f1 100 }
andrewboyson 130:9a5b8fe308f1 101 void HttpAddNibbleAsHex(int nibble)
andrewboyson 130:9a5b8fe308f1 102 {
andrewboyson 130:9a5b8fe308f1 103 nibble &= 0x0F;
andrewboyson 130:9a5b8fe308f1 104 char c;
andrewboyson 130:9a5b8fe308f1 105 if (nibble < 0x0A) c = nibble + '0';
andrewboyson 130:9a5b8fe308f1 106 else if (nibble < 0x10) c = nibble - 0xA + 'A';
andrewboyson 130:9a5b8fe308f1 107 else c = '0';
andrewboyson 130:9a5b8fe308f1 108 HttpAddChar(c);
andrewboyson 130:9a5b8fe308f1 109 }
andrewboyson 130:9a5b8fe308f1 110 void HttpAddByteAsHex(int value)
andrewboyson 130:9a5b8fe308f1 111 {
andrewboyson 130:9a5b8fe308f1 112 HttpAddNibbleAsHex(value >> 4);
andrewboyson 130:9a5b8fe308f1 113 HttpAddNibbleAsHex(value >> 0);
andrewboyson 130:9a5b8fe308f1 114 }
andrewboyson 130:9a5b8fe308f1 115 void HttpAddInt12AsHex(int value)
andrewboyson 130:9a5b8fe308f1 116 {
andrewboyson 130:9a5b8fe308f1 117 HttpAddNibbleAsHex(value >> 8);
andrewboyson 130:9a5b8fe308f1 118 HttpAddNibbleAsHex(value >> 4);
andrewboyson 130:9a5b8fe308f1 119 HttpAddNibbleAsHex(value >> 0);
andrewboyson 130:9a5b8fe308f1 120 }
andrewboyson 130:9a5b8fe308f1 121 void HttpAddInt16AsHex(int value)
andrewboyson 130:9a5b8fe308f1 122 {
andrewboyson 130:9a5b8fe308f1 123 HttpAddNibbleAsHex(value >> 12);
andrewboyson 130:9a5b8fe308f1 124 HttpAddNibbleAsHex(value >> 8);
andrewboyson 130:9a5b8fe308f1 125 HttpAddNibbleAsHex(value >> 4);
andrewboyson 130:9a5b8fe308f1 126 HttpAddNibbleAsHex(value >> 0);
andrewboyson 130:9a5b8fe308f1 127 }
andrewboyson 130:9a5b8fe308f1 128 void HttpAddInt32AsHex(int value)
andrewboyson 130:9a5b8fe308f1 129 {
andrewboyson 130:9a5b8fe308f1 130 HttpAddNibbleAsHex(value >> 28);
andrewboyson 130:9a5b8fe308f1 131 HttpAddNibbleAsHex(value >> 24);
andrewboyson 130:9a5b8fe308f1 132 HttpAddNibbleAsHex(value >> 20);
andrewboyson 130:9a5b8fe308f1 133 HttpAddNibbleAsHex(value >> 16);
andrewboyson 130:9a5b8fe308f1 134 HttpAddNibbleAsHex(value >> 12);
andrewboyson 130:9a5b8fe308f1 135 HttpAddNibbleAsHex(value >> 8);
andrewboyson 130:9a5b8fe308f1 136 HttpAddNibbleAsHex(value >> 4);
andrewboyson 130:9a5b8fe308f1 137 HttpAddNibbleAsHex(value >> 0);
andrewboyson 130:9a5b8fe308f1 138 }
andrewboyson 130:9a5b8fe308f1 139 void HttpAddInt64AsHex(int64_t value)
andrewboyson 130:9a5b8fe308f1 140 {
andrewboyson 130:9a5b8fe308f1 141 HttpAddNibbleAsHex(value >> 60);
andrewboyson 130:9a5b8fe308f1 142 HttpAddNibbleAsHex(value >> 56);
andrewboyson 130:9a5b8fe308f1 143 HttpAddNibbleAsHex(value >> 52);
andrewboyson 130:9a5b8fe308f1 144 HttpAddNibbleAsHex(value >> 48);
andrewboyson 130:9a5b8fe308f1 145 HttpAddNibbleAsHex(value >> 44);
andrewboyson 130:9a5b8fe308f1 146 HttpAddNibbleAsHex(value >> 40);
andrewboyson 130:9a5b8fe308f1 147 HttpAddNibbleAsHex(value >> 36);
andrewboyson 130:9a5b8fe308f1 148 HttpAddNibbleAsHex(value >> 32);
andrewboyson 130:9a5b8fe308f1 149 HttpAddNibbleAsHex(value >> 28);
andrewboyson 130:9a5b8fe308f1 150 HttpAddNibbleAsHex(value >> 24);
andrewboyson 130:9a5b8fe308f1 151 HttpAddNibbleAsHex(value >> 20);
andrewboyson 130:9a5b8fe308f1 152 HttpAddNibbleAsHex(value >> 16);
andrewboyson 130:9a5b8fe308f1 153 HttpAddNibbleAsHex(value >> 12);
andrewboyson 130:9a5b8fe308f1 154 HttpAddNibbleAsHex(value >> 8);
andrewboyson 130:9a5b8fe308f1 155 HttpAddNibbleAsHex(value >> 4);
andrewboyson 130:9a5b8fe308f1 156 HttpAddNibbleAsHex(value >> 0);
andrewboyson 130:9a5b8fe308f1 157 }
andrewboyson 130:9a5b8fe308f1 158 void HttpAddBytesAsHex(const uint8_t* value, int size)
andrewboyson 130:9a5b8fe308f1 159 {
andrewboyson 130:9a5b8fe308f1 160 int i = 0;
andrewboyson 130:9a5b8fe308f1 161 while(true)
andrewboyson 130:9a5b8fe308f1 162 {
andrewboyson 130:9a5b8fe308f1 163 HttpAddByteAsHex(value[i]);
andrewboyson 130:9a5b8fe308f1 164 i++;
andrewboyson 130:9a5b8fe308f1 165 if (i >= size) break;
andrewboyson 130:9a5b8fe308f1 166 if (i % 16 == 0) HttpAddText("\r\n");
andrewboyson 130:9a5b8fe308f1 167 else HttpAddChar(' ');
andrewboyson 130:9a5b8fe308f1 168 }
andrewboyson 130:9a5b8fe308f1 169 }
andrewboyson 130:9a5b8fe308f1 170 void HttpAddBytesAsHexRev(const uint8_t* value, int size)
andrewboyson 130:9a5b8fe308f1 171 {
andrewboyson 130:9a5b8fe308f1 172 int i = 0;
andrewboyson 130:9a5b8fe308f1 173 while(true)
andrewboyson 130:9a5b8fe308f1 174 {
andrewboyson 130:9a5b8fe308f1 175 HttpAddByteAsHex(value[size - i - 1]);
andrewboyson 130:9a5b8fe308f1 176 i++;
andrewboyson 130:9a5b8fe308f1 177 if (i >= size) break;
andrewboyson 130:9a5b8fe308f1 178 if (i % 16 == 0) HttpAddText("\r\n");
andrewboyson 130:9a5b8fe308f1 179 else HttpAddChar(' ');
andrewboyson 130:9a5b8fe308f1 180 }
andrewboyson 130:9a5b8fe308f1 181 }
andrewboyson 130:9a5b8fe308f1 182 void HttpAddTm(struct tm* ptm)
andrewboyson 130:9a5b8fe308f1 183 {
andrewboyson 130:9a5b8fe308f1 184 HttpAddF("%d-%02d-%02d ", ptm->tm_year + 1900, ptm->tm_mon + 1, ptm->tm_mday);
andrewboyson 130:9a5b8fe308f1 185 switch(ptm->tm_wday)
andrewboyson 130:9a5b8fe308f1 186 {
andrewboyson 130:9a5b8fe308f1 187 case 0: HttpAddText("Sun"); break;
andrewboyson 130:9a5b8fe308f1 188 case 1: HttpAddText("Mon"); break;
andrewboyson 130:9a5b8fe308f1 189 case 2: HttpAddText("Tue"); break;
andrewboyson 130:9a5b8fe308f1 190 case 3: HttpAddText("Wed"); break;
andrewboyson 130:9a5b8fe308f1 191 case 4: HttpAddText("Thu"); break;
andrewboyson 130:9a5b8fe308f1 192 case 5: HttpAddText("Fri"); break;
andrewboyson 130:9a5b8fe308f1 193 case 6: HttpAddText("Sat"); break;
andrewboyson 130:9a5b8fe308f1 194 default: HttpAddText("???"); break;
andrewboyson 130:9a5b8fe308f1 195 }
andrewboyson 130:9a5b8fe308f1 196 HttpAddF(" %02d:%02d:%02d", ptm->tm_hour, ptm->tm_min, ptm->tm_sec);
andrewboyson 130:9a5b8fe308f1 197 if (ptm->tm_isdst > 0) HttpAddText(" BST");
andrewboyson 130:9a5b8fe308f1 198 else if (ptm->tm_isdst == 0) HttpAddText(" GMT");
andrewboyson 130:9a5b8fe308f1 199 else HttpAddText(" UTC");
andrewboyson 130:9a5b8fe308f1 200 }