ESP3D  3.0
Firmware for ESP boards connected to 3D Printer
authentication_service.cpp
Go to the documentation of this file.
1 /*
2  authentication_service.cpp - ESP3D authentication service class
3 
4  Copyright (c) 2014 Luc Lebosse. All rights reserved.
5 
6  This library is free software; you can redistribute it and/or
7  modify it under the terms of the GNU Lesser General Public
8  License as published by the Free Software Foundation; either
9  version 2.1 of the License, or (at your option) any later version.
10 
11  This library is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  Lesser General Public License for more details.
15 
16  You should have received a copy of the GNU Lesser General Public
17  License along with this library; if not, write to the Free Software
18  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20 
21 #include "authentication_service.h"
22 #include "../../core/esp3doutput.h"
23 #include "../../core/settings_esp3d.h"
24 
25 #if defined (AUTHENTICATION_FEATURE)
26 #if defined (HTTP_FEATURE)
27 #if defined (ARDUINO_ARCH_ESP32)
28 #include <WebServer.h>
29 #endif //ARDUINO_ARCH_ESP32
30 #if defined (ARDUINO_ARCH_ESP8266)
31 #include <ESP8266WebServer.h>
32 #endif //ARDUINO_ARCH_ESP8266
33 Authwebserver * AuthenticationService::_webserver = nullptr;
34 #endif //HTTP_FEATURE
35 #endif //AUTHENTICATION_FEATURE
36 
37 #if defined (AUTHENTICATION_FEATURE)
38 String AuthenticationService::_adminpwd="";
39 String AuthenticationService::_userpwd="";
40 #if defined (HTTP_FEATURE)
41 uint32_t AuthenticationService::_sessionTimeout = 360000;
42 auth_ip * AuthenticationService::_head = nullptr;
43 uint8_t AuthenticationService::_current_nb_ip = 0;
44 #endif //HTTP_FEATURE
45 #endif //AUTHENTICATION_FEATURE
46 
47 #define MAX_AUTH_IP 10
48 //#define ALLOW_MULTIPLE_SESSIONS
49 
51 {
52 }
54 {
55 #if defined (HTTP_FEATURE) && defined (AUTHENTICATION_FEATURE)
56  end();
57 #endif //HTTP_FEATURE && AUTHENTICATION_FEATURE
58 }
59 
60 //check authentification
62 {
63 #ifdef AUTHENTICATION_FEATURE
65  if(pwd != nullptr) {
66 
67  if (isadmin(pwd)) {
68  auth_type = LEVEL_ADMIN;
69  }
70  if (isuser (pwd) && (auth_type != LEVEL_ADMIN)) {
71  auth_type = LEVEL_USER;
72  }
73  } else {
74 #if defined (HTTP_FEATURE)
75  if (_webserver) {
76  if (_webserver->hasHeader ("Authorization") ) {
77  //log_esp3d("Check authorization %",(_webserver->uri()).c_str());
78  if (_webserver->authenticate(DEFAULT_ADMIN_LOGIN, _adminpwd.c_str())) {
79  auth_type = LEVEL_ADMIN;
80  } else {
81  if (_webserver->authenticate(DEFAULT_USER_LOGIN, _userpwd.c_str())) {
82  auth_type = LEVEL_USER;
83  }
84  }
85  }
86  if (_webserver->hasHeader ("Cookie") ) {
87  //log_esp3d("Check Cookie %s",(_webserver->uri()).c_str());
88  String cookie = _webserver->header ("Cookie");
89  int pos = cookie.indexOf ("ESPSESSIONID=");
90  if (pos != -1) {
91  int pos2 = cookie.indexOf (";", pos);
92  String sessionID = cookie.substring (pos + strlen ("ESPSESSIONID="), pos2);
93  IPAddress ip = _webserver->client().remoteIP();
94  //check if cookie can be reset and clean table in same time
95  auth_type = ResetAuthIP (ip, sessionID.c_str() );
96  //log_esp3d("Authentication = %d", auth_type);
97  }
98  }
99  }
100 #endif //HTTP_FEATURE
101  }
102  return auth_type;
103 #else
104  (void)pwd;
105  return LEVEL_ADMIN;
106 #endif //AUTHENTICATION_FEATURE
107 }
108 #ifdef AUTHENTICATION_FEATURE
109 
110 #if defined (HTTP_FEATURE)
111 uint32_t AuthenticationService::setSessionTimeout(uint32_t timeout)
112 {
113  if (timeout >= 0) {
114  _sessionTimeout = timeout;
115  }
116  return _sessionTimeout;
117 }
118 uint32_t AuthenticationService::getSessionTimeout()
119 {
120  return _sessionTimeout;
121 }
122 #endif //HTTP_FEATURE
123 
124 bool AuthenticationService::begin(Authwebserver * webserver)
125 {
126  end();
127  update();
128 #if defined (HTTP_FEATURE)
129  _webserver = webserver;
130 #endif //HTTP_FEATURE
131  return true;
132 }
133 void AuthenticationService::end()
134 {
135 #if defined (HTTP_FEATURE)
136  _webserver = nullptr;
137  ClearAllSessions();
138 #endif //HTTP_FEATURE
139 }
140 
141 void AuthenticationService::update()
142 {
145 }
146 
147 void AuthenticationService::handle()
148 {
149 }
150 
151 //check admin password
152 bool AuthenticationService::isadmin (const char *pwd)
153 {
154  if (strcmp(_adminpwd.c_str(), pwd) !=0 ) {
155  return false;
156  } else {
157  return true;
158  }
159 }
160 
161 //check user password - admin password is also valid
162 bool AuthenticationService::isuser (const char *pwd)
163 {
164  //it is not user password
165  if (strcmp(_userpwd.c_str(), pwd)!=0) {
166  //check admin password
167  return isadmin (pwd);
168  } else {
169  return true;
170  }
171 }
172 
173 #if defined (HTTP_FEATURE)
174 //add the information in the linked list if possible
175 bool AuthenticationService::AddAuthIP (auth_ip * item)
176 {
177  if (_current_nb_ip > MAX_AUTH_IP) {
178  return false;
179  }
180  item->_next = _head;
181  _head = item;
182  _current_nb_ip++;
183  return true;
184 }
185 
186 //Session ID based on IP and time using 16 char
187 char * AuthenticationService::create_session_ID()
188 {
189  static char sessionID[17];
190 //reset SESSIONID
191  for (int i = 0; i < 17; i++) {
192  sessionID[i] = '\0';
193  }
194 //get time
195  uint32_t now = millis();
196 //get remote IP
197  IPAddress remoteIP = _webserver->client().remoteIP();
198 //generate SESSIONID
199  if (0 > sprintf (sessionID, "%02X%02X%02X%02X%02X%02X%02X%02X", remoteIP[0], remoteIP[1], remoteIP[2], remoteIP[3], (uint8_t) ( (now >> 0) & 0xff), (uint8_t) ( (now >> 8) & 0xff), (uint8_t) ( (now >> 16) & 0xff), (uint8_t) ( (now >> 24) & 0xff) ) ) {
200  strcpy (sessionID, "NONE");
201  }
202  return sessionID;
203 }
204 
205 bool AuthenticationService::ClearAllSessions()
206 {
207  while (_head) {
208  auth_ip * current = _head;
209  _head = _head->_next;
210  delete current;
211  }
212  _current_nb_ip = 0;
213  _head = nullptr;
214 
215  return true;
216 }
217 
218 bool AuthenticationService::ClearCurrentSession()
219 {
220  String cookie = _webserver->header("Cookie");
221  int pos = cookie.indexOf("ESPSESSIONID=");
222  String sessionID;
223  if (pos!= -1) {
224  int pos2 = cookie.indexOf(";",pos);
225  sessionID = cookie.substring(pos+strlen("ESPSESSIONID="),pos2);
226  }
227  return ClearAuthIP(_webserver->client().remoteIP(), sessionID.c_str());
228 }
229 
230 bool AuthenticationService::CreateSession(level_authenticate_type auth_level, const char * username, const char* session_ID)
231 {
232  auth_ip * current_auth = new auth_ip;
233  current_auth->level = auth_level;
234  current_auth->ip=_webserver->client().remoteIP();
235  strcpy(current_auth->sessionID, session_ID);
236  strcpy(current_auth->userID,username);
237  current_auth->last_time=millis();
238 #ifndef ALLOW_MULTIPLE_SESSIONS
239  //if not multiple session no need to keep all session, current one is enough
240  ClearAllSessions();
241 #endif //ALLOW_MULTIPLE_SESSIONS
242  if (AddAuthIP(current_auth)) {
243  return true;
244  } else {
245  delete current_auth;
246  return false;
247  }
248 }
249 
250 bool AuthenticationService::ClearAuthIP (IPAddress ip, const char * sessionID)
251 {
252  auth_ip * current = _head;
253  auth_ip * previous = NULL;
254  bool done = false;
255  while (current) {
256  if ( (ip == current->ip) && (strcmp (sessionID, current->sessionID) == 0) ) {
257  //remove
258  done = true;
259  if (current == _head) {
260  _head = current->_next;
261  _current_nb_ip--;
262  delete current;
263  current = _head;
264  } else {
265  previous->_next = current->_next;
266  _current_nb_ip--;
267  delete current;
268  current = previous->_next;
269  }
270  } else {
271  previous = current;
272  current = current->_next;
273  }
274  }
275  return done;
276 }
277 
278 //Get info
279 auth_ip * AuthenticationService::GetAuth (IPAddress ip, const char * sessionID)
280 {
281  auth_ip * current = _head;
282  //auth_ip * previous = NULL;
283  //get time
284  //uint32_t now = millis();
285  while (current) {
286  if (ip == current->ip) {
287  if (strcmp (sessionID, current->sessionID) == 0) {
288  //found
289  return current;
290  }
291  }
292  //previous = current;
293  current = current->_next;
294  }
295  return NULL;
296 }
297 
298 //Review all IP to reset timers
299 level_authenticate_type AuthenticationService::ResetAuthIP (IPAddress ip, const char * sessionID)
300 {
301  auth_ip * current = _head;
302  auth_ip * previous = NULL;
303  //get time
304  //uint32_t now = millis();
305  while (current) {
306  //if time out is reached and time out is not disabled
307  //if IP is not current one and time out is disabled
308  if ( (((millis() - current->last_time) > _sessionTimeout) && (_sessionTimeout!=0)) || ((ip != current->ip) && (_sessionTimeout==0)) ) {
309  //remove
310  if (current == _head) {
311  _head = current->_next;
312  _current_nb_ip--;
313  delete current;
314  current = _head;
315  } else {
316  previous->_next = current->_next;
317  _current_nb_ip--;
318  delete current;
319  current = previous->_next;
320  }
321  } else {
322  if (ip == current->ip) {
323  if (strcmp (sessionID, current->sessionID) == 0) {
324  //reset time
325  current->last_time = millis();
326  return (level_authenticate_type) current->level;
327  }
328  }
329  previous = current;
330  current = current->_next;
331  }
332  }
333  return LEVEL_GUEST;
334 }
335 #endif //HTTP_FEATURE
336 
337 
338 #endif //AUTHENTICATION_FEATURE
Settings_ESP3D::read_string
static const char * read_string(int pos, bool *haserror=NULL)
Definition: settings_esp3d.cpp:794
ESP_USER_PWD
#define ESP_USER_PWD
Definition: settings_esp3d.h:59
AuthenticationService::AuthenticationService
AuthenticationService()
Definition: authentication_service.cpp:50
AuthenticationService::~AuthenticationService
~AuthenticationService()
Definition: authentication_service.cpp:53
AuthenticationService::authenticated_level
static level_authenticate_type authenticated_level(const char *pwd=nullptr)
Definition: authentication_service.cpp:61
DEFAULT_USER_LOGIN
const char DEFAULT_USER_LOGIN[]
Definition: authentication_service.h:32
LEVEL_GUEST
@ LEVEL_GUEST
Definition: authentication_service.h:26
level_authenticate_type
level_authenticate_type
Definition: authentication_service.h:25
MAX_AUTH_IP
#define MAX_AUTH_IP
Definition: authentication_service.cpp:47
DEFAULT_ADMIN_LOGIN
const char DEFAULT_ADMIN_LOGIN[]
Definition: authentication_service.h:31
authentication_service.h
LEVEL_ADMIN
@ LEVEL_ADMIN
Definition: authentication_service.h:28
ESP_ADMIN_PWD
#define ESP_ADMIN_PWD
Definition: settings_esp3d.h:58
LEVEL_USER
@ LEVEL_USER
Definition: authentication_service.h:27