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 May 01 10:40:51 2019 +0000
Revision:
113:23507d14f927
Parent:
core/web-add.c@112:f29bb9b99059
Child:
118:53430a2a2595
Renamed 'core' to 'common'

Who changed what in which revision?

UserRevisionLine numberNew contents of line
andrewboyson 109:3e82f62c7e1f 1 #include <stdio.h>
andrewboyson 109:3e82f62c7e1f 2
andrewboyson 109:3e82f62c7e1f 3 #include "http.h"
andrewboyson 109:3e82f62c7e1f 4 #include "web-nav-base.h"
andrewboyson 112:f29bb9b99059 5 #include "web-nav-this.h"
andrewboyson 109:3e82f62c7e1f 6 #include "web-site-name.h"
andrewboyson 109:3e82f62c7e1f 7 #include "mac.h"
andrewboyson 109:3e82f62c7e1f 8 #include "ip4addr.h"
andrewboyson 109:3e82f62c7e1f 9 #include "ip6addr.h"
andrewboyson 109:3e82f62c7e1f 10
andrewboyson 109:3e82f62c7e1f 11 void WebAddNavItem(int highlight, char* href, char* title)
andrewboyson 109:3e82f62c7e1f 12 {
andrewboyson 109:3e82f62c7e1f 13 char *p;
andrewboyson 109:3e82f62c7e1f 14 HttpAddText("<li ");
andrewboyson 109:3e82f62c7e1f 15 if (highlight) p = "class='this'";
andrewboyson 109:3e82f62c7e1f 16 else p = " ";
andrewboyson 109:3e82f62c7e1f 17 HttpAddText(p);
andrewboyson 109:3e82f62c7e1f 18 HttpAddText("><a href='");
andrewboyson 109:3e82f62c7e1f 19 HttpAddText(href);
andrewboyson 109:3e82f62c7e1f 20 HttpAddText("'>");
andrewboyson 109:3e82f62c7e1f 21 HttpAddText(title);
andrewboyson 109:3e82f62c7e1f 22 HttpAddText("</a></li>\r\n");
andrewboyson 109:3e82f62c7e1f 23 }
andrewboyson 109:3e82f62c7e1f 24 void WebAddNav(int page)
andrewboyson 109:3e82f62c7e1f 25 {
andrewboyson 109:3e82f62c7e1f 26 HttpAddText("<a class='tab-shortcut' href='#main-content'>Skip to content</a>\r\n");
andrewboyson 109:3e82f62c7e1f 27
andrewboyson 109:3e82f62c7e1f 28 HttpAddText("<nav><ul>\r\n");
andrewboyson 112:f29bb9b99059 29 WebNavThis(page);
andrewboyson 109:3e82f62c7e1f 30 WebNavBase(page);
andrewboyson 109:3e82f62c7e1f 31 HttpAddText("</ul></nav>\r\n");
andrewboyson 109:3e82f62c7e1f 32 }
andrewboyson 109:3e82f62c7e1f 33
andrewboyson 109:3e82f62c7e1f 34 void WebAddHeader(const char* title, const char* style, const char* script)
andrewboyson 109:3e82f62c7e1f 35 {
andrewboyson 109:3e82f62c7e1f 36 HttpAddText("<!DOCTYPE html>\r\n"
andrewboyson 109:3e82f62c7e1f 37 "<html>\r\n"
andrewboyson 109:3e82f62c7e1f 38 "<head>\r\n");
andrewboyson 109:3e82f62c7e1f 39 HttpAddText(" <title>");
andrewboyson 109:3e82f62c7e1f 40 HttpAddText(WEB_SITE_NAME);
andrewboyson 109:3e82f62c7e1f 41 if (title)
andrewboyson 109:3e82f62c7e1f 42 {
andrewboyson 109:3e82f62c7e1f 43 HttpAddText(" - ");
andrewboyson 109:3e82f62c7e1f 44 HttpAddText(title);
andrewboyson 109:3e82f62c7e1f 45 }
andrewboyson 109:3e82f62c7e1f 46 HttpAddText("</title>\r\n");
andrewboyson 109:3e82f62c7e1f 47
andrewboyson 109:3e82f62c7e1f 48 HttpAddText(" <link rel='stylesheet' href='/base.css' type='text/css'/>\r\n");
andrewboyson 109:3e82f62c7e1f 49 if (style)
andrewboyson 109:3e82f62c7e1f 50 {
andrewboyson 109:3e82f62c7e1f 51 HttpAddText(" <link rel='stylesheet' href='/");
andrewboyson 109:3e82f62c7e1f 52 HttpAddText(style);
andrewboyson 109:3e82f62c7e1f 53 HttpAddText("' type='text/css'/>\r\n");
andrewboyson 109:3e82f62c7e1f 54 }
andrewboyson 109:3e82f62c7e1f 55 if (script)
andrewboyson 109:3e82f62c7e1f 56 {
andrewboyson 109:3e82f62c7e1f 57 HttpAddText(" <script src='/");
andrewboyson 109:3e82f62c7e1f 58 HttpAddText(script);
andrewboyson 109:3e82f62c7e1f 59 HttpAddText("' type='text/javascript'></script>\r\n");
andrewboyson 109:3e82f62c7e1f 60 }
andrewboyson 109:3e82f62c7e1f 61 HttpAddText(" <meta name='viewport' content='width=device-width, initial-scale=1'>\r\n"
andrewboyson 109:3e82f62c7e1f 62 " <link rel='icon' href='/favicon.ico' type='image/x-icon'/>\r\n"
andrewboyson 109:3e82f62c7e1f 63 "</head>\r\n"
andrewboyson 109:3e82f62c7e1f 64 "<body>\r\n");
andrewboyson 109:3e82f62c7e1f 65
andrewboyson 109:3e82f62c7e1f 66 }
andrewboyson 109:3e82f62c7e1f 67 void WebAddH1(const char* pageName)
andrewboyson 109:3e82f62c7e1f 68 {
andrewboyson 109:3e82f62c7e1f 69 HttpAddText("<h1 id='main-content'>");
andrewboyson 109:3e82f62c7e1f 70 HttpAddText(WEB_SITE_NAME);
andrewboyson 109:3e82f62c7e1f 71 HttpAddText(" - ");
andrewboyson 109:3e82f62c7e1f 72 HttpAddText(pageName);
andrewboyson 109:3e82f62c7e1f 73 HttpAddText("</h1>\r\n");
andrewboyson 109:3e82f62c7e1f 74 }
andrewboyson 109:3e82f62c7e1f 75 void WebAddH2(const char* text)
andrewboyson 109:3e82f62c7e1f 76 {
andrewboyson 109:3e82f62c7e1f 77 HttpAddText("<h2>");
andrewboyson 109:3e82f62c7e1f 78 HttpAddText(text);
andrewboyson 109:3e82f62c7e1f 79 HttpAddText("</h2>\r\n");
andrewboyson 109:3e82f62c7e1f 80 }
andrewboyson 109:3e82f62c7e1f 81 void WebAddEnd()
andrewboyson 109:3e82f62c7e1f 82 {
andrewboyson 109:3e82f62c7e1f 83 HttpAddText("</body>\r\n"
andrewboyson 109:3e82f62c7e1f 84 "</html>\r\n");
andrewboyson 109:3e82f62c7e1f 85 }
andrewboyson 109:3e82f62c7e1f 86
andrewboyson 109:3e82f62c7e1f 87 void WebAddLabelledPrefixSuffix(char* label, char* prefix, char* text, char* suffix)
andrewboyson 109:3e82f62c7e1f 88 {
andrewboyson 109:3e82f62c7e1f 89 HttpAddText("<div class='line'>\r\n");
andrewboyson 109:3e82f62c7e1f 90 HttpAddF (" <div>%s</div>\r\n", label);
andrewboyson 109:3e82f62c7e1f 91 HttpAddF (" <div>%s%s%s</div>\r\n", prefix, text, suffix);
andrewboyson 109:3e82f62c7e1f 92 HttpAddText("</div>\r\n");
andrewboyson 109:3e82f62c7e1f 93 }
andrewboyson 109:3e82f62c7e1f 94 void WebAddLabelledText(char* label, char* text)
andrewboyson 109:3e82f62c7e1f 95 {
andrewboyson 109:3e82f62c7e1f 96 HttpAddText("<div class='line'>\r\n");
andrewboyson 109:3e82f62c7e1f 97 HttpAddF (" <div>%s</div>\r\n", label);
andrewboyson 109:3e82f62c7e1f 98 HttpAddF (" <div>%s</div>\r\n", text);
andrewboyson 109:3e82f62c7e1f 99 HttpAddText("</div>\r\n");
andrewboyson 109:3e82f62c7e1f 100 }
andrewboyson 109:3e82f62c7e1f 101
andrewboyson 109:3e82f62c7e1f 102 void WebAddLabelledMac(char* label, char* mac)
andrewboyson 109:3e82f62c7e1f 103 {
andrewboyson 109:3e82f62c7e1f 104 HttpAddText("<div class='line'>\r\n");
andrewboyson 109:3e82f62c7e1f 105 HttpAddF (" <div>%s</div>\r\n", label);
andrewboyson 109:3e82f62c7e1f 106 HttpAddText(" <div>"); MacHttp(mac); HttpAddText("</div>\r\n");
andrewboyson 109:3e82f62c7e1f 107 HttpAddText("</div>\r\n");
andrewboyson 109:3e82f62c7e1f 108 }
andrewboyson 109:3e82f62c7e1f 109
andrewboyson 109:3e82f62c7e1f 110 void WebAddLabelledIp4(char* label, uint32_t ip)
andrewboyson 109:3e82f62c7e1f 111 {
andrewboyson 109:3e82f62c7e1f 112 HttpAddText("<div class='line'>\r\n");
andrewboyson 109:3e82f62c7e1f 113 HttpAddF (" <div>%s</div>\r\n", label);
andrewboyson 109:3e82f62c7e1f 114 HttpAddText(" <div>"); Ip4AddressHttp(ip); HttpAddText("</div>\r\n");
andrewboyson 109:3e82f62c7e1f 115 HttpAddText("</div>\r\n");
andrewboyson 109:3e82f62c7e1f 116 }
andrewboyson 109:3e82f62c7e1f 117
andrewboyson 109:3e82f62c7e1f 118 void WebAddLabelledIp6(char* label, char* ip)
andrewboyson 109:3e82f62c7e1f 119 {
andrewboyson 109:3e82f62c7e1f 120 HttpAddText("<div class='line'>\r\n");
andrewboyson 109:3e82f62c7e1f 121 HttpAddF (" <div>%s</div>\r\n", label);
andrewboyson 109:3e82f62c7e1f 122 HttpAddText(" <div>"); Ip6AddressHttp(ip); HttpAddText("</div>\r\n");
andrewboyson 109:3e82f62c7e1f 123 HttpAddText("</div>\r\n");
andrewboyson 109:3e82f62c7e1f 124 }
andrewboyson 109:3e82f62c7e1f 125 void WebAddLabelledOnOff(char* label, bool value)
andrewboyson 109:3e82f62c7e1f 126 {
andrewboyson 109:3e82f62c7e1f 127 if (value) WebAddLabelledText(label, "On");
andrewboyson 109:3e82f62c7e1f 128 else WebAddLabelledText(label, "Off");
andrewboyson 109:3e82f62c7e1f 129 }
andrewboyson 109:3e82f62c7e1f 130 void WebAddLabelledInt(char* label, int value)
andrewboyson 109:3e82f62c7e1f 131 {
andrewboyson 109:3e82f62c7e1f 132 char text[30];
andrewboyson 109:3e82f62c7e1f 133 snprintf(text, sizeof(text), "%8d", value); //Right align with enough spaces so that the length is always constant.
andrewboyson 109:3e82f62c7e1f 134 WebAddLabelledText(label, text);
andrewboyson 109:3e82f62c7e1f 135 }
andrewboyson 109:3e82f62c7e1f 136 void WebAddInputText(char* label, float inputwidth, char* value, char* action, char* name)
andrewboyson 109:3e82f62c7e1f 137 {
andrewboyson 109:3e82f62c7e1f 138 HttpAddF ("<form action='%s' method='get'>\r\n", action);
andrewboyson 109:3e82f62c7e1f 139 HttpAddText("<div class='line'>\r\n");
andrewboyson 109:3e82f62c7e1f 140 HttpAddF (" <div>%s</div>\r\n", label);
andrewboyson 109:3e82f62c7e1f 141 HttpAddF (" <input type='text' name='%s' style='width:%.1fem;' value='%s'>\r\n", name, inputwidth, value);
andrewboyson 109:3e82f62c7e1f 142 HttpAddText("</div>\r\n");
andrewboyson 109:3e82f62c7e1f 143 HttpAddText("<input type='submit' value='Set' style='display:none;'>\r\n");
andrewboyson 109:3e82f62c7e1f 144 HttpAddF ("</form>\r\n");
andrewboyson 109:3e82f62c7e1f 145
andrewboyson 109:3e82f62c7e1f 146 }
andrewboyson 109:3e82f62c7e1f 147 void WebAddInputInt(char* label, float inputwidth, int value, char* action, char* name)
andrewboyson 109:3e82f62c7e1f 148 {
andrewboyson 109:3e82f62c7e1f 149 char text[30];
andrewboyson 109:3e82f62c7e1f 150 snprintf(text, sizeof(text), "%d", value);
andrewboyson 109:3e82f62c7e1f 151 WebAddInputText(label, inputwidth, text, action, name);
andrewboyson 109:3e82f62c7e1f 152 }
andrewboyson 109:3e82f62c7e1f 153 void WebAddInputButton(char* label, char* value, char* action, char* name)
andrewboyson 109:3e82f62c7e1f 154 {
andrewboyson 109:3e82f62c7e1f 155 HttpAddF ("<form action='%s' method='get'>\r\n", action);
andrewboyson 109:3e82f62c7e1f 156 HttpAddF ("<input type='hidden' name='%s'>\r\n", name);
andrewboyson 109:3e82f62c7e1f 157 HttpAddText("<div class='line'>\r\n");
andrewboyson 109:3e82f62c7e1f 158 HttpAddF (" <div>%s</div>\r\n", label);
andrewboyson 109:3e82f62c7e1f 159 HttpAddF (" <input type='submit' value='%s'>\r\n", value);
andrewboyson 109:3e82f62c7e1f 160 HttpAddText("</div>\r\n");
andrewboyson 109:3e82f62c7e1f 161 HttpAddText("</form>\r\n");
andrewboyson 109:3e82f62c7e1f 162 }
andrewboyson 109:3e82f62c7e1f 163 void WebAddAjaxInputToggle(char* label, char* id, char* name)
andrewboyson 109:3e82f62c7e1f 164 {
andrewboyson 109:3e82f62c7e1f 165 HttpAddText("<div class='line'>\r\n");
andrewboyson 109:3e82f62c7e1f 166 HttpAddF (" <div>%s</div>\r\n", label);
andrewboyson 109:3e82f62c7e1f 167 HttpAddF (" <div class='toggle' id='%s' tabindex='0' dir='ltr' onclick='AjaxRequest(\"%s=1\")' onkeydown='return event.keyCode != 13 || AjaxRequest(\"%s=1\")'>\r\n", id, name, name);
andrewboyson 109:3e82f62c7e1f 168 HttpAddText(" <div class='slot'></div><div class='knob'></div>\r\n");
andrewboyson 109:3e82f62c7e1f 169 HttpAddText(" </div>\r\n");
andrewboyson 109:3e82f62c7e1f 170 HttpAddText("</div>\r\n");
andrewboyson 109:3e82f62c7e1f 171 }
andrewboyson 109:3e82f62c7e1f 172 void WebAddAjaxLed(char* label, char* id)
andrewboyson 109:3e82f62c7e1f 173 {
andrewboyson 109:3e82f62c7e1f 174 HttpAddText("<div class='line'>\r\n");
andrewboyson 109:3e82f62c7e1f 175 HttpAddF (" <div>%s</div>\r\n", label);
andrewboyson 109:3e82f62c7e1f 176 HttpAddF (" <div class='led' id='%s' dir='ltr'></div>\r\n", id);
andrewboyson 109:3e82f62c7e1f 177 HttpAddText("</div>\r\n");
andrewboyson 109:3e82f62c7e1f 178 }
andrewboyson 109:3e82f62c7e1f 179 void WebAddAjaxInput(char* label, float inputwidth, char* id, char* name)
andrewboyson 109:3e82f62c7e1f 180 {
andrewboyson 109:3e82f62c7e1f 181 HttpAddText("<div class='line'>\r\n");
andrewboyson 109:3e82f62c7e1f 182 HttpAddF (" <div>%s</div>\r\n", label);
andrewboyson 109:3e82f62c7e1f 183 HttpAddF (" <input type='text' style='width:%.1fem;' id='%s' onchange='AjaxRequest(\"%s=\" + this.value)'>\r\n", inputwidth, id, name);
andrewboyson 109:3e82f62c7e1f 184 HttpAddText("</div>\r\n");
andrewboyson 109:3e82f62c7e1f 185 }
andrewboyson 109:3e82f62c7e1f 186 void WebAddAjaxInputSuffix(char* label, float inputwidth, char* id, char* name, char* suffix)
andrewboyson 109:3e82f62c7e1f 187 {
andrewboyson 109:3e82f62c7e1f 188 HttpAddText("<div class='line'>\r\n");
andrewboyson 109:3e82f62c7e1f 189 HttpAddF (" <div>%s</div>\r\n", label);
andrewboyson 109:3e82f62c7e1f 190 HttpAddF (" <input type='text' style='width:%.1fem;' id='%s' onchange='AjaxRequest(\"%s=\" + this.value)'>%s\r\n", inputwidth, id, name, suffix);
andrewboyson 109:3e82f62c7e1f 191 HttpAddText("</div>\r\n");
andrewboyson 109:3e82f62c7e1f 192 }
andrewboyson 109:3e82f62c7e1f 193 void WebAddAjaxLabelled(char* label, char* id)
andrewboyson 109:3e82f62c7e1f 194 {
andrewboyson 109:3e82f62c7e1f 195 HttpAddText("<div class='line'>\r\n");
andrewboyson 109:3e82f62c7e1f 196 HttpAddF (" <div>%s</div>\r\n", label);
andrewboyson 109:3e82f62c7e1f 197 HttpAddF (" <div id='%s'></div>\r\n", id);
andrewboyson 109:3e82f62c7e1f 198 HttpAddText("</div>\r\n");
andrewboyson 109:3e82f62c7e1f 199 }
andrewboyson 109:3e82f62c7e1f 200 void WebAddAjaxLabelledSuffix(char* label, char* id, char* suffix)
andrewboyson 109:3e82f62c7e1f 201 {
andrewboyson 109:3e82f62c7e1f 202 HttpAddText("<div class='line'>\r\n");
andrewboyson 109:3e82f62c7e1f 203 HttpAddF (" <div>%s</div>\r\n", label);
andrewboyson 109:3e82f62c7e1f 204 HttpAddF (" <div><span id='%s'></span>%s</div>\r\n", id, suffix);
andrewboyson 109:3e82f62c7e1f 205 HttpAddText("</div>\r\n");
andrewboyson 109:3e82f62c7e1f 206 }
andrewboyson 109:3e82f62c7e1f 207 void WebAddAjaxInputLabelId(char* labelId, float inputwidth, char* id, char* name)
andrewboyson 109:3e82f62c7e1f 208 {
andrewboyson 109:3e82f62c7e1f 209 HttpAddText("<div class='line'>\r\n");
andrewboyson 109:3e82f62c7e1f 210 HttpAddF (" <div id='%s'></div>\r\n", labelId);
andrewboyson 109:3e82f62c7e1f 211 HttpAddF (" <input type='text' style='width:%.1fem;' id='%s' onchange='AjaxRequest(\"%s=\" + this.value)'>\r\n", inputwidth, id, name);
andrewboyson 109:3e82f62c7e1f 212 HttpAddText("</div>\r\n");
andrewboyson 109:3e82f62c7e1f 213 }
andrewboyson 109:3e82f62c7e1f 214
andrewboyson 109:3e82f62c7e1f 215