00001 #include "otsdaq-core/WebUsersUtilities/WebUsers.h"
00002 #include "otsdaq-core/MessageFacility/MessageFacility.h"
00003 #include "otsdaq-core/Macros/CoutHeaderMacros.h"
00004 #include "otsdaq-core/XmlUtilities/HttpXmlDocument.h"
00005
00006 #include <sys/types.h>
00007 #include <sys/stat.h>
00008 #include <iostream>
00009 #include <openssl/sha.h>
00010 #include <cstdlib>
00011 #include <cstdio>
00012 #include <cassert>
00013
00014 #include <thread>
00015 #include <chrono>
00016
00017 using namespace ots;
00018
00019
00020
00021 #define WEB_LOGIN_BKUP_DB_PATH "bkup/"
00022
00023 #define SECURITY_FILE_NAME std::string(getenv("SERVICE_DATA_PATH")) + "/OtsWizardData/security.dat"
00024
00025
00026 #define HASHES_DB_FILE HASHES_DB_PATH + "/hashes.xml"
00027 #define USERS_DB_FILE USERS_DB_PATH + "/users.xml"
00028 #define USERS_GLOBAL_HISTORY_FILE "__global"
00029 #define USERS_LOGIN_HISTORY_FILETYPE "hist"
00030 #define USERS_PREFERENCES_FILETYPE "pref"
00031 #define SYSTEM_PREFERENCES_PREFIX "system.preset"
00032 #define USER_WITH_LOCK_FILE WEB_LOGIN_DB_PATH + "/user_with_lock.dat"
00033
00034 #define HASHES_DB_GLOBAL_STRING "hashData"
00035 #define HASHES_DB_ENTRY_STRING "hashEntry"
00036 #define USERS_DB_GLOBAL_STRING "userData"
00037 #define USERS_DB_ENTRY_STRING "userEntry"
00038 #define USERS_DB_NEXT_UID_STRING "nextUserId"
00039
00040
00041 #define PREF_XML_BGCOLOR_FIELD "pref_bgcolor" // -background color
00042 #define PREF_XML_DBCOLOR_FIELD "pref_dbcolor" // -dashboard color
00043 #define PREF_XML_WINCOLOR_FIELD "pref_wincolor" // -window color
00044 #define PREF_XML_LAYOUT_FIELD "pref_layout" // -3 defaults window layouts(and current)
00045 #define PREF_XML_SYSLAYOUT_FIELD "pref_syslayout" // -2 defaults window layouts
00046 #define PREF_XML_PERMISSIONS_FIELD "desktop_user_permissions" // 0-255 permissions valud (255 is admin super user)
00047 #define PREF_XML_USERLOCK_FIELD "username_with_lock" // user with lock (to lockout others)
00048 #define PREF_XML_USERNAME_FIELD "pref_username" // user with lock (to lockout others)
00049
00050 #define PREF_XML_BGCOLOR_DEFAULT "rgb(15,34,105)" // -background color
00051 #define PREF_XML_DBCOLOR_DEFAULT "rgb(60,64,75)" // -dashboard color
00052 #define PREF_XML_WINCOLOR_DEFAULT "rgba(196,229,255,0.9)" // -window color
00053 #define PREF_XML_LAYOUT_DEFAULT "0;0;0;0" // 3 default window layouts(and current)
00054 #define PREF_XML_SYSLAYOUT_DEFAULT "0;0" // 2 system default window layouts
00055
00056 #define PREF_XML_ACCOUNTS_FIELD "users_accounts" // user accounts field for super users
00057 #define PREF_XML_LOGIN_HISTORY_FIELD "login_entry" // login history field for user login history data
00058
00059 const std::string WebUsers::DEFAULT_ADMIN_USERNAME = "admin";
00060 const std::string WebUsers::DEFAULT_ADMIN_DISPLAY_NAME = "Administrator";
00061
00062 #undef __MF_SUBJECT__
00063 #define __MF_SUBJECT__ "WebUsers"
00064
00065
00066 WebUsers::WebUsers()
00067 {
00068
00069
00070 usersNextUserId_ = 0;
00071 usersUsernameWithLock_ = "";
00072
00073
00074 HashesDatabaseEntryFields.push_back("hash");
00075 HashesDatabaseEntryFields.push_back("lastAccessTime");
00076
00077 UsersDatabaseEntryFields.push_back("username");
00078 UsersDatabaseEntryFields.push_back("displayName");
00079 UsersDatabaseEntryFields.push_back("salt");
00080 UsersDatabaseEntryFields.push_back("uid");
00081 UsersDatabaseEntryFields.push_back("permissions");
00082 UsersDatabaseEntryFields.push_back("lastLoginAttemptTime");
00083 UsersDatabaseEntryFields.push_back("accountCreatedTime");
00084 UsersDatabaseEntryFields.push_back("loginFailureCount");
00085 UsersDatabaseEntryFields.push_back("lastModifiedTime");
00086 UsersDatabaseEntryFields.push_back("lastModifierUsername");
00087
00088
00089 mkdir(((std::string)WEB_LOGIN_DB_PATH).c_str(), 0755);
00090 mkdir(((std::string)WEB_LOGIN_DB_PATH + HASHES_DB_PATH).c_str(), 0755);
00091 mkdir(((std::string)WEB_LOGIN_DB_PATH + USERS_DB_PATH).c_str(), 0755);
00092 mkdir(((std::string)WEB_LOGIN_DB_PATH + USERS_LOGIN_HISTORY_PATH).c_str(), 0755);
00093 mkdir(((std::string)WEB_LOGIN_DB_PATH + USERS_PREFERENCES_PATH).c_str(), 0755);
00094
00095
00096 if(!loadDatabases())
00097 __MOUT__ << "FATAL USER DATABASE ERROR - failed to load!!!" << std::endl;
00098
00099 loadSecuritySelection();
00100
00101
00102
00103 uint64_t i;
00104 std::string user = DEFAULT_ADMIN_USERNAME;
00105 if((i = searchUsersDatabaseForUsername(user)) == NOT_FOUND_IN_DATABASE)
00106 {
00107 __MOUT__ << "user: " << user << " is not found" << std::endl;
00108 assert(0);
00109 exit(0);
00110 }
00111 else if(UsersSaltVector[i] == "" &&
00112 securityType_ == SECURITY_TYPE_DIGEST_ACCESS)
00113 {
00114 char charTimeStr[10];
00115 sprintf(charTimeStr,"%d",int(UsersAccountCreatedTimeVector[i] & 0xffff));
00116 std::string tmpTimeStr = charTimeStr;
00117
00119
00120
00121 std::thread([](std::string nac, std::string user){ WebUsers::NACDisplayThread(nac,user); },
00122 tmpTimeStr,user).detach();
00123
00124 }
00125
00126
00127 loadUserWithLock();
00128
00129 srand (time(0));
00130
00131 __MOUT__ << "Done with Web Users initialization!" << std::endl;
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314 }
00315
00316
00317
00318
00319
00320
00321 bool WebUsers::loadDatabases()
00322 {
00323 std::string fn;
00324 FILE *fp;
00325 unsigned int LINE_LEN = 1000;
00326 char line[LINE_LEN];
00327 unsigned int i,si,c,len,f;
00328 uint64_t tmpInt64;
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338 fn = (std::string)WEB_LOGIN_DB_PATH + (std::string)HASHES_DB_FILE;
00339 __MOUT__ << fn << std::endl;
00340 fp = fopen(fn.c_str(),"r");
00341 if(!fp)
00342 {
00343 mkdir(((std::string)WEB_LOGIN_DB_PATH + (std::string)HASHES_DB_PATH).c_str(), 0755);
00344 __MOUT__ << ((std::string)WEB_LOGIN_DB_PATH + (std::string)HASHES_DB_PATH).c_str() << std::endl;
00345 fp = fopen(fn.c_str(),"w");
00346 if(!fp) return false;
00347 __MOUT__ << "Hashes database created: " << fn << std::endl;
00348
00349 saveToDatabase(fp,HASHES_DB_GLOBAL_STRING,"",DB_SAVE_OPEN);
00350 saveToDatabase(fp,HASHES_DB_GLOBAL_STRING,"",DB_SAVE_CLOSE);
00351 fclose(fp);
00352 }
00353 else
00354 {
00355
00356
00357 while(fgets(line,LINE_LEN,fp))
00358 {
00359 if(strlen(line) < SHA512_DIGEST_LENGTH) continue;
00360
00361 c=0;
00362 len = strlen(line);
00363 for(i=0;i<len;++i)
00364 if(line[i] == '>')
00365 {
00366 ++c;
00367 if(c != 2 && c != 4) continue;
00368
00369 si = ++i;
00370 while(i<len && line[i] != '<') ++i;
00371 if(i == len)
00372 break;
00373 line[i] = '\0';
00374
00375
00376
00377 f = c/2-1;
00378 if(f == 0)
00379 HashesVector.push_back(&line[si]);
00380 else if(f == 1)
00381 {
00382 sscanf(&line[si],"%lu",&tmpInt64);
00383 HashesAccessTimeVector.push_back(tmpInt64);
00384 }
00385 }
00386 }
00387 __MOUT__ << HashesAccessTimeVector.size() << " Hashes found." << std::endl;
00388
00389 fclose(fp);
00390 }
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401 fn = (std::string)WEB_LOGIN_DB_PATH + (std::string)USERS_DB_FILE;
00402 fp = fopen(fn.c_str(),"r");
00403 if(!fp)
00404 {
00405 mkdir(((std::string)WEB_LOGIN_DB_PATH + (std::string)USERS_DB_PATH).c_str(), 0755);
00406 __MOUT__ << ((std::string)WEB_LOGIN_DB_PATH + (std::string)USERS_DB_PATH).c_str() << std::endl;
00407 fp = fopen(fn.c_str(),"w");
00408 if(!fp) return false;
00409 __MOUT__ << "Users database created: " << fn << std::endl;
00410
00411 saveToDatabase(fp,USERS_DB_GLOBAL_STRING,"",DB_SAVE_OPEN);
00412 char nidStr[100];
00413 sprintf(nidStr,"%lu",usersNextUserId_);
00414 saveToDatabase(fp,USERS_DB_NEXT_UID_STRING,nidStr,DB_SAVE_OPEN_AND_CLOSE);
00415 saveToDatabase(fp,USERS_DB_GLOBAL_STRING,"",DB_SAVE_CLOSE);
00416 fclose(fp);
00417
00418 createNewAccount(DEFAULT_ADMIN_USERNAME,DEFAULT_ADMIN_DISPLAY_NAME);
00419 }
00420 else
00421 {
00422
00423
00424
00425 char salt[] = "nextUserId";
00426 while(fgets(line,LINE_LEN,fp))
00427 {
00428 if(strlen(line) < strlen(salt)*2) continue;
00429
00430 for(i=0;i<strlen(salt);++i)
00431 if(line[i+1] != salt[i]) break;
00432
00433 if(i == strlen(salt))
00434 {
00435 i += 2;
00436 si = i;
00437 while(i < LINE_LEN && line[i] != '\0' && line[i] != '<') ++i;
00438 line[i] = '\0';
00439 sscanf(&line[si],"%lu",&usersNextUserId_);
00440 break;
00441 }
00442 }
00443
00444 __MOUT__ << "Found Users database next user Id: " << usersNextUserId_ << std::endl;
00445
00446
00447 while(fgets(line,LINE_LEN,fp))
00448 {
00449 if(strlen(line) < 30) continue;
00450
00451 c=0;
00452 len = strlen(line);
00453 if(len >= LINE_LEN)
00454 {
00455 __MOUT__ << "Line buffer too small: " << len << std::endl;
00456 break;
00457 }
00458
00459
00460 f = 0;
00461 for(i=0;i<len;++i)
00462 if(line[i] == '>')
00463 {
00464 ++c;
00465 if(c == 0 || c%2 == 1) continue;
00466
00467 si = ++i;
00468 while(i<len && line[i] != '<') ++i;
00469 if(i == len)
00470 break;
00471 line[i] = '\0';
00472 f = c/2-1;
00473
00474
00475
00476 if(f == 0)
00477 UsersUsernameVector.push_back(&line[si]);
00478 else if(f == 1)
00479 UsersDisplayNameVector.push_back(&line[si]);
00480 else if(f == 2)
00481 UsersSaltVector.push_back(&line[si]);
00482 else if(f == 3)
00483 {
00484 sscanf(&line[si],"%lu",&tmpInt64);
00485 UsersUserIdVector.push_back(tmpInt64);
00486 }
00487 else if(f == 4)
00488 {
00489 sscanf(&line[si],"%lu",&tmpInt64);
00490 UsersPermissionsVector.push_back(tmpInt64);
00491 }
00492 else if(f == 5)
00493 {
00494 sscanf(&line[si],"%lu",&tmpInt64);
00495 UsersLastLoginAttemptVector.push_back(tmpInt64);
00496 }
00497 else if(f == 6)
00498 {
00499 sscanf(&line[si],"%lu",&tmpInt64);
00500 UsersAccountCreatedTimeVector.push_back(tmpInt64);
00501 }
00502 else if(f == 7)
00503 {
00504 sscanf(&line[si],"%lu",&tmpInt64);
00505 UsersLoginFailureCountVector.push_back(tmpInt64);
00506 }
00507 else if(f == 8)
00508 {
00509 sscanf(&line[si],"%lu",&tmpInt64);
00510 UsersLastModifiedTimeVector.push_back(tmpInt64);
00511 }
00512 else if(f == 9)
00513 UsersLastModifierUsernameVector.push_back(&line[si]);
00514 }
00515
00516
00517
00518 if(f && f != UsersDatabaseEntryFields.size()-1)
00519 {
00520 if(f != 7)
00521 {
00522 __MOUT__ << "FATAL ERROR - invalid database found with field number " << f << std::endl;
00523 fclose(fp);
00524 return false;
00525 }
00526
00527
00528 __MOUT__ << "Update database to current version - adding fields: " <<
00529 (UsersDatabaseEntryFields.size()-1-f) << std::endl;
00530
00531 UsersLastModifiedTimeVector.push_back(0);
00532 UsersLastModifierUsernameVector.push_back("");
00533 }
00534 }
00535 fclose(fp);
00536 }
00537
00538 __MOUT__ << UsersLastModifiedTimeVector.size() << " Users found." << std::endl;
00539 return true;
00540 }
00541
00542
00543
00544 void WebUsers::saveToDatabase (FILE * fp,std::string field, std::string value, uint8_t type, bool addNewLine)
00545 {
00546 if(!fp) return;
00547
00548 std::string newLine = addNewLine?"\n":"";
00549
00550 if(type == DB_SAVE_OPEN_AND_CLOSE)
00551 fprintf(fp,"<%s>%s</%s>%s",field.c_str(),value.c_str(),field.c_str(),newLine.c_str());
00552 else if(type == DB_SAVE_OPEN)
00553 fprintf(fp,"<%s>%s%s",field.c_str(),value.c_str(),newLine.c_str());
00554 else if(type == DB_SAVE_CLOSE)
00555 fprintf(fp,"</%s>%s",field.c_str(),newLine.c_str());
00556 }
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566 bool WebUsers::saveDatabaseToFile (uint8_t db)
00567 {
00568 __MOUT__ << "Save Database: " << (int)db << std::endl;
00569
00570 std::string fn = (std::string)WEB_LOGIN_DB_PATH +
00571 ((db==DB_USERS)?(std::string)USERS_DB_FILE:(std::string)HASHES_DB_FILE);
00572
00573 __MOUT__ << "Save Database Filename: " << fn << std::endl;
00574
00575
00576 {
00577 char dayAppend[20];
00578 sprintf(dayAppend,".%lu.bkup",time(0)/(3600*24));
00579 std::string bkup_fn = (std::string)WEB_LOGIN_DB_PATH +
00580 (std::string)WEB_LOGIN_BKUP_DB_PATH +
00581 ((db==DB_USERS)?(std::string)USERS_DB_FILE:(std::string)HASHES_DB_FILE) +
00582 (std::string)dayAppend;
00583
00584 __MOUT__ << "Backup file: " << bkup_fn << std::endl;
00585
00586 std::string shell_command = "mv " + fn + " " + bkup_fn;
00587 system(shell_command.c_str());
00588 }
00589
00590 FILE *fp = fopen(fn.c_str(),"wb");
00591 if(!fp) return false;
00592
00593 char fldStr[100];
00594
00595 if(db==DB_USERS)
00596 {
00597 saveToDatabase(fp,USERS_DB_GLOBAL_STRING,"",DB_SAVE_OPEN);
00598
00599 sprintf(fldStr,"%lu",usersNextUserId_);
00600 saveToDatabase(fp,USERS_DB_NEXT_UID_STRING,fldStr,DB_SAVE_OPEN_AND_CLOSE);
00601
00602 __MOUT__ << "Saving " << UsersUsernameVector.size() << " Users." << std::endl;
00603
00604 for(uint64_t i=0;i<UsersUsernameVector.size();++i)
00605 {
00606
00607
00608 saveToDatabase(fp,USERS_DB_ENTRY_STRING,"",DB_SAVE_OPEN,false);
00609
00610 for(unsigned int f=0;f<UsersDatabaseEntryFields.size();++f)
00611 {
00612
00613 if(f == 0)
00614 saveToDatabase(fp,UsersDatabaseEntryFields[f],UsersUsernameVector[i],DB_SAVE_OPEN_AND_CLOSE,false);
00615 else if(f == 1)
00616 saveToDatabase(fp,UsersDatabaseEntryFields[f],UsersDisplayNameVector[i],DB_SAVE_OPEN_AND_CLOSE,false);
00617 else if(f == 2)
00618 saveToDatabase(fp,UsersDatabaseEntryFields[f],UsersSaltVector[i],DB_SAVE_OPEN_AND_CLOSE,false);
00619 else if(f == 3)
00620 {
00621 sprintf(fldStr,"%lu",UsersUserIdVector[i]);
00622 saveToDatabase(fp,UsersDatabaseEntryFields[f],fldStr,DB_SAVE_OPEN_AND_CLOSE,false);
00623 }
00624 else if(f == 4)
00625 {
00626 sprintf(fldStr,"%d",UsersPermissionsVector[i]);
00627 saveToDatabase(fp,UsersDatabaseEntryFields[f],fldStr,DB_SAVE_OPEN_AND_CLOSE,false);
00628 }
00629 else if(f == 5)
00630 {
00631 sprintf(fldStr,"%lu",UsersLastLoginAttemptVector[i]);
00632 saveToDatabase(fp,UsersDatabaseEntryFields[f],fldStr,DB_SAVE_OPEN_AND_CLOSE,false);
00633 }
00634 else if(f == 6)
00635 {
00636 sprintf(fldStr,"%lu",UsersAccountCreatedTimeVector[i]);
00637 saveToDatabase(fp,UsersDatabaseEntryFields[f],fldStr,DB_SAVE_OPEN_AND_CLOSE,false);
00638 }
00639 else if(f == 7)
00640 {
00641 sprintf(fldStr,"%d",UsersLoginFailureCountVector[i]);
00642 saveToDatabase(fp,UsersDatabaseEntryFields[f],fldStr,DB_SAVE_OPEN_AND_CLOSE,false);
00643 }
00644 else if(f == 8)
00645 {
00646 sprintf(fldStr,"%lu",UsersLastModifiedTimeVector[i]);
00647 saveToDatabase(fp,UsersDatabaseEntryFields[f],fldStr,DB_SAVE_OPEN_AND_CLOSE,false);
00648 }
00649 else if(f == 9)
00650 saveToDatabase(fp,UsersDatabaseEntryFields[f],UsersLastModifierUsernameVector[i],DB_SAVE_OPEN_AND_CLOSE,false);
00651 }
00652
00653 saveToDatabase(fp,USERS_DB_ENTRY_STRING,"",DB_SAVE_CLOSE);
00654 }
00655
00656 saveToDatabase(fp,USERS_DB_GLOBAL_STRING,"",DB_SAVE_CLOSE);
00657
00658 }
00659 else
00660 {
00661 saveToDatabase(fp,HASHES_DB_GLOBAL_STRING,"",DB_SAVE_OPEN);
00662
00663 __MOUT__ << "Saving " << HashesVector.size() << " Hashes." << std::endl;
00664 for(uint64_t i=0;i<HashesVector.size();++i)
00665 {
00666 __MOUT__ << "Saving " << HashesVector[i] << " Hashes." << std::endl;
00667 saveToDatabase(fp,HASHES_DB_ENTRY_STRING,"",DB_SAVE_OPEN,false);
00668 for(unsigned int f=0;f<HashesDatabaseEntryFields.size();++f)
00669 {
00670 if(f == 0)
00671 saveToDatabase(fp,HashesDatabaseEntryFields[f],HashesVector[i],DB_SAVE_OPEN_AND_CLOSE,false);
00672 else if(f == 1)
00673 {
00674 sprintf(fldStr,"%lu",HashesAccessTimeVector[i]);
00675 saveToDatabase(fp,HashesDatabaseEntryFields[f],fldStr,DB_SAVE_OPEN_AND_CLOSE,false);
00676 }
00677 }
00678 saveToDatabase(fp,HASHES_DB_ENTRY_STRING,"",DB_SAVE_CLOSE);
00679 }
00680
00681 saveToDatabase(fp,HASHES_DB_GLOBAL_STRING,"",DB_SAVE_CLOSE);
00682 }
00683
00684
00685 fclose(fp);
00686 return true;
00687 }
00688
00689
00690
00691
00692
00693
00694
00695
00696 bool WebUsers::createNewAccount(std::string Username, std::string DisplayName)
00697 {
00698 __MOUT__ << "Creating account: " << Username << std::endl;
00699
00700 uint64_t i;
00701 if((i = searchUsersDatabaseForUsername(Username)) != NOT_FOUND_IN_DATABASE)
00702 {
00703 __MOUT__ << "Username: " << Username << " already exists" << std::endl;
00704 return false;
00705 }
00706
00707
00708 UsersUsernameVector.push_back(Username);
00709 UsersDisplayNameVector.push_back(DisplayName);
00710 UsersSaltVector.push_back("");
00711 UsersPermissionsVector.push_back(UsersPermissionsVector.size()?0:-1);
00712 UsersUserIdVector.push_back(usersNextUserId_++);
00713 if(usersNextUserId_ == (uint64_t)-1)
00714 {
00715 __MOUT__ << "usersNextUserId_ wrap around!! Too many users??? Notify Admins." << std::endl;
00716 usersNextUserId_ = 1;
00717 }
00718 UsersLastLoginAttemptVector.push_back(0);
00719 UsersLoginFailureCountVector.push_back(0);
00720 UsersAccountCreatedTimeVector.push_back(time(0));
00721 UsersLastModifiedTimeVector.push_back(0);
00722 UsersLastModifierUsernameVector.push_back("");
00723
00724 return saveDatabaseToFile(DB_USERS);
00725 }
00726
00727
00728
00729
00730
00731
00732
00733 bool WebUsers::deleteAccount(std::string username, std::string displayName)
00734 {
00735 uint64_t i = searchUsersDatabaseForUsername(username);
00736 if(i == NOT_FOUND_IN_DATABASE) return false;
00737 if(UsersDisplayNameVector[i] != displayName) return false;
00738
00739
00740
00741 UsersUsernameVector.erase(UsersUsernameVector.begin()+i);
00742 UsersDisplayNameVector.erase(UsersDisplayNameVector.begin()+i);
00743 UsersSaltVector.erase(UsersSaltVector.begin()+i);
00744 UsersPermissionsVector.erase(UsersPermissionsVector.begin()+i);
00745 UsersUserIdVector.erase(UsersUserIdVector.begin()+i);
00746 UsersLastLoginAttemptVector.erase(UsersLastLoginAttemptVector.begin()+i);
00747 UsersAccountCreatedTimeVector.erase(UsersAccountCreatedTimeVector.begin()+i);
00748 UsersLoginFailureCountVector.erase(UsersLoginFailureCountVector.begin()+i);
00749 UsersLastModifierUsernameVector.erase(UsersLastModifierUsernameVector.begin()+i);
00750 UsersLastModifiedTimeVector.erase(UsersLastModifiedTimeVector.begin()+i);
00751
00752
00753 return saveDatabaseToFile(DB_USERS);
00754 }
00755
00756
00757 unsigned int WebUsers::hexByteStrToInt(const char *h)
00758 {
00759 unsigned int rv;
00760 char hs[3] = {h[0],h[1],'\0'};
00761 sscanf(hs,"%X",&rv);
00762 return rv;
00763 }
00764
00765
00766 void WebUsers::intToHexStr(unsigned char i, char *h)
00767 {
00768 sprintf(h,"%2.2X",i);
00769 }
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780 uint64_t WebUsers::attemptActiveSession(std::string uuid, std::string &jumbledUser,
00781 std::string jumbledPw, std::string &newAccountCode)
00782 {
00783 cleanupExpiredEntries();
00784
00785 if(!CareAboutCookieCodes_)
00786 {
00787 uint64_t uid = getAdminUserID();
00788 jumbledUser = getUsersDisplayName(uid);
00789 newAccountCode = genCookieCode();
00790 return uid;
00791 }
00792
00793 if(securityType_ == SECURITY_TYPE_KERBEROS)
00794 return -1;
00795
00796 uint64_t i;
00797
00798
00799 if((i = searchLoginSessionDatabaseForUUID(uuid)) == NOT_FOUND_IN_DATABASE)
00800 {
00801 __MOUT__ << "uuid: " << uuid << " is not found" << std::endl;
00802 newAccountCode = "1";
00803 return NOT_FOUND_IN_DATABASE;
00804 }
00805 ++LoginSessionAttemptsVector[i];
00806
00807 std::string user = dejumble(jumbledUser,LoginSessionIdVector[i]);
00808 __MOUT__ << "DejumbledUser = " << user << std::endl;
00809 std::string pw = dejumble(jumbledPw,LoginSessionIdVector[i]);
00810
00811
00812 if((i = searchUsersDatabaseForUsername(user)) == NOT_FOUND_IN_DATABASE)
00813 {
00814 __MOUT__ << "user: " << user << " is not found" << std::endl;
00815 return NOT_FOUND_IN_DATABASE;
00816 }
00817
00818 UsersLastLoginAttemptVector[i] = time(0);
00819 if(!UsersPermissionsVector[i])
00820 {
00821 __MOUT__ << "user: " << user << " account INACTIVE (could be due to failed logins)" << std::endl;
00822 return NOT_FOUND_IN_DATABASE;
00823 }
00824
00825 if(UsersSaltVector[i] == "")
00826 {
00827 __MOUT__ << "First login attempt for user: " << user << std::endl;
00828
00829 char charTimeStr[10];
00830 sprintf(charTimeStr,"%d",int(UsersAccountCreatedTimeVector[i] & 0xffff));
00831 std::string tmpTimeStr = charTimeStr;
00832 if(newAccountCode != tmpTimeStr)
00833 {
00834 __MOUT__ << "New account code did not match: " << tmpTimeStr << " != " << newAccountCode << std::endl;
00835 saveDatabaseToFile(DB_USERS);
00836 return NOT_FOUND_IN_DATABASE;
00837 }
00838
00839
00840
00841
00842 while(!addToHashesDatabase(sha512(user,pw,UsersSaltVector[i])))
00843 {
00844
00845
00846 UsersSaltVector[i] = "";
00847 }
00848
00849
00850 __MOUT__ << "\tHash added: " << HashesVector[HashesVector.size()-1] << std::endl;
00851 }
00852 else
00853 {
00854 std::string salt = UsersSaltVector[i];
00855 __MOUT__ << salt<< " " << i << std::endl;
00856 if(searchHashesDatabaseForHash(sha512(user,pw,salt)) == NOT_FOUND_IN_DATABASE)
00857 {
00858 __MOUT__ << "not found?" << std::endl;
00859 ++UsersLoginFailureCountVector[i];
00860 if(UsersLoginFailureCountVector[i] >= USERS_MAX_LOGIN_FAILURES)
00861 UsersPermissionsVector[i] = 0;
00862
00863 __MOUT__ << "\tUser/pw for user: " << user << " was not correct Failed Attempt #" << (int)(UsersLoginFailureCountVector[i]) << std::endl;
00864 if(!UsersPermissionsVector[i])
00865 __MOUT__ << "Account is locked!" << std::endl;
00866
00867 saveDatabaseToFile(DB_USERS);
00868 return NOT_FOUND_IN_DATABASE;
00869 }
00870 }
00871
00872 __MOUT__ << "Login successful for: " << user << std::endl;
00873
00874 UsersLoginFailureCountVector[i] = 0;
00875
00876
00877 for(int h=0;h<2;++h)
00878 {
00879 std::string fn = (std::string)WEB_LOGIN_DB_PATH + (std::string)USERS_LOGIN_HISTORY_PATH + (h?USERS_GLOBAL_HISTORY_FILE:UsersUsernameVector[i])
00880 + "." + (std::string)USERS_LOGIN_HISTORY_FILETYPE;
00881
00882 HttpXmlDocument histXml;
00883
00884 if(histXml.loadXmlDocument(fn))
00885 {
00886 while(histXml.getChildrenCount() + 1 > (h?USERS_GLOBAL_HISTORY_SIZE:USERS_LOGIN_HISTORY_SIZE))
00887 histXml.removeDataElement();
00888 }
00889 else
00890 __MOUT__ << "No previous login history found." << std::endl;
00891
00892
00893 char entryStr[500];
00894 if(h)
00895 sprintf(entryStr,"Time=%lu Username=%s Permissions=%d UID=%lu",
00896 time(0),UsersUsernameVector[i].c_str(),UsersPermissionsVector[i],UsersUserIdVector[i]);
00897 else
00898 sprintf(entryStr,"Time=%lu DisplayName=%s Permissions=%d UID=%lu",
00899 time(0),UsersDisplayNameVector[i].c_str(),UsersPermissionsVector[i],UsersUserIdVector[i]);
00900 histXml.addTextElementToData(PREF_XML_LOGIN_HISTORY_FIELD,entryStr);
00901
00902
00903 histXml.saveXmlDocument(fn);
00904 }
00905
00906
00907 saveDatabaseToFile(DB_USERS);
00908 jumbledUser = UsersDisplayNameVector[i];
00909 newAccountCode = createNewActiveSession(UsersUserIdVector[i]);
00910 return UsersUserIdVector[i];
00911 }
00912
00913
00914
00915
00916 uint64_t WebUsers::searchActiveSessionDatabaseForCookie(std::string cookieCode) const
00917 {
00918 uint64_t i=0;
00919 for(;i<ActiveSessionCookieCodeVector.size();++i)
00920 if(ActiveSessionCookieCodeVector[i] == cookieCode) break;
00921 return (i == ActiveSessionCookieCodeVector.size())?NOT_FOUND_IN_DATABASE:i;
00922 }
00923
00924
00925
00926
00927
00928 bool WebUsers::isUsernameActive (std::string username) const
00929 {
00930 uint64_t u;
00931 if((u = searchUsersDatabaseForUsername(username)) == NOT_FOUND_IN_DATABASE) return false;
00932 return isUserIdActive(UsersUserIdVector[u]);
00933 }
00934
00935
00936
00937
00938
00939 bool WebUsers::isUserIdActive(uint64_t uid) const
00940 {
00941 uint64_t i=0;
00942 for(;i<ActiveSessionUserIdVector.size();++i)
00943 if(ActiveSessionUserIdVector[i] == uid) return true;
00944 return false;
00945 }
00946
00947
00948
00949
00950 uint64_t WebUsers::searchUsersDatabaseForUsername(std::string username) const
00951 {
00952 uint64_t i=0;
00953 for(;i<UsersUsernameVector.size();++i)
00954 if(UsersUsernameVector[i] == username) break;
00955 return (i == UsersUsernameVector.size())?NOT_FOUND_IN_DATABASE:i;
00956 }
00957
00958
00959
00960
00961 uint64_t WebUsers::searchUsersDatabaseForUserId(uint64_t uid) const
00962 {
00963 uint64_t i=0;
00964 for(;i<UsersUserIdVector.size();++i)
00965 if(UsersUserIdVector[i] == uid) break;
00966 return (i == UsersUserIdVector.size())?NOT_FOUND_IN_DATABASE:i;
00967 }
00968
00969
00970
00971
00972 uint64_t WebUsers::searchLoginSessionDatabaseForUUID(std::string uuid) const
00973 {
00974 uint64_t i=0;
00975 for(;i<LoginSessionUUIDVector.size();++i)
00976 if(LoginSessionUUIDVector[i] == uuid) break;
00977 return (i == LoginSessionUUIDVector.size())?NOT_FOUND_IN_DATABASE:i;
00978 }
00979
00980
00981
00982
00983 uint64_t WebUsers::searchHashesDatabaseForHash(std::string hash)
00984 {
00985 uint64_t i=0;
00986 __MOUT__ << i << " " << HashesVector.size()<< " " << HashesAccessTimeVector.size() <<
00987 hash << std::endl;
00988 for(;i<HashesVector.size();++i)
00989 if(HashesVector[i] == hash) break;
00990 else
00991 __MOUT__ << HashesVector[i] << " ?????? " << std::endl;
00992 __MOUT__ << i << std::endl;
00993 if(i < HashesAccessTimeVector.size())
00994 HashesAccessTimeVector.push_back((time(0) + (rand()%2?1:-1)*(rand() % 30*24*60*60)) & 0x0FFFFFFFFFE000000 );
00995
00996 __MOUT__ << i << std::endl;
00997 return (i == HashesVector.size())?NOT_FOUND_IN_DATABASE:i;
00998 }
00999
01000
01001
01002
01003
01004 bool WebUsers::addToHashesDatabase(std::string hash)
01005 {
01006 if(searchHashesDatabaseForHash(hash) != NOT_FOUND_IN_DATABASE)
01007 {
01008 __MOUT__ << "Hash collision: " << hash << std::endl;
01009 return false;
01010 }
01011 HashesVector.push_back(hash);
01012 HashesAccessTimeVector.push_back((time(0) + (rand()%2?1:-1)*(rand() % 30*24*60*60)) & 0x0FFFFFFFFFE000000 );
01013
01014 return saveDatabaseToFile(DB_HASHES);
01015 }
01016
01017
01018
01019 std::string WebUsers::genCookieCode()
01020 {
01021 char hexStr[3];
01022 std::string cc = "";
01023 for(uint32_t i=0;i<COOKIE_CODE_LENGTH/2;++i)
01024 {
01025 intToHexStr(rand(),hexStr);
01026 cc.append(hexStr);
01027 }
01028 return cc;
01029 }
01030
01031
01032
01033 void WebUsers::removeLoginSessionEntry(unsigned int i)
01034 {
01035 LoginSessionIdVector.erase (LoginSessionIdVector.begin()+i);
01036 LoginSessionUUIDVector.erase (LoginSessionUUIDVector.begin()+i);
01037 LoginSessionIpVector.erase (LoginSessionIpVector.begin()+i);
01038 LoginSessionStartTimeVector.erase (LoginSessionStartTimeVector.begin()+i);
01039 LoginSessionAttemptsVector.erase (LoginSessionAttemptsVector.begin()+i);
01040 }
01041
01042
01043
01044
01045
01046 std::string WebUsers::createNewActiveSession(uint64_t uid, std::string ip, uint64_t asIndex)
01047 {
01048 ActiveSessionCookieCodeVector.push_back (genCookieCode());
01049 ActiveSessionIpVector.push_back (ip);
01050 ActiveSessionUserIdVector.push_back (uid);
01051 ActiveSessionStartTimeVector.push_back (time(0));
01052
01053 if(asIndex)
01054 ActiveSessionIndex.push_back (asIndex);
01055 else
01056 {
01057
01058 uint64_t max = 0;
01059 for(uint64_t j=0;j<ActiveSessionIndex.size();++j)
01060 if(ActiveSessionUserIdVector[j] == uid && max < ActiveSessionIndex[j])
01061 max = ActiveSessionIndex[j];
01062
01063 ActiveSessionIndex.push_back (max?max+1:1);
01064 }
01065
01066 return ActiveSessionCookieCodeVector[ActiveSessionCookieCodeVector.size()-1];
01067 }
01068
01069
01070
01071 void WebUsers::removeActiveSessionEntry(unsigned int i)
01072 {
01073 ActiveSessionCookieCodeVector.erase (ActiveSessionCookieCodeVector.begin()+i);
01074 ActiveSessionIpVector.erase (ActiveSessionIpVector.begin()+i);
01075 ActiveSessionUserIdVector.erase (ActiveSessionUserIdVector.begin()+i);
01076 ActiveSessionStartTimeVector.erase (ActiveSessionStartTimeVector.begin()+i);
01077 ActiveSessionIndex.erase (ActiveSessionIndex.begin()+i);
01078 }
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091
01092
01093
01094
01095
01096
01097
01098
01099
01100
01101
01102
01103 std::string WebUsers::refreshCookieCode(unsigned int i, bool enableRefresh)
01104 {
01105
01106 for(uint64_t j=ActiveSessionUserIdVector.size()-1;j!=(uint64_t)-1;--j)
01107 if (ActiveSessionUserIdVector[j] == ActiveSessionUserIdVector[i] &&
01108 ActiveSessionIndex[j] == ActiveSessionIndex[i])
01109 {
01110
01111
01112
01113 if(enableRefresh && (time(0) - ActiveSessionStartTimeVector[j] > ACTIVE_SESSION_EXPIRATION_TIME/2))
01114 {
01115
01116 ActiveSessionStartTimeVector[j] = time(0) - ACTIVE_SESSION_EXPIRATION_TIME +
01117 ACTIVE_SESSION_COOKIE_OVERLAP_TIME;
01118
01119
01120 return createNewActiveSession(ActiveSessionUserIdVector[i],ActiveSessionIpVector[i],ActiveSessionIndex[i]);
01121 }
01122
01123 return ActiveSessionCookieCodeVector[j];
01124 }
01125
01126 return "0";
01127 }
01128
01129
01130
01131
01132
01133
01134 uint64_t WebUsers::isCookieCodeActiveForLogin(std::string uuid,std::string &cookieCode,std::string &username)
01135 {
01136
01137
01138 if(!CareAboutCookieCodes_)
01139 return getAdminUserID();
01140
01141
01142
01143
01144 if(!ActiveSessionStartTimeVector.size()) return NOT_FOUND_IN_DATABASE;
01145
01146 uint64_t i,j;
01147
01148
01149 if((i = searchLoginSessionDatabaseForUUID(uuid)) == NOT_FOUND_IN_DATABASE)
01150 {
01151 __MOUT__ << "uuid not found: " << uuid << std::endl;
01152 return NOT_FOUND_IN_DATABASE;
01153 }
01154
01155 username = dejumble(username,LoginSessionIdVector[i]);
01156
01157
01158 if((i = searchActiveSessionDatabaseForCookie(cookieCode)) == NOT_FOUND_IN_DATABASE)
01159 {
01160 __MOUT__ << "Cookie code not found" << std::endl;
01161 return NOT_FOUND_IN_DATABASE;
01162 }
01163
01164
01165 if((j = searchUsersDatabaseForUserId(ActiveSessionUserIdVector[i])) == NOT_FOUND_IN_DATABASE)
01166 {
01167 __MOUT__ << "User ID not found" << std::endl;
01168 return NOT_FOUND_IN_DATABASE;
01169 }
01170
01171
01172 if(UsersUsernameVector[j] != username)
01173 {
01174 __MOUT__ << "username: " << username << " is not found" << std::endl;
01175 return NOT_FOUND_IN_DATABASE;
01176 }
01177
01178 username = UsersDisplayNameVector[j];
01179 cookieCode = refreshCookieCode(i);
01180 return UsersUserIdVector[j];
01181 }
01182
01183
01184
01185
01186 uint64_t WebUsers::getActiveSessionCountForUser(uint64_t uid)
01187 {
01188 bool unique;
01189 std::vector<uint64_t> uniqueAsi;
01190
01191 uint64_t i,j;
01192 for(i = 0; i<ActiveSessionUserIdVector.size(); ++i)
01193 if(ActiveSessionUserIdVector[i] == uid)
01194 {
01195
01196 unique = true;
01197
01198 for(j = 0; j<uniqueAsi.size(); ++j)
01199 if(uniqueAsi[j] == ActiveSessionIndex[i])
01200 {
01201 unique = false; break;
01202 }
01203
01204 if(unique)
01205 uniqueAsi.push_back(ActiveSessionIndex[i]);
01206 }
01207
01208 __MOUT__ << "Found " << uniqueAsi.size() << " active sessions for uid " << uid << std::endl;
01209
01210 return uniqueAsi.size();
01211 }
01212
01213
01214
01215 std::string WebUsers::getUsersDisplayName(uint64_t uid)
01216 {
01217 uint64_t i;
01218 if((i = searchUsersDatabaseForUserId(uid)) == NOT_FOUND_IN_DATABASE) return "";
01219 return UsersDisplayNameVector[i];
01220 }
01221
01222
01223
01224 std::string WebUsers::getUsersUsername(uint64_t uid)
01225 {
01226 uint64_t i;
01227 if((i = searchUsersDatabaseForUserId(uid)) == NOT_FOUND_IN_DATABASE) return "";
01228 return UsersUsernameVector[i];
01229 }
01230
01231
01232
01233
01234
01235
01236
01237
01238
01239
01240
01241 uint64_t WebUsers::cookieCodeLogout(std::string cookieCode, bool logoutOtherUserSessions, uint64_t *userId, std::string ip)
01242 {
01243
01244
01245 uint64_t i;
01246
01247
01248 if((i = searchActiveSessionDatabaseForCookie(cookieCode)) == NOT_FOUND_IN_DATABASE)
01249 {
01250 __MOUT__ << "Cookie code not found" << std::endl;
01251 return NOT_FOUND_IN_DATABASE;
01252 }
01253
01254
01255 if(ActiveSessionIpVector[i] != ip)
01256 {
01257 __MOUT__ << "IP does not match active session" << std::endl;
01258 return NOT_FOUND_IN_DATABASE;
01259 }
01260
01261
01262
01263
01264
01265
01266
01267 uint64_t asi = ActiveSessionIndex[i];
01268 uint64_t uid = ActiveSessionUserIdVector[i];
01269 if(userId) *userId = uid;
01270 uint64_t logoutCount = 0;
01271
01272 i = 0;
01273 while(i < ActiveSessionIndex.size())
01274 {
01275 if( (logoutOtherUserSessions && ActiveSessionUserIdVector[i] == uid &&
01276 ActiveSessionIndex[i] != asi) ||
01277 (!logoutOtherUserSessions && ActiveSessionUserIdVector[i] == uid &&
01278 ActiveSessionIndex[i] == asi) )
01279 {
01280 __MOUT__ << "Logging out of active session " << ActiveSessionUserIdVector[i]
01281 << "-" << ActiveSessionIndex[i] << std::endl;
01282 removeActiveSessionEntry(i);
01283 ++logoutCount;
01284 }
01285 else
01286 ++i;
01287 }
01288
01289 __MOUT__ << "Found and removed active session count = " << logoutCount << std::endl;
01290
01291 return logoutCount;
01292 }
01293
01294
01295
01296 bool WebUsers::getUserInfoForCookie(std::string &cookieCode,
01297 std::string *userName, std::string *displayName,
01298 uint64_t *activeSessionIndex)
01299 {
01300 if(userName) *userName = "";
01301 if(displayName) *displayName = "";
01302
01303 if(!CareAboutCookieCodes_)
01304 {
01305 uint64_t uid = getAdminUserID();
01306 if(userName) *userName = getUsersUsername(uid);
01307 if(displayName) *displayName = getUsersDisplayName(uid);
01308 if(activeSessionIndex) *activeSessionIndex = -1;
01309 return true;
01310 }
01311
01312 uint64_t i,j;
01313
01314
01315 if((i = searchActiveSessionDatabaseForCookie(cookieCode)) == NOT_FOUND_IN_DATABASE)
01316 {
01317 __MOUT__ << "cookieCode NOT_FOUND_IN_DATABASE" << std::endl;
01318 return false;
01319 }
01320
01321
01322 if((j = searchUsersDatabaseForUserId(ActiveSessionUserIdVector[i])) == NOT_FOUND_IN_DATABASE)
01323 {
01324 __MOUT__ << "ActiveSessionUserIdVector NOT_FOUND_IN_DATABASE" << std::endl;
01325 return false;
01326 }
01327
01328 if(userName) *userName = UsersUsernameVector[j];
01329 if(displayName) *displayName = UsersDisplayNameVector[j];
01330 if(activeSessionIndex) *activeSessionIndex = ActiveSessionIndex[i];
01331 return true;
01332 }
01333
01334
01335
01336
01337
01338
01339
01340
01341
01342
01343
01344
01345 bool WebUsers::cookieCodeIsActiveForRequest(std::string &cookieCode,
01346 uint8_t *userPermissions, uint64_t *uid, std::string ip,
01347 bool refresh, std::string *userWithLock)
01348 {
01349
01350 cleanupExpiredEntries();
01351
01352 uint64_t i,j;
01353
01354
01355
01356
01357 if(!CareAboutCookieCodes_)
01358 {
01359 if(userPermissions) *userPermissions = -1;
01360 if(uid) *uid = getAdminUserID();
01361 if(userWithLock) *userWithLock = usersUsernameWithLock_;
01362
01363 cookieCode = genCookieCode();
01364
01365 return true;
01366 }
01367
01368
01369
01370 if((i = searchActiveSessionDatabaseForCookie(cookieCode)) == NOT_FOUND_IN_DATABASE)
01371 {
01372 __MOUT__ << "Cookie code not found" << std::endl;
01373 cookieCode = REQ_NO_LOGIN_RESPONSE;
01374 return false;
01375 }
01376
01377
01378 if(ActiveSessionIpVector[i] != ip)
01379 {
01380 __MOUT__ << "IP does not match active session" << std::endl;
01381 cookieCode = REQ_NO_LOGIN_RESPONSE;
01382 return false;
01383 }
01384
01385
01386 if((j = searchUsersDatabaseForUserId(ActiveSessionUserIdVector[i])) == NOT_FOUND_IN_DATABASE)
01387 {
01388 __MOUT__ << "User ID not found" << std::endl;
01389 cookieCode = REQ_NO_LOGIN_RESPONSE;
01390 return false;
01391 }
01392
01393 uint8_t tmpPerm = getPermissionsForUser(UsersUserIdVector[j]);
01394
01395 if(!tmpPerm)
01396 {
01397 cookieCode = REQ_NO_PERMISSION_RESPONSE;
01398 return false;
01399 }
01400
01401
01402 if(userPermissions) *userPermissions = tmpPerm;
01403 if(uid) *uid = UsersUserIdVector[j];
01404 if(userWithLock) *userWithLock = usersUsernameWithLock_;
01405
01406 cookieCode = refreshCookieCode(i,refresh);
01407
01408 return true;
01409 }
01410
01411
01412
01413
01414
01415
01416
01417 void WebUsers::cleanupExpiredEntries(std::vector<std::string> *loggedOutUsernames)
01418 {
01419 uint64_t i;
01420 uint64_t tmpUid;
01421
01422 if(loggedOutUsernames)
01423 {
01424 for(i=0;i<UsersLoggedOutUsernames_.size();++i)
01425 loggedOutUsernames->push_back(UsersLoggedOutUsernames_[i]);
01426 UsersLoggedOutUsernames_.clear();
01427 }
01428
01429
01430
01431
01432 for(i=0;i<LoginSessionStartTimeVector.size();++i)
01433 if(LoginSessionStartTimeVector[i] + LOGIN_SESSION_EXPIRATION_TIME < time(0) ||
01434 LoginSessionAttemptsVector[i] > LOGIN_SESSION_ATTEMPTS_MAX)
01435 {
01436
01437
01438
01439 removeLoginSessionEntry(i);
01440 --i;
01441 }
01442
01443
01444
01445
01446
01447
01448
01449
01450
01451
01452 for(i=0;i<ActiveSessionStartTimeVector.size();++i)
01453 if(ActiveSessionStartTimeVector[i] + ACTIVE_SESSION_EXPIRATION_TIME <= time(0))
01454 {
01455
01456
01457
01458
01459
01460 tmpUid = ActiveSessionUserIdVector[i];
01461 removeActiveSessionEntry(i);
01462
01463
01464
01465 if(!isUserIdActive(tmpUid))
01466 {
01467 if(loggedOutUsernames)
01468 loggedOutUsernames->push_back(UsersUsernameVector[searchUsersDatabaseForUserId(tmpUid)]);
01469 else
01470 UsersLoggedOutUsernames_.push_back(UsersUsernameVector[searchUsersDatabaseForUserId(tmpUid)]);
01471 }
01472
01473 --i;
01474 }
01475
01476
01477
01478
01479
01480
01481
01482
01483
01484
01485
01486
01487 if(CareAboutCookieCodes_ && !isUsernameActive(usersUsernameWithLock_))
01488 usersUsernameWithLock_ = "";
01489 }
01490
01491
01492
01493
01494
01495
01496
01497
01498 std::string WebUsers::createNewLoginSession(std::string UUID,std::string ip)
01499 {
01500 __MOUT__ << "UUID: " << UUID << std::endl << std::endl;
01501 uint64_t i=0;
01502 for(;i<LoginSessionUUIDVector.size();++i)
01503 if(LoginSessionUUIDVector[i] == UUID) break;
01504
01505 if(i != LoginSessionUUIDVector.size())
01506 {
01507 __MOUT__ << "UUID: " << UUID << " is not unique" << std::endl;
01508 return "";
01509 }
01510
01511
01512 LoginSessionUUIDVector.push_back(UUID);
01513
01514
01515 char hexStr[3];
01516 std::string sid = "";
01517 for(i=0;i<SESSION_ID_LENGTH/2;++i)
01518 {
01519 intToHexStr(rand(),hexStr);
01520 sid.append(hexStr);
01521 }
01522 LoginSessionIdVector.push_back(sid);
01523 LoginSessionIpVector.push_back("");
01524 LoginSessionStartTimeVector.push_back(time(0));
01525 LoginSessionAttemptsVector.push_back(0);
01526
01527 return sid;
01528 }
01529
01530
01531
01532
01533
01534
01535
01536
01537 std::string WebUsers::sha512(std::string user, std::string password, std::string &salt)
01538 {
01539 SHA512_CTX sha512_context;
01540 char hexStr[3];
01541
01542 if(salt == "")
01543 {
01544 SHA512_Init(&sha512_context);
01545
01546 for(unsigned int i=0;i<8;++i)
01547 sha512_context.h[i] += rand();
01548
01549 for(unsigned int i=0;i<sizeof(SHA512_CTX);++i)
01550 {
01551 intToHexStr((uint8_t)(((uint8_t *)(&sha512_context))[i]),hexStr);
01552
01553 salt.append(hexStr);
01554 }
01555 __MOUT__ << salt << std::endl;
01556 }
01557 else
01558 {
01559
01560 __MOUT__ << salt << std::endl;
01561
01562 for(unsigned int i=0;i<sizeof(SHA512_CTX);++i)
01563 ((uint8_t *)(&sha512_context))[i] = hexByteStrToInt(&(salt.c_str()[i*2]));
01564 }
01565
01566 std::string strToHash = salt + user + password;
01567
01568 __MOUT__ << salt << std::endl;
01569 unsigned char hash[SHA512_DIGEST_LENGTH];
01570 __MOUT__ << salt << std::endl;
01571 char retHash[SHA512_DIGEST_LENGTH*2+1];
01572 __MOUT__ << strToHash.length() << " " << strToHash << std::endl;
01573
01574
01575 __MOUT__ << "If crashing occurs here, may be an illegal salt context." << std::endl;
01576 SHA512_Update(&sha512_context, strToHash.c_str(), strToHash.length());
01577
01578 SHA512_Final(hash, &sha512_context);
01579
01580 __MOUT__ << salt << std::endl;
01581 int i = 0;
01582 for(i = 0; i < SHA512_DIGEST_LENGTH; i++)
01583 sprintf(retHash + (i * 2), "%02x", hash[i]);
01584
01585 __MOUT__ << salt << std::endl;
01586 retHash[SHA512_DIGEST_LENGTH*2] = '\0';
01587
01588
01589 __MOUT__ << salt << std::endl;
01590
01591
01592 return retHash;
01593 }
01594
01595
01596
01597
01598
01599
01600 std::string WebUsers::dejumble(std::string u, std::string s)
01601 {
01602
01603 if(s.length() != SESSION_ID_LENGTH) return "";
01604
01605 int ss = s.length()/2;
01606 int p = hexByteStrToInt(&(s.c_str()[0])) % ss;
01607 int n = hexByteStrToInt(&(s.c_str()[p*2])) % ss;
01608 int len = (hexByteStrToInt(&(u.c_str()[p*2])) - p - n + ss*3) % ss;
01609
01610 bool x[ss];
01611 for(int i=0;i<ss;++i) x[i] = 0;
01612 x[p] = 1;
01613
01614 int c = hexByteStrToInt(&(u.c_str()[p*2]));
01615
01616 std::string user = "";
01617
01618 for(int l=0;l<len;++l) {
01619 p = (p + hexByteStrToInt(&(s.c_str()[p*2]))) % ss;
01620 while(x[p]) p = (p+1) % ss;
01621 x[p] = 1;
01622 n = hexByteStrToInt(&(s.c_str()[p*2]));
01623 user.append(1,(hexByteStrToInt(&(u.c_str()[p*2])) - c - n + ss*4) % ss);
01624 c = hexByteStrToInt(&(u.c_str()[p*2]));
01625 }
01626
01627 return user;
01628 }
01629
01630
01631
01632
01633 uint8_t WebUsers::getPermissionsForUser(uint64_t uid)
01634 {
01635 uint64_t userIndex = searchUsersDatabaseForUserId(uid);
01636 return (userIndex < UsersPermissionsVector.size())?UsersPermissionsVector[userIndex]:0;
01637 }
01638
01639
01640
01641
01642
01643 std::string WebUsers::getTooltipFilename(
01644 const std::string& username, const std::string &srcFile,
01645 const std::string &srcFunc, const std::string &srcId)
01646 {
01647 std::string filename = (std::string)WEB_LOGIN_DB_PATH + TOOLTIP_DB_PATH + "/";
01648
01649
01650
01651 mkdir(((std::string)WEB_LOGIN_DB_PATH).c_str(), 0755);
01652 mkdir(((std::string)WEB_LOGIN_DB_PATH + USERS_DB_PATH).c_str(), 0755);
01653 mkdir(filename.c_str(), 0755);
01654
01655 for(const char& c: username)
01656 if(
01657 (c >= 'a' && c <= 'z') ||
01658 (c >= 'A' && c <= 'Z') ||
01659 (c >= '0' && c <= '9') )
01660 filename += c;
01661 filename += "/";
01662
01663
01664 mkdir(filename.c_str(), 0755);
01665
01666 for(const char& c: srcFile)
01667 if(
01668 (c >= 'a' && c <= 'z') ||
01669 (c >= 'A' && c <= 'Z') ||
01670 (c >= '0' && c <= '9') )
01671 filename += c;
01672 filename += "_";
01673 for(const char& c: srcFunc)
01674 if(
01675 (c >= 'a' && c <= 'z') ||
01676 (c >= 'A' && c <= 'Z') ||
01677 (c >= '0' && c <= '9') )
01678 filename += c;
01679 filename += "_";
01680 for(const char& c: srcId)
01681 if(
01682 (c >= 'a' && c <= 'z') ||
01683 (c >= 'A' && c <= 'Z') ||
01684 (c >= '0' && c <= '9') )
01685 filename += c;
01686 filename += ".tip";
01687 __MOUT__ << "filename " << filename << std::endl;
01688 return filename;
01689 }
01690
01691
01692
01693
01694 void WebUsers::tooltipSetNeverShowForUsername(const std::string& username,
01695 HttpXmlDocument *xmldoc,
01696 const std::string &srcFile, const std::string &srcFunc,
01697 const std::string &srcId, bool doNeverShow, bool temporarySilence)
01698 {
01699
01700 __MOUT__ << "Setting tooltip never show for user: " << username <<
01701 " to " << doNeverShow << " (temporarySilence=" <<
01702 temporarySilence << ")" << std::endl;
01703
01704
01705 std::string filename = getTooltipFilename(username, srcFile, srcFunc, srcId);
01706 FILE *fp = fopen(filename.c_str(),"w");
01707 if(fp)
01708 {
01709 if(temporarySilence)
01710 fprintf(fp,"%ld",time(0)+60*60);
01711 else
01712 fputc(doNeverShow?'1':'0',fp);
01713 fclose(fp);
01714 }
01715 else
01716 __MOUT_ERR__ << "Big problme with tooltips! File not accessible: " << filename << std::endl;
01717 }
01718
01719
01720
01721
01722
01723
01724
01725
01726 void WebUsers::tooltipCheckForUsername(const std::string& username,
01727 HttpXmlDocument *xmldoc,
01728 const std::string &srcFile, const std::string &srcFunc,
01729 const std::string &srcId)
01730 {
01731 if(srcId == "ALWAYS")
01732 {
01733
01734 xmldoc->addTextElementToData("ShowTooltip","1");
01735 return;
01736 }
01737
01738
01739
01740
01741
01742 __MOUT__ << "Checking tooltip for user: " << username << std::endl;
01743
01744
01745
01746 std::string filename = getTooltipFilename(username, srcFile, srcFunc, srcId);
01747 FILE *fp = fopen(filename.c_str(),"r");
01748 if(fp)
01749 {
01750 time_t val;
01751 char line[100];
01752 fgets(line,100,fp);
01753
01754 sscanf(line,"%ld",&val);
01755 __MOUT__ << "tooltip value read = " << val << std::endl;
01756 fclose(fp);
01757
01758
01759
01760 xmldoc->addTextElementToData("ShowTooltip",val==1?"0":
01761 (time(0) > val?"1":"0"));
01762 }
01763 else
01764 xmldoc->addTextElementToData("ShowTooltip","1");
01765 }
01766
01767
01768
01769 void WebUsers::resetAllUserTooltips (const std::string &userNeedle)
01770 {
01771 std::system(("rm -rf " + (std::string)WEB_LOGIN_DB_PATH + TOOLTIP_DB_PATH +
01772 "/" + userNeedle).c_str());
01773 __MOUT__ << "Successfully reset Tooltips for user " << userNeedle << std::endl;
01774 }
01775
01776
01777
01778
01779
01780
01781
01782
01783
01784
01785
01786
01787
01788
01789
01790
01791
01792
01793
01794 void WebUsers::insertSettingsForUser(uint64_t uid, HttpXmlDocument *xmldoc, bool includeAccounts)
01795 {
01796 uint8_t p = getPermissionsForUser(uid);
01797 if(!p) return;
01798
01799 uint64_t userIndex = searchUsersDatabaseForUserId(uid);
01800 __MOUT__ << "Gettings settings for user: " << UsersUsernameVector[userIndex] << std::endl;
01801
01802 std::string fn = (std::string)WEB_LOGIN_DB_PATH + (std::string)USERS_PREFERENCES_PATH + UsersUsernameVector[userIndex] + "." + (std::string)USERS_PREFERENCES_FILETYPE;
01803
01804 HttpXmlDocument prefXml;
01805
01806 __MOUT__ << "Preferences file: " << fn << std::endl;
01807
01808 if(!prefXml.loadXmlDocument(fn))
01809 {
01810 __MOUT__ << "Preferences are defaults." << std::endl;
01811
01812 xmldoc->addTextElementToData(PREF_XML_BGCOLOR_FIELD,PREF_XML_BGCOLOR_DEFAULT);
01813 xmldoc->addTextElementToData(PREF_XML_DBCOLOR_FIELD,PREF_XML_DBCOLOR_DEFAULT);
01814 xmldoc->addTextElementToData(PREF_XML_WINCOLOR_FIELD,PREF_XML_WINCOLOR_DEFAULT);
01815 xmldoc->addTextElementToData(PREF_XML_LAYOUT_FIELD,PREF_XML_LAYOUT_DEFAULT);
01816 }
01817 else
01818 {
01819 __MOUT__ << "Saved Preferences found." << std::endl;
01820 xmldoc->copyDataChildren(prefXml);
01821 }
01822
01823 char permStr[10];
01824
01825
01826 if (includeAccounts && p == (uint8_t)-1) {
01827
01828 __MOUT__ << "Super User on our hands" << std::endl;
01829
01830 xmldoc->addTextElementToData(PREF_XML_ACCOUNTS_FIELD,"");
01831
01832
01833
01834 for(uint64_t i=0;i<UsersUsernameVector.size();++i)
01835 {
01836 xmldoc->addTextElementToParent("username",UsersUsernameVector[i],PREF_XML_ACCOUNTS_FIELD);
01837 xmldoc->addTextElementToParent("display_name",UsersDisplayNameVector[i],PREF_XML_ACCOUNTS_FIELD);
01838 sprintf(permStr,"%d",UsersPermissionsVector[i]);
01839 xmldoc->addTextElementToParent("permissions",permStr,PREF_XML_ACCOUNTS_FIELD);
01840 if(UsersSaltVector[i] == "")
01841 sprintf(permStr,"%d",int(UsersAccountCreatedTimeVector[i] & 0xffff));
01842 else
01843 permStr[0] = '\0';
01844 xmldoc->addTextElementToParent("nac",permStr,PREF_XML_ACCOUNTS_FIELD);
01845 }
01846 }
01847
01848
01849 fn = (std::string)WEB_LOGIN_DB_PATH + (std::string)USERS_PREFERENCES_PATH +
01850 (std::string)SYSTEM_PREFERENCES_PREFIX + "." + (std::string)USERS_PREFERENCES_FILETYPE;
01851 if(!prefXml.loadXmlDocument(fn))
01852 {
01853 __MOUT__ << "System Preferences are defaults." << std::endl;
01854
01855 xmldoc->addTextElementToData(PREF_XML_SYSLAYOUT_FIELD,PREF_XML_SYSLAYOUT_DEFAULT);
01856 }
01857 else
01858 {
01859 __MOUT__ << "Saved System Preferences found." << std::endl;
01860 xmldoc->copyDataChildren(prefXml);
01861 }
01862
01863
01864 sprintf(permStr,"%d",p);
01865 xmldoc->addTextElementToData(PREF_XML_PERMISSIONS_FIELD,permStr);
01866
01867
01868 xmldoc->addTextElementToData(PREF_XML_USERLOCK_FIELD,usersUsernameWithLock_);
01869
01870 xmldoc->addTextElementToData(PREF_XML_USERNAME_FIELD,getUsersUsername(uid));
01871 }
01872
01873
01874
01875
01876 void WebUsers::setGenericPreference (uint64_t uid, const std::string &preferenceName,
01877 const std::string &preferenceValue)
01878 {
01879 uint64_t userIndex = searchUsersDatabaseForUserId(uid);
01880
01881
01882
01883 std::string safePreferenceName = "";
01884 for(const auto &c:preferenceName)
01885 if((c >= 'a' && c <= 'z') ||
01886 (c >= 'A' && c <= 'Z') ||
01887 (c >= '0' && c <= '9') ||
01888 (c >= '-' || c <= '_'))
01889 safePreferenceName += c;
01890
01891 std::string dir = (std::string)WEB_LOGIN_DB_PATH + (std::string)USERS_PREFERENCES_PATH +
01892 "generic_" + safePreferenceName + "/";
01893
01894
01895 mkdir(dir.c_str(), 0755);
01896
01897 std::string fn = UsersUsernameVector[userIndex] + "_" + safePreferenceName +
01898 "." + (std::string)USERS_PREFERENCES_FILETYPE;
01899
01900 __MOUT__ << "Preferences file: " << (dir+fn) << std::endl;
01901
01902 FILE *fp = fopen((dir+fn).c_str(),"w");
01903 if(fp)
01904 {
01905 fprintf(fp,"%s",preferenceValue.c_str());
01906 fclose(fp);
01907 }
01908 else
01909 __MOUT_ERR__ << "Preferences file could not be opened for writing!" << std::endl;
01910 }
01911
01912
01913
01914
01915
01916 std::string WebUsers::getGenericPreference (uint64_t uid, const std::string &preferenceName,
01917 HttpXmlDocument *xmldoc) const
01918 {
01919 uint64_t userIndex = searchUsersDatabaseForUserId(uid);
01920
01921
01922
01923 std::string safePreferenceName = "";
01924 for(const auto &c:preferenceName)
01925 if((c >= 'a' && c <= 'z') ||
01926 (c >= 'A' && c <= 'Z') ||
01927 (c >= '0' && c <= '9') ||
01928 (c >= '-' || c <= '_'))
01929 safePreferenceName += c;
01930
01931 std::string dir = (std::string)WEB_LOGIN_DB_PATH + (std::string)USERS_PREFERENCES_PATH +
01932 "generic_" + safePreferenceName + "/";
01933
01934 std::string fn = UsersUsernameVector[userIndex] + "_" + safePreferenceName +
01935 "." + (std::string)USERS_PREFERENCES_FILETYPE;
01936
01937 __MOUT__ << "Preferences file: " << (dir+fn) << std::endl;
01938
01939
01940 FILE *fp = fopen((dir+fn).c_str(),"rb");
01941 if(fp)
01942 {
01943 fseek(fp, 0, SEEK_END);
01944 long size = ftell(fp);
01945 char line[size+1];
01946 rewind(fp);
01947 fgets(line,size+1,fp);
01948 fclose(fp);
01949
01950 __MOUT__ << "Read value " << line << std::endl;
01951 if(xmldoc) xmldoc->addTextElementToData(safePreferenceName,line);
01952 return line;
01953 }
01954 else
01955 __MOUT__ << "Using default value." << std::endl;
01956
01957
01958 if(xmldoc) xmldoc->addTextElementToData(safePreferenceName,"");
01959 return "";
01960 }
01961
01962
01963
01964 void WebUsers::changeSettingsForUser (uint64_t uid, const std::string &bgcolor, const std::string &dbcolor,
01965 const std::string &wincolor, const std::string &layout, const std::string &syslayout)
01966 {
01967 uint8_t p = getPermissionsForUser(uid);
01968 if(!p) return;
01969
01970 uint64_t userIndex = searchUsersDatabaseForUserId(uid);
01971 __MOUT__ << "Changing settings for user: " << UsersUsernameVector[userIndex] << std::endl;
01972
01973 std::string fn = (std::string)WEB_LOGIN_DB_PATH + (std::string)USERS_PREFERENCES_PATH + UsersUsernameVector[userIndex] + "." + (std::string)USERS_PREFERENCES_FILETYPE;
01974
01975 __MOUT__ << "Preferences file: " << fn << std::endl;
01976
01977 HttpXmlDocument prefXml;
01978 prefXml.addTextElementToData(PREF_XML_BGCOLOR_FIELD,bgcolor);
01979 prefXml.addTextElementToData(PREF_XML_DBCOLOR_FIELD,dbcolor);
01980 prefXml.addTextElementToData(PREF_XML_WINCOLOR_FIELD,wincolor);
01981 prefXml.addTextElementToData(PREF_XML_LAYOUT_FIELD,layout);
01982
01983 prefXml.saveXmlDocument(fn);
01984
01985
01986 if(p < 255) return;
01987
01988
01989 fn = (std::string)WEB_LOGIN_DB_PATH + (std::string)USERS_PREFERENCES_PATH +
01990 (std::string)SYSTEM_PREFERENCES_PREFIX + "." + (std::string)USERS_PREFERENCES_FILETYPE;
01991
01992 HttpXmlDocument sysPrefXml;
01993 sysPrefXml.addTextElementToData(PREF_XML_SYSLAYOUT_FIELD,syslayout);
01994
01995 sysPrefXml.saveXmlDocument(fn);
01996
01997 }
01998
01999
02000
02001
02002
02003
02004 bool WebUsers::setUserWithLock(uint64_t uid_master, bool lock, std::string username)
02005 {
02006 uint8_t p = getPermissionsForUser(uid_master);
02007
02008 __MOUT__ << "permissions " << (int)p << std::endl;
02009 __MOUT__ << "usersUsernameWithLock_ " << usersUsernameWithLock_ << std::endl;
02010 __MOUT__ << "lock " << lock << std::endl;
02011 __MOUT__ << "username " << username << std::endl;
02012 __MOUT__ << "isUsernameActive(username) " << isUsernameActive(username) << std::endl;
02013
02014 if(p != (uint8_t)-1) return false;
02015
02016 if(lock && (isUsernameActive(username) || !CareAboutCookieCodes_))
02017 {
02018 if(!CareAboutCookieCodes_ && username != DEFAULT_ADMIN_USERNAME)
02019 {
02020 __MOUT__ << "User tried to lock for a user other than admin in wiz mode. Not allowed." << std::endl;
02021 return false;
02022 }
02023 usersUsernameWithLock_ = username;
02024 }
02025 else if(!lock && usersUsernameWithLock_ == username)
02026 usersUsernameWithLock_ = "";
02027 else
02028 return false;
02029
02030
02031 {
02032 std::string securityFileName = USER_WITH_LOCK_FILE;
02033 FILE *fp = fopen(securityFileName.c_str(),"w");
02034 if(!fp)
02035 {
02036 __MOUT_INFO__ << "USER_WITH_LOCK_FILE " << USER_WITH_LOCK_FILE <<
02037 " not found. Ignoring." << std::endl;
02038 }
02039 else
02040 {
02041 fprintf(fp,"%s",usersUsernameWithLock_.c_str());
02042 fclose(fp);
02043 }
02044 }
02045 return true;
02046 }
02047
02048
02049
02050 void WebUsers::modifyAccountSettings (uint64_t uid_master, uint8_t cmd_type, std::string username, std::string displayname, std::string permissions)
02051 {
02052
02053 uint8_t p = getPermissionsForUser(uid_master);
02054 if(p != (uint8_t)-1) return;
02055
02056 uint64_t modi = searchUsersDatabaseForUsername(username);
02057 if(modi == 0)
02058 {
02059 __MOUT__ << "Cannot modify first user" << std::endl;
02060 return;
02061 }
02062
02063 if(username.length() < USERNAME_LENGTH || displayname.length() < DISPLAY_NAME_LENGTH)
02064 {
02065 __MOUT__ << "Invalid Username or Display Name must be length " << USERNAME_LENGTH << " or " << DISPLAY_NAME_LENGTH << std::endl;
02066 return;
02067 }
02068
02069 int inputp;
02070 sscanf(permissions.c_str(),"%d",&inputp);
02071
02072 __MOUT__ << "Input Permissions " << inputp << std::endl;
02073
02074 switch(cmd_type)
02075 {
02076 case MOD_TYPE_UPDATE:
02077 __MOUT__ << "MOD_TYPE_UPDATE " << username << " := " << inputp << std::endl;
02078 if(modi == NOT_FOUND_IN_DATABASE)
02079 {
02080 __MOUT__ << "User not found!? Should not happen." << std::endl;
02081 return;
02082 }
02083
02084 UsersDisplayNameVector[modi] = displayname;
02085
02086
02087
02088 if(!UsersPermissionsVector[modi] && inputp)
02089 {
02090 UsersLoginFailureCountVector[modi] = 0;
02091 UsersSaltVector[modi] = "";
02092 }
02093 UsersPermissionsVector[modi] = inputp;
02094
02095
02096 {
02097 uint64_t i = searchUsersDatabaseForUserId(uid_master);
02098 if(i == NOT_FOUND_IN_DATABASE)
02099 {
02100 __MOUT__ << "Master User not found!? Should not happen." << std::endl;
02101 return;
02102 }
02103 UsersLastModifierUsernameVector[modi] = UsersUsernameVector[i];
02104 UsersLastModifiedTimeVector[modi] = time(0);
02105 }
02106 break;
02107 case MOD_TYPE_ADD:
02108 __MOUT__ << "MOD_TYPE_ADD " << username << " - " << displayname << std::endl;
02109 createNewAccount(username,displayname);
02110 break;
02111 case MOD_TYPE_DELETE:
02112 __MOUT__ << "MOD_TYPE_DELETE " << username << " - " << displayname << std::endl;
02113 deleteAccount(username,displayname);
02114 break;
02115 default:
02116 __MOUT__ << "Undefined command - do nothing " << username << std::endl;
02117 }
02118
02119 saveDatabaseToFile(DB_USERS);
02120 }
02121
02122
02123
02124 std::string WebUsers::getActiveUsersString()
02125 {
02126 std::string ret = "";
02127 uint64_t u;
02128 bool repeat;
02129 for(uint64_t i=0; i<ActiveSessionUserIdVector.size(); ++i)
02130 {
02131 repeat = false;
02132
02133 for(uint64_t j=0; j<i; ++j)
02134 if(ActiveSessionUserIdVector[i] == ActiveSessionUserIdVector[j])
02135 { repeat = true; break;}
02136
02137 if(!repeat && (u = searchUsersDatabaseForUserId(ActiveSessionUserIdVector[i])) !=
02138 NOT_FOUND_IN_DATABASE)
02139 ret += UsersDisplayNameVector[u] + ",";
02140 }
02141 if(ret.length() > 1) ret.erase(ret.length()-1);
02142 return ret;
02143 }
02144
02145
02146
02147 uint64_t WebUsers::getAdminUserID()
02148 {
02149 uint64_t uid = searchUsersDatabaseForUsername(DEFAULT_ADMIN_USERNAME);
02150 return uid;
02151 }
02152
02153
02154
02155
02156
02157 void WebUsers::loadUserWithLock()
02158 {
02159 char username[300] = "";
02160
02161 std::string securityFileName = USER_WITH_LOCK_FILE;
02162 FILE *fp = fopen(securityFileName.c_str(),"r");
02163 if(!fp)
02164 {
02165 __MOUT_INFO__ << "USER_WITH_LOCK_FILE " << USER_WITH_LOCK_FILE <<
02166 " not found. Defaulting to admin lock." << std::endl;
02167
02168
02169 sprintf(username,"%s",DEFAULT_ADMIN_USERNAME.c_str());
02170 }
02171 else
02172 {
02173 fgets(username,300,fp);
02174 username[299] = '\0';
02175 fclose(fp);
02176 }
02177
02178
02179 __MOUT__ << "Attempting to load username with lock: " << username << std::endl;
02180
02181 if(strlen(username) == 0)
02182 {
02183 __MOUT_INFO__ << "Loaded state for user-with-lock is unlocked." << std::endl;
02184 return;
02185 }
02186
02187 uint64_t i = searchUsersDatabaseForUsername(username);
02188 if(i == NOT_FOUND_IN_DATABASE)
02189 {
02190 __MOUT_INFO__ << "username " << username <<
02191 " not found in database. Ignoring." << std::endl;
02192 return;
02193 }
02194 setUserWithLock(UsersUserIdVector[i],true,username);
02195 }
02196
02197
02198
02199
02200 std::string WebUsers::getSecurity()
02201 {
02202 return securityType_;
02203 }
02204
02205
02206
02207 void WebUsers::loadSecuritySelection()
02208 {
02209 std::string securityFileName = SECURITY_FILE_NAME;
02210 FILE *fp = fopen(securityFileName.c_str(),"r");
02211 char line[100] = "";
02212 if(fp) fgets(line,100,fp);
02213 unsigned int i = 0;
02214
02215
02216 while(i<strlen(line) && line[i] >= 'A' && line[i] <= 'z') ++i;
02217 line[i] = '\0';
02218
02219
02220 if(strcmp(line,SECURITY_TYPE_NONE.c_str()) == 0 ||
02221 strcmp(line,SECURITY_TYPE_DIGEST_ACCESS.c_str()) == 0 ||
02222 strcmp(line,SECURITY_TYPE_KERBEROS.c_str()) == 0)
02223 securityType_ = line;
02224 else
02225 securityType_ = SECURITY_TYPE_DIGEST_ACCESS;
02226
02227 __MOUT__ << "The current security type is " << securityType_ << std::endl;
02228
02229 if(fp) fclose(fp);
02230
02231
02232 if(securityType_ == SECURITY_TYPE_NONE)
02233 CareAboutCookieCodes_ = false;
02234 else
02235 CareAboutCookieCodes_ = true;
02236
02237 __MOUT__ << "CareAboutCookieCodes_: " <<
02238 CareAboutCookieCodes_ << std::endl;
02239
02240 }
02241
02242
02243
02244
02245 void WebUsers::NACDisplayThread(std::string nac, std::string user)
02246 {
02247 INIT_MF("WebUsers_NAC");
02249
02250
02251
02252
02253 int i = 0;
02254 for (; i < 5; ++i)
02255 {
02256 std::this_thread::sleep_for (std::chrono::seconds(2));
02257 __MOUT__ << __COUT_HDR_P__ << "\n******************************************************************** " << std::endl;
02258 __MOUT__ << __COUT_HDR_P__ << "\n******************************************************************** " << std::endl;
02259 __MOUT__ << __COUT_HDR_P__ << "\n\nNew account code = " << nac << " for user: " << user << "\n" << std::endl;
02260 __MOUT__ << __COUT_HDR_P__ << "\n******************************************************************** " << std::endl;
02261 __MOUT__ << __COUT_HDR_P__ << "\n******************************************************************** " << std::endl;
02262 }
02263 }
02264
02265
02266
02267