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:
Tue Sep 24 18:16:47 2019 +0000
Revision:
130:9a5b8fe308f1
Parent:
web-connection.c@128:fc9708e1d17c
Added http

Who changed what in which revision?

UserRevisionLine numberNew contents of line
andrewboyson 128:fc9708e1d17c 1 #include <stdlib.h>
andrewboyson 128:fc9708e1d17c 2
andrewboyson 130:9a5b8fe308f1 3 #include "http-connection.h"
andrewboyson 128:fc9708e1d17c 4 #include "mstimer.h"
andrewboyson 128:fc9708e1d17c 5
andrewboyson 128:fc9708e1d17c 6 #define MAX_CONNECTIONS 10
andrewboyson 128:fc9708e1d17c 7
andrewboyson 130:9a5b8fe308f1 8 static struct HttpConnection connections[MAX_CONNECTIONS];
andrewboyson 128:fc9708e1d17c 9
andrewboyson 130:9a5b8fe308f1 10 static void zeroConnection(struct HttpConnection* p)
andrewboyson 128:fc9708e1d17c 11 {
andrewboyson 128:fc9708e1d17c 12 p->id = 0;
andrewboyson 128:fc9708e1d17c 13 p->lastUsed = 0;
andrewboyson 128:fc9708e1d17c 14 p->toDo = 0;
andrewboyson 128:fc9708e1d17c 15 p->postComplete = false;
andrewboyson 128:fc9708e1d17c 16 p->delayUntil = 0;
andrewboyson 128:fc9708e1d17c 17 }
andrewboyson 128:fc9708e1d17c 18
andrewboyson 130:9a5b8fe308f1 19 struct HttpConnection* HttpConnectionNew(int connectionId) //Never fails so never returns NULL
andrewboyson 128:fc9708e1d17c 20 {
andrewboyson 130:9a5b8fe308f1 21 struct HttpConnection* p;
andrewboyson 128:fc9708e1d17c 22
andrewboyson 128:fc9708e1d17c 23 //Look for an existing connection
andrewboyson 128:fc9708e1d17c 24 for (p = connections; p < connections + MAX_CONNECTIONS; p++)
andrewboyson 128:fc9708e1d17c 25 {
andrewboyson 128:fc9708e1d17c 26 if (p->id == connectionId) goto end;
andrewboyson 128:fc9708e1d17c 27 }
andrewboyson 128:fc9708e1d17c 28
andrewboyson 128:fc9708e1d17c 29 //look for an empty connection
andrewboyson 128:fc9708e1d17c 30 {
andrewboyson 130:9a5b8fe308f1 31 struct HttpConnection* pOldest = 0;
andrewboyson 128:fc9708e1d17c 32 uint32_t ageOldest = 0;
andrewboyson 128:fc9708e1d17c 33 for (p = connections; p < connections + MAX_CONNECTIONS; p++)
andrewboyson 128:fc9708e1d17c 34 {
andrewboyson 128:fc9708e1d17c 35 if (!p->id) goto end;
andrewboyson 128:fc9708e1d17c 36
andrewboyson 128:fc9708e1d17c 37 //Otherwise record the oldest and keep going
andrewboyson 128:fc9708e1d17c 38 uint32_t age = MsTimerCount - p->lastUsed;
andrewboyson 128:fc9708e1d17c 39 if (age >= ageOldest)
andrewboyson 128:fc9708e1d17c 40 {
andrewboyson 128:fc9708e1d17c 41 ageOldest = age;
andrewboyson 128:fc9708e1d17c 42 pOldest = p;
andrewboyson 128:fc9708e1d17c 43 }
andrewboyson 128:fc9708e1d17c 44 }
andrewboyson 128:fc9708e1d17c 45
andrewboyson 128:fc9708e1d17c 46 //No empty ones found so use the oldest
andrewboyson 128:fc9708e1d17c 47 p = pOldest;
andrewboyson 128:fc9708e1d17c 48 }
andrewboyson 128:fc9708e1d17c 49
andrewboyson 128:fc9708e1d17c 50 end:
andrewboyson 128:fc9708e1d17c 51 zeroConnection(p);
andrewboyson 128:fc9708e1d17c 52 p->id = connectionId;
andrewboyson 128:fc9708e1d17c 53 p->lastUsed = MsTimerCount;
andrewboyson 128:fc9708e1d17c 54 return p;
andrewboyson 128:fc9708e1d17c 55 }
andrewboyson 130:9a5b8fe308f1 56 struct HttpConnection* HttpConnectionOrNull(int connectionId)
andrewboyson 128:fc9708e1d17c 57 {
andrewboyson 130:9a5b8fe308f1 58 for (struct HttpConnection* p = connections; p < connections + MAX_CONNECTIONS; p++)
andrewboyson 128:fc9708e1d17c 59 {
andrewboyson 128:fc9708e1d17c 60 if (p->id == connectionId)
andrewboyson 128:fc9708e1d17c 61 {
andrewboyson 128:fc9708e1d17c 62 p->lastUsed = MsTimerCount;
andrewboyson 128:fc9708e1d17c 63 return p;
andrewboyson 128:fc9708e1d17c 64 }
andrewboyson 128:fc9708e1d17c 65 }
andrewboyson 128:fc9708e1d17c 66 return NULL;
andrewboyson 128:fc9708e1d17c 67 }
andrewboyson 130:9a5b8fe308f1 68 void HttpConnectionReset(int connectionId)
andrewboyson 128:fc9708e1d17c 69 {
andrewboyson 130:9a5b8fe308f1 70 for (struct HttpConnection* p = connections; p < connections + MAX_CONNECTIONS; p++)
andrewboyson 128:fc9708e1d17c 71 {
andrewboyson 128:fc9708e1d17c 72 if (p->id == connectionId) zeroConnection(p);
andrewboyson 128:fc9708e1d17c 73 }
andrewboyson 128:fc9708e1d17c 74 }