source: S-port/trunk/Core/Src/cmd_login.c

Last change on this file was 1, checked in by AlexLir, 3 years ago
File size: 9.6 KB
Line 
1/****************************************************************************************
2*
3* cmd_login.c
4*
5* Àóòåíòèôèêàöèÿ è óïðàâëåíèå ïîëüçîâàòåëÿìè
6****************************************************************************************/
7
8#include "commands.h"
9#include "main.h"
10#include "Time.h"
11#include "MD5.h"
12#include "cookie.h"
13#include <string.h>
14#include <stdio.h>
15#include "rng.h"
16#include "log_and_debug.h"
17#include "fatfs.h"
18#include "xml.h"
19
20#define AMOUNT_MAX_USER 1 // ïîëüçîâàòåëåé ïîêà ÷òî îäèí
21
22extern RealTimeClock_typeDef RealTimeClock;
23extern char *cookie_out;
24extern xSemaphoreHandle MutexAccessFlash;
25
26struct { // ñòðóêòóðà ïîëüçîâàòåëåé
27 char user[17]; // 16 - ñèìâîëîâ ñòðîêà + íóëü òåðìèíàòîð
28 uint8_t len_user;
29 char passHash[33]; // õåø ïàðîëÿ 32 áàéòà ñèìâîëîâ + íóëü òåðìèíàòîð
30 //uint8_t len_password;
31 uint32_t permissions; // ïðàâà ïîëüçîâàòåëÿ
32}userTable[AMOUNT_MAX_USER] = {0};
33
34_Bool change_pass_to_file(uint8_t indx, char *user, char* new_pass)
35{
36 char str_indx[3] = {0};
37 char *p = NULL, BufferRead[128] = {0};
38 FIL FileLogin_old, FileLogin_new;
39
40 xSemaphoreTake(MutexAccessFlash, portMAX_DELAY);
41 if(f_open(&FileLogin_new, "Tlogin.xml", FA_OPEN_ALWAYS | FA_WRITE) == FR_OK){ // íîâûé âðåìåííûé ôàéë
42 if(f_open(&FileLogin_old, "login.xml", FA_READ) == FR_OK){ // îòêðûâàåì ñóùåñòâóþùèé ôàéë
43 for(;;){
44 if(f_gets(BufferRead, 128, &FileLogin_old) != NULL) { // ïîëó÷àåì ñòðîêó äàííûõ
45 if((p = strchr(BufferRead, '<')) != NULL){ //ïåðåøëè â íà÷àëî òåãà
46 if((p = strstr(p, "user")) != NULL){
47 if((p = strstr(p, "id")) != NULL){
48 if((p = strchr(p, '"')) != NULL){
49 _substr(p, 1, '"', str_indx);
50 if(indx == atoi(str_indx)){
51 f_printf(&FileLogin_new, "\t<user id=\"%d\" name=\"%s\" pass=\"%s\" permissions=\"2147483647\"/>\n", indx, user, new_pass);/*âìåñòî íåå âñòàâèòü íîâóþ*/
52 continue;
53 }
54 }
55 }
56 }
57 f_printf(&FileLogin_new, BufferRead);
58 }
59 }
60 else if(f_eof(&FileLogin_old) != 0){
61 f_close(&FileLogin_old);
62 f_close(&FileLogin_new);
63 f_unlink("login.xml");
64 f_rename("Tlogin.xml", "login.xml");
65 xSemaphoreGive(MutexAccessFlash);
66 return 1;
67 }
68 }
69 }
70 }
71 xSemaphoreGive(MutexAccessFlash);
72 return 0;
73}
74
75void hashtostr(char *str, uint8_t lenstr, char *hash_out)
76{
77 uint8_t hash[16] = {0};
78 md5((uint8_t*)str, lenstr, hash);
79
80 char *out = hash_out;
81 for(int i = 0; i < 16; i++) {
82 out += sprintf(out, "%02x", hash[i]);
83 }
84 hash_out[32] = 0;
85}
86
87void setAuth(char *user, char *pass, char *cookie)
88{
89 char hash_md5[33] = {0};
90 char nonce[11] = {0}, time[11] = {0};
91 uint8_t cnt = 0;
92
93 sprintf(&nonce[0], "%010x", RNG_get());
94 sprintf(&time[0], "%u", time_to_unix(&RealTimeClock));
95
96 char str[70] = {0};
97 cnt += sprintf(&str[cnt], "%s", user); //16 ñèìâîëîâ
98 cnt += sprintf(&str[cnt], "%s", pass); // hash 32 ñèìâîëà
99 cnt += sprintf(&str[cnt], "%s", time); // unixtime 10 ñèìâîëîâ
100 cnt += sprintf(&str[cnt], "%s", nonce); // id ñåññèè 10 ñèìâîëîâ
101
102 hashtostr(str, cnt, hash_md5);
103
104 cookie_write_open(cookie, 512);
105 cookie_set("login", user);
106 cookie_set("time", time);
107 cookie_set("nonce", nonce);
108 cookie_set("password", hash_md5);
109 cookie_close();
110}
111
112void clearAuth(char *cookie) // 30 us
113{
114 cookie_write_open(cookie, 512);
115 cookie_set("login", "");
116 cookie_set("time", "");
117 cookie_set("nonce", "");
118 cookie_set("password", "");
119 cookie_close();
120}
121
122uint8_t checkLogin(cookie_token_data_typDef *cookieIn, char *cookieOut)
123{
124 char hash_md5[33] = {0};
125 char user[17] = {0}, nonce[11] = {0}, time[11] = {0}, pass[33] = {0};
126 uint8_t cnt = 0, index = 0;
127 uint32_t cookie_time, unix_time;
128
129 if(cookieIn != NULL){
130 cookie_get_option(cookieIn, "login", user);
131 cookie_get_option(cookieIn, "nonce", nonce);
132 cookie_get_option(cookieIn, "time", time);
133 cookie_get_option(cookieIn, "password", pass);
134
135 for(uint8_t i = 0; i < AMOUNT_MAX_USER; i++){
136 if((memcmp(userTable[i].user, user, userTable[i].len_user) && (userTable[i].len_user > 0)) == 0) {
137 index = i;
138 break;
139 }
140 }
141
142 cookie_time = atoi(time);
143 unix_time = time_to_unix(&RealTimeClock);
144 if((unix_time < cookie_time) || (unix_time - cookie_time > 86400)) return 0;
145
146 char str[70] = {0};
147 cnt += sprintf(&str[cnt], "%s", user);
148 cnt += sprintf(&str[cnt], "%s", userTable[index].passHash);
149 cnt += sprintf(&str[cnt], "%s", time);
150 cnt += sprintf(&str[cnt], "%s", nonce);
151
152 hashtostr(str, cnt, hash_md5);
153
154 if(memcmp(pass, hash_md5, 32) == 0){
155 setAuth(user, userTable[index].passHash, cookieOut); //óñòàíàâëèâàåì íîâóþ àóòåíòèôèêàöèþ
156 return 1;
157 }
158 }
159 return 0;
160}
161
162void cmd_changePass(json_tokens_data_t *tokens_data, json_response_t *json_response)
163{
164 char login[17] = {0}, hash_md5_curr[33] = {0}, hash_md5_new[33] = {0};
165 volatile _Bool flagFound = 0;
166 uint8_t ptr_user = 0;
167
168 if(json_get_value_object(tokens_data, "user", login, json_type_string , json_root) == json_success){ // ïðîâåðèòü åñòü ëè òàêîé ïîëüçîâàòåëü
169 for(uint8_t i = 0; i < AMOUNT_MAX_USER; i++){
170 if(userTable[i].len_user > 0){
171 if(memcmp(userTable[i].user, login, userTable[i].len_user) == 0) { /* åñòü ïîëüçîâàòåëü â òàáëèöå */
172 flagFound = 1;
173 ptr_user = i;
174 break;
175 }
176 }
177 else {
178 json_write_obj_string("status", "error");
179 json_write_obj_string("error", "invalid parametr");
180 }
181 }
182 /* íåò çàïðàøèâàåìîãî ïîëüçîâàòåëÿ */
183 if(!flagFound){
184 json_write_obj_string("status", "error");
185 json_write_obj_string("error", "password change error");
186 return;
187 }
188 /* íåò ïîëÿ new */
189 if(json_get_value_object(tokens_data, "new", hash_md5_new, json_type_string , json_root) != json_success){
190 json_write_obj_string("status", "error");
191 json_write_obj_string("error", "invalid parametr");
192 return;
193 }
194 /* íåò ïîëÿ current */
195 if(json_get_value_object(tokens_data, "current", hash_md5_curr, json_type_string, json_root) != json_success){
196 json_write_obj_string("status", "error");
197 json_write_obj_string("error", "invalid parametr");
198 return;
199 }
200 /* åñëè õåøè íå ñîâïàëè */
201 if(memcmp(userTable[ptr_user].passHash, hash_md5_curr, sizeof(userTable[ptr_user].passHash)) != 0) {
202 json_write_obj_string("status", "error");
203 json_write_obj_string("error", "password change error");
204 return;
205 }
206 /* ïàðîëè ñîâïàëè ïèøåì íîâûé â òàáëèöó */
207 memcpy(userTable[ptr_user].passHash, hash_md5_new, sizeof(userTable[ptr_user].passHash));
208 /*òóò íîâûé ïàðîëü çàïèñûâàåì â ôàéë login.xml*/
209 if(change_pass_to_file(ptr_user, userTable[ptr_user].user, userTable[ptr_user].passHash)) json_write_obj_string("status", "ok");
210 else {
211 json_write_obj_string("status", "error");
212 json_write_obj_string("error", "password change error");
213 }
214 }
215}
216
217extern _Bool ClearPassword;
218
219void cmd_login(json_tokens_data_t *tokens_data, json_response_t *json_response)
220{
221 FIL FileLogin;
222 xml_status_typeDef xmlStatus;
223 char login[17] = {0}, xml_data[33] = {0}, password[33] = {0}, attr[8] = {0};
224
225 if(json_get_value_object(tokens_data, "user", login, json_type_string, json_root) == json_success){ // çàáèðàåì ïîëå user
226 if(strlen(login) > 0){
227 xmlStatus = xml_get_attr("login.xml", "user", attr, "name", xml_data);
228 if(xmlStatus == XML_ERR_NO_FILE){ // íåò ôàéëà
229 xSemaphoreTake(MutexAccessFlash, portMAX_DELAY);
230 if(f_open(&FileLogin, "login.xml", FA_OPEN_ALWAYS | FA_WRITE) == FR_OK){//ôàéëà íåò è çíà÷èò ïëàòó âîîáùå ïåðâûé ðàç âêëþ÷èëè è ïåðâûé ðàç çàïðîñèëè àâòîðèçàöèþ
231 f_printf(&FileLogin, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
232 f_printf(&FileLogin, "<users>\n");
233 f_printf(&FileLogin, "\t<user id=\"0\" name=\"admin\" pass=\"\" permissions=\"2147483647\"/>\n"); //ñîçäàåì ïîëüçîâàòåëÿ admin ñ ïóñòûì ïàðîëåì
234 f_printf(&FileLogin, "</users>\n");
235 f_close(&FileLogin);
236 }
237 else{}// îøèáêà ñîçäàíèÿ ôàéëà, ÷òî äåëàòü â ýòîì ñëó÷àå!
238 xSemaphoreGive(MutexAccessFlash);
239 }
240 for(uint8_t i = 0; i < AMOUNT_MAX_USER; i++){
241 sprintf(attr, "id=\"%d\"", i);
242 if((xmlStatus != XML_OK) && (xml_get_attr("login.xml", "user", attr, "name", xml_data) == XML_OK)){
243 userTable[i].len_user = strlen(xml_data);
244 if(userTable[i].len_user > 0){
245 memcpy(userTable[i].user, xml_data, strlen(xml_data));
246 if(memcmp(userTable[i].user, login, userTable[i].len_user) == 0){
247 if(json_get_value_object(tokens_data, "password", password, json_type_string , json_root) == json_success){
248 if(xml_get_attr("login.xml", "user", attr, "pass", xml_data) == XML_OK){
249 uint8_t lenHash = strlen(xml_data);
250 if((ClearPassword) || (lenHash == 0)) memset(userTable[i].passHash, 0x00, sizeof(userTable[i].passHash)); // ClearPassword ïðèìåíÿòü òîëüêî ó admin
251 else if(lenHash > 0) memcpy(userTable[i].passHash, xml_data, sizeof(userTable[i].passHash));
252 if(memcmp(userTable[i].passHash, password, sizeof(userTable[i].passHash)) == 0){
253 setAuth(login, password, cookie_out);
254 json_write_obj_string("status", "ok");
255 __logWrite("Autentification successfully for \"%s\". Remoute ip:%s;\n", login, ip4addr_ntoa(tokens_data->remote_addr));
256 return;
257 }
258 else __logWrite("Autentification error: incorrect password for \"%s\". Remoute ip:%s;\n", login, ip4addr_ntoa(tokens_data->remote_addr));
259 }
260 }
261 }
262 }
263 }
264 }
265 }
266 }
267 json_write_obj_string("status", "error");// îøèáêà ëîãèíà è ïàðîëÿ
268 json_write_obj_string("error", "incorrect login attempt");
269}
Note: See TracBrowser for help on using the repository browser.