1 #include "otsdaq-core/WebUsersUtilities/WebUsers.h"
2 #include "otsdaq-core/MessageFacility/MessageFacility.h"
3 #include "otsdaq-core/Macros/CoutHeaderMacros.h"
4 #include "otsdaq-core/XmlUtilities/HttpXmlDocument.h"
9 #include <openssl/sha.h>
22 #define WEB_LOGIN_BKUP_DB_PATH "bkup/"
24 #define SECURITY_FILE_NAME std::string(getenv("SERVICE_DATA_PATH")) + "/OtsWizardData/security.dat"
26 #define USERS_ACTIVE_SESSIONS_FILE USERS_DB_PATH + "/activeSessions.sv"
28 #define HASHES_DB_FILE HASHES_DB_PATH + "/hashes.xml"
29 #define USERS_DB_FILE USERS_DB_PATH + "/users.xml"
30 #define USERS_GLOBAL_HISTORY_FILE "__global"
31 #define USERS_LOGIN_HISTORY_FILETYPE "hist"
32 #define USERS_PREFERENCES_FILETYPE "pref"
33 #define SYSTEM_PREFERENCES_PREFIX "system.preset"
34 #define USER_WITH_LOCK_FILE WEB_LOGIN_DB_PATH + "/user_with_lock.dat"
36 #define HASHES_DB_GLOBAL_STRING "hashData"
37 #define HASHES_DB_ENTRY_STRING "hashEntry"
38 #define USERS_DB_GLOBAL_STRING "userData"
39 #define USERS_DB_ENTRY_STRING "userEntry"
40 #define USERS_DB_NEXT_UID_STRING "nextUserId"
43 #define PREF_XML_BGCOLOR_FIELD "pref_bgcolor" // -background color
44 #define PREF_XML_DBCOLOR_FIELD "pref_dbcolor" // -dashboard color
45 #define PREF_XML_WINCOLOR_FIELD "pref_wincolor" // -window color
46 #define PREF_XML_LAYOUT_FIELD "pref_layout" // -3 defaults window layouts(and current)
47 #define PREF_XML_SYSLAYOUT_FIELD "pref_syslayout" // -2 defaults window layouts
48 #define PREF_XML_PERMISSIONS_FIELD "desktop_user_permissions" // 0-255 permissions valud (255 is admin super user)
49 #define PREF_XML_USERLOCK_FIELD "username_with_lock" // user with lock (to lockout others)
50 #define PREF_XML_USERNAME_FIELD "pref_username" // user with lock (to lockout others)
52 #define PREF_XML_BGCOLOR_DEFAULT "rgb(0,76,151)" // -background color
53 #define PREF_XML_DBCOLOR_DEFAULT "rgb(0,40,85)" // -dashboard color
54 #define PREF_XML_WINCOLOR_DEFAULT "rgba(196,229,255,0.9)" // -window color
55 #define PREF_XML_LAYOUT_DEFAULT "0;0;0;0" // 3 default window layouts(and current)
56 #define PREF_XML_SYSLAYOUT_DEFAULT "0;0" // 2 system default window layouts
58 #define PREF_XML_ACCOUNTS_FIELD "users_accounts" // user accounts field for super users
59 #define PREF_XML_LOGIN_HISTORY_FIELD "login_entry" // login history field for user login history data
61 const std::string WebUsers::DEFAULT_ADMIN_USERNAME =
"admin";
62 const std::string WebUsers::DEFAULT_ADMIN_DISPLAY_NAME =
"Administrator";
63 const std::string WebUsers::DEFAULT_ADMIN_EMAIL =
"root@otsdaq.fnal.gov";
64 const std::string WebUsers::DEFAULT_ITERATOR_USERNAME =
"iterator";
65 const std::string WebUsers::DEFAULT_STATECHANGER_USERNAME =
"statechanger";
67 const std::string WebUsers::REQ_NO_LOGIN_RESPONSE =
"NoLogin";
68 const std::string WebUsers::REQ_NO_PERMISSION_RESPONSE =
"NoPermission";
69 const std::string WebUsers::REQ_USER_LOCKOUT_RESPONSE =
"UserLockout";
71 const std::string WebUsers::SECURITY_TYPE_NONE =
"NoSecurity";
72 const std::string WebUsers::SECURITY_TYPE_DIGEST_ACCESS =
"DigestAccessAuthentication";
75 #define __MF_SUBJECT__ "WebUsers"
83 usersUsernameWithLock_ =
"";
86 HashesDatabaseEntryFields.push_back(
"hash");
87 HashesDatabaseEntryFields.push_back(
"lastAccessTime");
89 UsersDatabaseEntryFields.push_back(
"username");
90 UsersDatabaseEntryFields.push_back(
"displayName");
91 UsersDatabaseEntryFields.push_back(
"salt");
92 UsersDatabaseEntryFields.push_back(
"uid");
93 UsersDatabaseEntryFields.push_back(
"permissions");
94 UsersDatabaseEntryFields.push_back(
"lastLoginAttemptTime");
95 UsersDatabaseEntryFields.push_back(
"accountCreatedTime");
96 UsersDatabaseEntryFields.push_back(
"loginFailureCount");
97 UsersDatabaseEntryFields.push_back(
"lastModifiedTime");
98 UsersDatabaseEntryFields.push_back(
"lastModifierUsername");
99 UsersDatabaseEntryFields.push_back(
"useremail");
102 mkdir(((std::string)WEB_LOGIN_DB_PATH).c_str(), 0755);
103 mkdir(((std::string)WEB_LOGIN_DB_PATH +
"bkup/" + USERS_DB_PATH).c_str(), 0755);
104 mkdir(((std::string)WEB_LOGIN_DB_PATH + HASHES_DB_PATH).c_str(), 0755);
105 mkdir(((std::string)WEB_LOGIN_DB_PATH + USERS_DB_PATH).c_str(), 0755);
106 mkdir(((std::string)WEB_LOGIN_DB_PATH + USERS_LOGIN_HISTORY_PATH).c_str(), 0755);
107 mkdir(((std::string)WEB_LOGIN_DB_PATH + USERS_PREFERENCES_PATH).c_str(), 0755);
110 if (!loadDatabases())
111 __COUT__ <<
"FATAL USER DATABASE ERROR - failed to load!!!" << std::endl;
113 loadSecuritySelection();
118 std::string user = DEFAULT_ADMIN_USERNAME;
119 if ((i = searchUsersDatabaseForUsername(user)) == NOT_FOUND_IN_DATABASE)
121 __SS__ <<
"user: " << user <<
" is not found" << std::endl;
122 __COUT_ERR__ << ss.str();
123 throw std::runtime_error(ss.str());
126 else if (UsersSaltVector[i] ==
"" &&
127 securityType_ == SECURITY_TYPE_DIGEST_ACCESS)
129 char charTimeStr[10];
130 sprintf(charTimeStr,
"%d",
int(UsersAccountCreatedTimeVector[i] & 0xffff));
131 std::string tmpTimeStr = charTimeStr;
136 std::thread([](std::string nac, std::string user) { WebUsers::NACDisplayThread(nac, user); },
137 tmpTimeStr, user).detach();
143 loadActiveSessions();
151 __COUT__ <<
"Done with Web Users initialization!" << std::endl;
339 void WebUsers::saveActiveSessions()
343 fn = (std::string)WEB_LOGIN_DB_PATH + (std::string)USERS_ACTIVE_SESSIONS_FILE;
344 __COUT__ << fn << std::endl;
346 FILE *fp = fopen(fn.c_str(),
"w");
349 __COUT_ERR__ <<
"Error! Persistent active sessions could not be saved." << std::endl;
354 fprintf(fp,
"%d\n", version);
355 for (
unsigned int i = 0; i < ActiveSessionCookieCodeVector.size(); ++i)
363 fprintf(fp,
"%s\n", ActiveSessionCookieCodeVector[i].c_str());
364 fprintf(fp,
"%s\n", ActiveSessionIpVector[i].c_str());
365 fprintf(fp,
"%lu\n", ActiveSessionUserIdVector[i]);
366 fprintf(fp,
"%lu\n", ActiveSessionIndex[i]);
367 fprintf(fp,
"%ld\n", ActiveSessionStartTimeVector[i]);
370 __COUT__ <<
"ActiveSessionCookieCodeVector saved with size " <<
371 ActiveSessionCookieCodeVector.size() << std::endl;
379 void WebUsers::loadActiveSessions()
383 fn = (std::string)WEB_LOGIN_DB_PATH + (std::string)USERS_ACTIVE_SESSIONS_FILE;
384 __COUT__ << fn << std::endl;
385 FILE *fp = fopen(fn.c_str(),
"r");
388 __COUT_ERR__ <<
"Error! Persistent active sessions could not be saved." << std::endl;
394 const int LINELEN = 1000;
396 fgets(line, LINELEN, fp);
397 sscanf(line,
"%d", &version);
400 __COUT__ <<
"Extracting active sessions..." << std::endl;
404 while (fgets(line, LINELEN, fp))
406 if (strlen(line)) line[strlen(line) - 1] =
'\0';
407 if (strlen(line) != COOKIE_CODE_LENGTH)
409 __COUT__ <<
"Illegal cookie code found: " << line << std::endl;
414 ActiveSessionCookieCodeVector.push_back(line);
416 fgets(line, LINELEN, fp);
417 if (strlen(line)) line[strlen(line) - 1] =
'\0';
418 ActiveSessionIpVector.push_back(line);
420 fgets(line, LINELEN, fp);
421 ActiveSessionUserIdVector.push_back(uint64_t());
422 sscanf(line,
"%lu", &(ActiveSessionUserIdVector[ActiveSessionUserIdVector.size() - 1]));
424 fgets(line, LINELEN, fp);
425 ActiveSessionIndex.push_back(uint64_t());
426 sscanf(line,
"%lu", &(ActiveSessionIndex[ActiveSessionIndex.size() - 1]));
428 fgets(line, LINELEN, fp);
429 ActiveSessionStartTimeVector.push_back(time_t());
430 sscanf(line,
"%ld", &(ActiveSessionStartTimeVector[ActiveSessionStartTimeVector.size() - 1]));
441 __COUT__ <<
"ActiveSessionCookieCodeVector loaded with size " <<
442 ActiveSessionCookieCodeVector.size() << std::endl;
447 fp = fopen(fn.c_str(),
"w");
456 bool WebUsers::loadDatabases()
460 const unsigned int LINE_LEN = 1000;
462 unsigned int i, si, c, len, f;
473 fn = (std::string)WEB_LOGIN_DB_PATH + (std::string)HASHES_DB_FILE;
474 __COUT__ << fn << std::endl;
475 fp = fopen(fn.c_str(),
"r");
478 mkdir(((std::string)WEB_LOGIN_DB_PATH + (std::string)HASHES_DB_PATH).c_str(), 0755);
479 __COUT__ << ((std::string)WEB_LOGIN_DB_PATH + (std::string)HASHES_DB_PATH).c_str() << std::endl;
480 fp = fopen(fn.c_str(), "w");
481 if (!fp) return false;
482 __COUT__ << "Hashes database created: " << fn << std::endl;
484 saveToDatabase(fp, HASHES_DB_GLOBAL_STRING, "", DB_SAVE_OPEN);
485 saveToDatabase(fp, HASHES_DB_GLOBAL_STRING, "", DB_SAVE_CLOSE);
492 while (fgets(line, LINE_LEN, fp))
494 if (strlen(line) < SHA512_DIGEST_LENGTH)
continue;
498 for (i = 0; i < len; ++i)
502 if (c != 2 && c != 4)
continue;
505 while (i < len && line[i] !=
'<') ++i;
514 HashesVector.push_back(&line[si]);
517 sscanf(&line[si],
"%lu", &tmpInt64);
518 HashesAccessTimeVector.push_back(tmpInt64);
522 __COUT__ << HashesAccessTimeVector.size() <<
" Hashes found." << std::endl;
536 fn = (std::string)WEB_LOGIN_DB_PATH + (std::string)USERS_DB_FILE;
537 fp = fopen(fn.c_str(),
"r");
540 mkdir(((std::string)WEB_LOGIN_DB_PATH + (std::string)USERS_DB_PATH).c_str(), 0755);
541 __COUT__ << ((std::string)WEB_LOGIN_DB_PATH + (std::string)USERS_DB_PATH).c_str() << std::endl;
542 fp = fopen(fn.c_str(), "w");
543 if (!fp) return false;
544 __COUT__ << "Users database created: " << fn << std::endl;
546 saveToDatabase(fp, USERS_DB_GLOBAL_STRING, "", DB_SAVE_OPEN);
548 sprintf(nidStr, "%lu", usersNextUserId_);
549 saveToDatabase(fp, USERS_DB_NEXT_UID_STRING, nidStr, DB_SAVE_OPEN_AND_CLOSE);
550 saveToDatabase(fp, USERS_DB_GLOBAL_STRING, "", DB_SAVE_CLOSE);
553 createNewAccount(DEFAULT_ADMIN_USERNAME, DEFAULT_ADMIN_DISPLAY_NAME, DEFAULT_ADMIN_EMAIL);
560 char salt[] =
"nextUserId";
561 while (fgets(line, LINE_LEN, fp))
563 if (strlen(line) < strlen(salt) * 2)
continue;
565 for (i = 0; i < strlen(salt); ++i)
566 if (line[i + 1] != salt[i])
break;
568 if (i == strlen(salt))
572 while (i < LINE_LEN && line[i] !=
'\0' && line[i] !=
'<') ++i;
574 sscanf(&line[si],
"%lu", &usersNextUserId_);
579 __COUT__ <<
"Found Users database next user Id: " << usersNextUserId_ << std::endl;
582 while (fgets(line, LINE_LEN, fp))
584 if (strlen(line) < 30)
continue;
590 __COUT__ <<
"Line buffer too small: " << len << std::endl;
596 for (i = 0; i < len; ++i)
600 if (c == 0 || c % 2 == 1)
continue;
603 while (i < len && line[i] !=
'<') ++i;
612 UsersUsernameVector.push_back(&line[si]);
614 UsersDisplayNameVector.push_back(&line[si]);
616 UsersSaltVector.push_back(&line[si]);
619 sscanf(&line[si],
"%lu", &tmpInt64);
620 UsersUserIdVector.push_back(tmpInt64);
624 sscanf(&line[si],
"%lu", &tmpInt64);
625 UsersPermissionsVector.push_back(tmpInt64);
629 sscanf(&line[si],
"%lu", &tmpInt64);
630 UsersLastLoginAttemptVector.push_back(tmpInt64);
634 sscanf(&line[si],
"%lu", &tmpInt64);
635 UsersAccountCreatedTimeVector.push_back(tmpInt64);
639 sscanf(&line[si],
"%lu", &tmpInt64);
640 UsersLoginFailureCountVector.push_back(tmpInt64);
644 sscanf(&line[si],
"%lu", &tmpInt64);
645 UsersLastModifiedTimeVector.push_back(tmpInt64);
648 UsersLastModifierUsernameVector.push_back(&line[si]);
650 UsersUserEmailVector.push_back(&line[si]);
655 if (f && f != UsersDatabaseEntryFields.size() - 1)
657 if (f != 7 && f != 9)
659 __COUT__ <<
"FATAL ERROR - invalid database found with field number " << f << std::endl;
667 __COUT__ <<
"Update database to current version - adding fields: " <<
668 (UsersDatabaseEntryFields.size() - 1 - f) << std::endl;
670 UsersLastModifiedTimeVector.push_back(0);
671 UsersLastModifierUsernameVector.push_back(
"");
675 UsersUserEmailVector.push_back(
"");
682 __COUT__ << UsersLastModifiedTimeVector.size() <<
" Users found." << std::endl;
683 for (
size_t ii = 0; ii < UsersLastModifiedTimeVector.size(); ++ii)
685 __COUT__ <<
"User " << UsersUserIdVector[ii] <<
": Name: " << UsersUsernameVector[ii] <<
"\t\tDisplay Name: " << UsersDisplayNameVector[ii] <<
"\t\tEmail: " << UsersUserEmailVector[ii] <<
"\t\tPermissions: " << std::to_string(UsersPermissionsVector[ii]) << std::endl;
692 void WebUsers::saveToDatabase(FILE * fp, std::string field, std::string value, uint8_t type,
bool addNewLine)
696 std::string newLine = addNewLine ?
"\n" :
"";
698 if (type == DB_SAVE_OPEN_AND_CLOSE)
699 fprintf(fp,
"<%s>%s</%s>%s", field.c_str(), value.c_str(), field.c_str(), newLine.c_str());
700 else if (type == DB_SAVE_OPEN)
701 fprintf(fp,
"<%s>%s%s", field.c_str(), value.c_str(), newLine.c_str());
702 else if (type == DB_SAVE_CLOSE)
703 fprintf(fp,
"</%s>%s", field.c_str(), newLine.c_str());
714 bool WebUsers::saveDatabaseToFile(uint8_t db)
716 __COUT__ <<
"Save Database: " << (int)db << std::endl;
718 std::string fn = (std::string)WEB_LOGIN_DB_PATH +
719 ((db == DB_USERS) ? (std::string)USERS_DB_FILE : (std::string)HASHES_DB_FILE);
721 __COUT__ <<
"Save Database Filename: " << fn << std::endl;
727 sprintf(dayAppend,
".%lu.bkup", time(0) / (3600 * 24));
728 std::string bkup_fn = (std::string)WEB_LOGIN_DB_PATH +
729 (std::string)WEB_LOGIN_BKUP_DB_PATH +
730 ((db == DB_USERS) ? (std::string)USERS_DB_FILE : (std::
string)HASHES_DB_FILE) +
731 (std::
string)dayAppend;
733 __COUT__ << "Backup file: " << bkup_fn << std::endl;
735 std::
string shell_command = "mv " + fn + " " + bkup_fn;
736 system(shell_command.c_str());
739 FILE *fp = fopen(fn.c_str(), "wb");
740 if (!fp) return false;
746 saveToDatabase(fp, USERS_DB_GLOBAL_STRING,
"", DB_SAVE_OPEN);
748 sprintf(fldStr,
"%lu", usersNextUserId_);
749 saveToDatabase(fp, USERS_DB_NEXT_UID_STRING, fldStr, DB_SAVE_OPEN_AND_CLOSE);
751 __COUT__ <<
"Saving " << UsersUsernameVector.size() <<
" Users." << std::endl;
753 for (uint64_t i = 0; i < UsersUsernameVector.size(); ++i)
757 saveToDatabase(fp, USERS_DB_ENTRY_STRING,
"", DB_SAVE_OPEN,
false);
759 for (
unsigned int f = 0; f < UsersDatabaseEntryFields.size(); ++f)
763 saveToDatabase(fp, UsersDatabaseEntryFields[f], UsersUsernameVector[i], DB_SAVE_OPEN_AND_CLOSE,
false);
765 saveToDatabase(fp, UsersDatabaseEntryFields[f], UsersDisplayNameVector[i], DB_SAVE_OPEN_AND_CLOSE,
false);
767 saveToDatabase(fp, UsersDatabaseEntryFields[f], UsersSaltVector[i], DB_SAVE_OPEN_AND_CLOSE,
false);
770 sprintf(fldStr,
"%lu", UsersUserIdVector[i]);
771 saveToDatabase(fp, UsersDatabaseEntryFields[f], fldStr, DB_SAVE_OPEN_AND_CLOSE,
false);
775 sprintf(fldStr,
"%d", UsersPermissionsVector[i]);
776 saveToDatabase(fp, UsersDatabaseEntryFields[f], fldStr, DB_SAVE_OPEN_AND_CLOSE,
false);
780 sprintf(fldStr,
"%lu", UsersLastLoginAttemptVector[i]);
781 saveToDatabase(fp, UsersDatabaseEntryFields[f], fldStr, DB_SAVE_OPEN_AND_CLOSE,
false);
785 sprintf(fldStr,
"%lu", UsersAccountCreatedTimeVector[i]);
786 saveToDatabase(fp, UsersDatabaseEntryFields[f], fldStr, DB_SAVE_OPEN_AND_CLOSE,
false);
790 sprintf(fldStr,
"%d", UsersLoginFailureCountVector[i]);
791 saveToDatabase(fp, UsersDatabaseEntryFields[f], fldStr, DB_SAVE_OPEN_AND_CLOSE,
false);
795 sprintf(fldStr,
"%lu", UsersLastModifiedTimeVector[i]);
796 saveToDatabase(fp, UsersDatabaseEntryFields[f], fldStr, DB_SAVE_OPEN_AND_CLOSE,
false);
799 saveToDatabase(fp, UsersDatabaseEntryFields[f], UsersLastModifierUsernameVector[i], DB_SAVE_OPEN_AND_CLOSE,
false);
801 saveToDatabase(fp, UsersDatabaseEntryFields[f], UsersUserEmailVector[i], DB_SAVE_OPEN_AND_CLOSE,
false);
804 saveToDatabase(fp, USERS_DB_ENTRY_STRING,
"", DB_SAVE_CLOSE);
807 saveToDatabase(fp, USERS_DB_GLOBAL_STRING,
"", DB_SAVE_CLOSE);
812 saveToDatabase(fp, HASHES_DB_GLOBAL_STRING,
"", DB_SAVE_OPEN);
814 __COUT__ <<
"Saving " << HashesVector.size() <<
" Hashes." << std::endl;
815 for (uint64_t i = 0; i < HashesVector.size(); ++i)
817 __COUT__ <<
"Saving " << HashesVector[i] <<
" Hashes." << std::endl;
818 saveToDatabase(fp, HASHES_DB_ENTRY_STRING,
"", DB_SAVE_OPEN,
false);
819 for (
unsigned int f = 0; f < HashesDatabaseEntryFields.size(); ++f)
822 saveToDatabase(fp, HashesDatabaseEntryFields[f], HashesVector[i], DB_SAVE_OPEN_AND_CLOSE,
false);
825 sprintf(fldStr,
"%lu", HashesAccessTimeVector[i]);
826 saveToDatabase(fp, HashesDatabaseEntryFields[f], fldStr, DB_SAVE_OPEN_AND_CLOSE,
false);
829 saveToDatabase(fp, HASHES_DB_ENTRY_STRING,
"", DB_SAVE_CLOSE);
832 saveToDatabase(fp, HASHES_DB_GLOBAL_STRING,
"", DB_SAVE_CLOSE);
847 bool WebUsers::createNewAccount(std::string Username, std::string DisplayName, std::string Email)
849 __COUT__ <<
"Creating account: " << Username << std::endl;
852 if ((i = searchUsersDatabaseForUsername(Username)) != NOT_FOUND_IN_DATABASE ||
853 Username == WebUsers::DEFAULT_ITERATOR_USERNAME ||
854 Username == WebUsers::DEFAULT_STATECHANGER_USERNAME)
856 __COUT__ <<
"Username: " << Username <<
" already exists" << std::endl;
861 UsersUsernameVector.push_back(Username);
862 UsersDisplayNameVector.push_back(DisplayName);
863 UsersUserEmailVector.push_back(Email);
864 UsersSaltVector.push_back(
"");
865 UsersPermissionsVector.push_back(UsersPermissionsVector.size() ? 1 : -1);
866 UsersUserIdVector.push_back(usersNextUserId_++);
867 if (usersNextUserId_ == (uint64_t)-1)
869 __COUT__ <<
"usersNextUserId_ wrap around!! Too many users??? Notify Admins." << std::endl;
870 usersNextUserId_ = 1;
872 UsersLastLoginAttemptVector.push_back(0);
873 UsersLoginFailureCountVector.push_back(0);
874 UsersAccountCreatedTimeVector.push_back(time(0));
875 UsersLastModifiedTimeVector.push_back(0);
876 UsersLastModifierUsernameVector.push_back(
"");
878 return saveDatabaseToFile(DB_USERS);
887 bool WebUsers::deleteAccount(std::string username, std::string displayName)
889 uint64_t i = searchUsersDatabaseForUsername(username);
890 if (i == NOT_FOUND_IN_DATABASE)
return false;
891 if (UsersDisplayNameVector[i] != displayName)
return false;
895 UsersUsernameVector.erase(UsersUsernameVector.begin() + i);
896 UsersUserEmailVector.erase(UsersUserEmailVector.begin() + i);
897 UsersDisplayNameVector.erase(UsersDisplayNameVector.begin() + i);
898 UsersSaltVector.erase(UsersSaltVector.begin() + i);
899 UsersPermissionsVector.erase(UsersPermissionsVector.begin() + i);
900 UsersUserIdVector.erase(UsersUserIdVector.begin() + i);
901 UsersLastLoginAttemptVector.erase(UsersLastLoginAttemptVector.begin() + i);
902 UsersAccountCreatedTimeVector.erase(UsersAccountCreatedTimeVector.begin() + i);
903 UsersLoginFailureCountVector.erase(UsersLoginFailureCountVector.begin() + i);
904 UsersLastModifierUsernameVector.erase(UsersLastModifierUsernameVector.begin() + i);
905 UsersLastModifiedTimeVector.erase(UsersLastModifiedTimeVector.begin() + i);
908 return saveDatabaseToFile(DB_USERS);
912 unsigned int WebUsers::hexByteStrToInt(
const char *h)
915 char hs[3] = { h[0],h[1],
'\0' };
916 sscanf(hs,
"%X", &rv);
921 void WebUsers::intToHexStr(
unsigned char i,
char *h)
923 sprintf(h,
"%2.2X", i);
935 uint64_t WebUsers::attemptActiveSession(std::string uuid, std::string &jumbledUser,
936 std::string jumbledPw, std::string &newAccountCode)
938 cleanupExpiredEntries();
940 if (!CareAboutCookieCodes_)
942 uint64_t uid = getAdminUserID();
943 jumbledUser = getUsersDisplayName(uid);
944 newAccountCode = genCookieCode();
951 if ((i = searchLoginSessionDatabaseForUUID(uuid)) == NOT_FOUND_IN_DATABASE)
953 __COUT__ <<
"uuid: " << uuid <<
" is not found" << std::endl;
954 newAccountCode =
"1";
955 return NOT_FOUND_IN_DATABASE;
957 ++LoginSessionAttemptsVector[i];
959 std::string user = dejumble(jumbledUser, LoginSessionIdVector[i]);
960 __COUT__ <<
"DejumbledUser = " << user << std::endl;
961 std::string pw = dejumble(jumbledPw, LoginSessionIdVector[i]);
964 if ((i = searchUsersDatabaseForUsername(user)) == NOT_FOUND_IN_DATABASE)
966 __COUT__ <<
"user: " << user <<
" is not found" << std::endl;
967 return NOT_FOUND_IN_DATABASE;
970 UsersLastLoginAttemptVector[i] = time(0);
971 if (!UsersPermissionsVector[i])
973 __COUT__ <<
"user: " << user <<
" account INACTIVE (could be due to failed logins)" << std::endl;
974 return NOT_FOUND_IN_DATABASE;
977 if (UsersSaltVector[i] ==
"")
979 __COUT__ <<
"First login attempt for user: " << user << std::endl;
981 char charTimeStr[10];
982 sprintf(charTimeStr,
"%d",
int(UsersAccountCreatedTimeVector[i] & 0xffff));
983 std::string tmpTimeStr = charTimeStr;
984 if (newAccountCode != tmpTimeStr)
986 __COUT__ <<
"New account code did not match: " << tmpTimeStr <<
" != " << newAccountCode << std::endl;
987 saveDatabaseToFile(DB_USERS);
988 return NOT_FOUND_IN_DATABASE;
994 while (!addToHashesDatabase(sha512(user, pw, UsersSaltVector[i])))
998 UsersSaltVector[i] =
"";
1002 __COUT__ <<
"\tHash added: " << HashesVector[HashesVector.size() - 1] << std::endl;
1006 std::string salt = UsersSaltVector[i];
1008 if (searchHashesDatabaseForHash(sha512(user, pw, salt)) == NOT_FOUND_IN_DATABASE)
1010 __COUT__ <<
"not found?" << std::endl;
1011 ++UsersLoginFailureCountVector[i];
1012 if (UsersLoginFailureCountVector[i] >= USERS_MAX_LOGIN_FAILURES)
1013 UsersPermissionsVector[i] = 0;
1015 __COUT__ <<
"\tUser/pw for user: " << user <<
" was not correct Failed Attempt #" << (int)(UsersLoginFailureCountVector[i]) << std::endl;
1016 if (!UsersPermissionsVector[i])
1017 __COUT__ <<
"Account is locked!" << std::endl;
1019 saveDatabaseToFile(DB_USERS);
1020 return NOT_FOUND_IN_DATABASE;
1024 __COUT__ <<
"Login successful for: " << user << std::endl;
1026 UsersLoginFailureCountVector[i] = 0;
1029 for (
int h = 0; h < 2; ++h)
1031 std::string fn = (std::string)WEB_LOGIN_DB_PATH + (std::string)USERS_LOGIN_HISTORY_PATH + (h ? USERS_GLOBAL_HISTORY_FILE : UsersUsernameVector[i])
1032 +
"." + (std::string)USERS_LOGIN_HISTORY_FILETYPE;
1036 if (histXml.loadXmlDocument(fn))
1038 while (histXml.getChildrenCount() + 1 > (h ? USERS_GLOBAL_HISTORY_SIZE : USERS_LOGIN_HISTORY_SIZE))
1039 histXml.removeDataElement();
1042 __COUT__ <<
"No previous login history found." << std::endl;
1047 sprintf(entryStr,
"Time=%lu Username=%s Permissions=%d UID=%lu",
1048 time(0), UsersUsernameVector[i].c_str(), UsersPermissionsVector[i], UsersUserIdVector[i]);
1050 sprintf(entryStr,
"Time=%lu DisplayName=%s Permissions=%d UID=%lu",
1051 time(0), UsersDisplayNameVector[i].c_str(), UsersPermissionsVector[i], UsersUserIdVector[i]);
1052 histXml.addTextElementToData(PREF_XML_LOGIN_HISTORY_FIELD, entryStr);
1055 histXml.saveXmlDocument(fn);
1059 saveDatabaseToFile(DB_USERS);
1060 jumbledUser = UsersDisplayNameVector[i];
1061 newAccountCode = createNewActiveSession(UsersUserIdVector[i]);
1062 return UsersUserIdVector[i];
1070 uint64_t WebUsers::attemptActiveSessionWithCert(std::string uuid, std::string &email,
1071 std::string &cookieCode, std::string& user)
1073 cleanupExpiredEntries();
1075 if (!CareAboutCookieCodes_)
1077 uint64_t uid = getAdminUserID();
1078 email = getUsersDisplayName(uid);
1079 cookieCode = genCookieCode();
1085 __COUT__ <<
"Rejecting logon with blank fingerprint" << std::endl;
1086 return NOT_FOUND_IN_DATABASE;
1092 if ((i = searchLoginSessionDatabaseForUUID(uuid)) == NOT_FOUND_IN_DATABASE)
1094 __COUT__ <<
"uuid: " << uuid <<
" is not found" << std::endl;
1096 return NOT_FOUND_IN_DATABASE;
1098 ++LoginSessionAttemptsVector[i];
1100 email = getUserEmailFromFingerprint(email);
1101 __COUT__ <<
"DejumbledEmail = " << email << std::endl;
1104 __COUT__ <<
"Rejecting logon with unknown fingerprint" << std::endl;
1105 return NOT_FOUND_IN_DATABASE;
1109 if ((i = searchUsersDatabaseForUserEmail(email)) == NOT_FOUND_IN_DATABASE)
1111 __COUT__ <<
"email: " << email <<
" is not found" << std::endl;
1112 return NOT_FOUND_IN_DATABASE;
1115 user = getUsersUsername(i);
1117 UsersLastLoginAttemptVector[i] = time(0);
1118 if (!UsersPermissionsVector[i])
1120 __COUT__ <<
"user: " << user <<
" account INACTIVE (could be due to failed logins)" << std::endl;
1121 return NOT_FOUND_IN_DATABASE;
1124 if (UsersSaltVector[i] ==
"")
1126 return NOT_FOUND_IN_DATABASE;
1129 __COUT__ <<
"Login successful for: " << user << std::endl;
1131 UsersLoginFailureCountVector[i] = 0;
1134 for (
int h = 0; h < 2; ++h)
1136 std::string fn = (std::string)WEB_LOGIN_DB_PATH + (std::string)USERS_LOGIN_HISTORY_PATH + (h ? USERS_GLOBAL_HISTORY_FILE : UsersUsernameVector[i])
1137 +
"." + (std::string)USERS_LOGIN_HISTORY_FILETYPE;
1141 if (histXml.loadXmlDocument(fn))
1143 while (histXml.getChildrenCount() + 1 > (h ? USERS_GLOBAL_HISTORY_SIZE : USERS_LOGIN_HISTORY_SIZE))
1144 histXml.removeDataElement();
1147 __COUT__ <<
"No previous login history found." << std::endl;
1152 sprintf(entryStr,
"Time=%lu Username=%s Permissions=%d UID=%lu",
1153 time(0), UsersUsernameVector[i].c_str(), UsersPermissionsVector[i], UsersUserIdVector[i]);
1155 sprintf(entryStr,
"Time=%lu DisplayName=%s Permissions=%d UID=%lu",
1156 time(0), UsersDisplayNameVector[i].c_str(), UsersPermissionsVector[i], UsersUserIdVector[i]);
1157 histXml.addTextElementToData(PREF_XML_LOGIN_HISTORY_FIELD, entryStr);
1160 histXml.saveXmlDocument(fn);
1164 saveDatabaseToFile(DB_USERS);
1165 email = UsersDisplayNameVector[i];
1166 cookieCode = createNewActiveSession(UsersUserIdVector[i]);
1167 return UsersUserIdVector[i];
1173 uint64_t WebUsers::searchActiveSessionDatabaseForCookie(std::string cookieCode)
const
1176 for (; i < ActiveSessionCookieCodeVector.size(); ++i)
1177 if (ActiveSessionCookieCodeVector[i] == cookieCode)
break;
1178 return (i == ActiveSessionCookieCodeVector.size()) ? NOT_FOUND_IN_DATABASE : i;
1185 bool WebUsers::isUsernameActive(std::string username)
const
1188 if ((u = searchUsersDatabaseForUsername(username)) == NOT_FOUND_IN_DATABASE)
return false;
1189 return isUserIdActive(UsersUserIdVector[u]);
1196 bool WebUsers::isUserIdActive(uint64_t uid)
const
1199 for (; i < ActiveSessionUserIdVector.size(); ++i)
1200 if (ActiveSessionUserIdVector[i] == uid)
return true;
1207 uint64_t WebUsers::searchUsersDatabaseForUsername(std::string username)
const
1210 for (; i < UsersUsernameVector.size(); ++i)
1211 if (UsersUsernameVector[i] == username)
break;
1212 return (i == UsersUsernameVector.size()) ? NOT_FOUND_IN_DATABASE : i;
1218 uint64_t WebUsers::searchUsersDatabaseForUserEmail(std::string useremail)
const
1221 for (; i < UsersUserEmailVector.size(); ++i)
1222 if (UsersUserEmailVector[i] == useremail)
break;
1223 return (i == UsersUserEmailVector.size()) ? NOT_FOUND_IN_DATABASE : i;
1229 uint64_t WebUsers::searchUsersDatabaseForUserId(uint64_t uid)
const
1232 for (; i < UsersUserIdVector.size(); ++i)
1233 if (UsersUserIdVector[i] == uid)
break;
1234 return (i == UsersUserIdVector.size()) ? NOT_FOUND_IN_DATABASE : i;
1240 uint64_t WebUsers::searchLoginSessionDatabaseForUUID(std::string uuid)
const
1243 for (; i < LoginSessionUUIDVector.size(); ++i)
1244 if (LoginSessionUUIDVector[i] == uuid)
break;
1245 return (i == LoginSessionUUIDVector.size()) ? NOT_FOUND_IN_DATABASE : i;
1251 uint64_t WebUsers::searchHashesDatabaseForHash(std::string hash)
1256 for (; i < HashesVector.size(); ++i)
1257 if (HashesVector[i] == hash)
break;
1261 if (i < HashesAccessTimeVector.size())
1262 HashesAccessTimeVector.push_back((time(0) + (rand() % 2 ? 1 : -1)*(rand() % 30 * 24 * 60 * 60)) & 0x0FFFFFFFFFE000000);
1265 return (i == HashesVector.size()) ? NOT_FOUND_IN_DATABASE : i;
1272 bool WebUsers::addToHashesDatabase(std::string hash)
1274 if (searchHashesDatabaseForHash(hash) != NOT_FOUND_IN_DATABASE)
1276 __COUT__ <<
"Hash collision: " << hash << std::endl;
1279 HashesVector.push_back(hash);
1280 HashesAccessTimeVector.push_back((time(0) + (rand() % 2 ? 1 : -1)*(rand() % 30 * 24 * 60 * 60)) & 0x0FFFFFFFFFE000000);
1282 return saveDatabaseToFile(DB_HASHES);
1287 std::string WebUsers::genCookieCode()
1290 std::string cc =
"";
1291 for (uint32_t i = 0; i < COOKIE_CODE_LENGTH / 2; ++i)
1293 intToHexStr(rand(), hexStr);
1301 void WebUsers::removeLoginSessionEntry(
unsigned int i)
1303 LoginSessionIdVector.erase(LoginSessionIdVector.begin() + i);
1304 LoginSessionUUIDVector.erase(LoginSessionUUIDVector.begin() + i);
1305 LoginSessionIpVector.erase(LoginSessionIpVector.begin() + i);
1306 LoginSessionStartTimeVector.erase(LoginSessionStartTimeVector.begin() + i);
1307 LoginSessionAttemptsVector.erase(LoginSessionAttemptsVector.begin() + i);
1314 std::string WebUsers::createNewActiveSession(uint64_t uid, std::string ip, uint64_t asIndex)
1316 ActiveSessionCookieCodeVector.push_back(genCookieCode());
1317 ActiveSessionIpVector.push_back(ip);
1318 ActiveSessionUserIdVector.push_back(uid);
1319 ActiveSessionStartTimeVector.push_back(time(0));
1322 ActiveSessionIndex.push_back(asIndex);
1327 for (uint64_t j = 0; j < ActiveSessionIndex.size(); ++j)
1328 if (ActiveSessionUserIdVector[j] == uid && max < ActiveSessionIndex[j])
1329 max = ActiveSessionIndex[j];
1331 ActiveSessionIndex.push_back(max ? max + 1 : 1);
1334 return ActiveSessionCookieCodeVector[ActiveSessionCookieCodeVector.size() - 1];
1339 void WebUsers::removeActiveSessionEntry(
unsigned int i)
1341 ActiveSessionCookieCodeVector.erase(ActiveSessionCookieCodeVector.begin() + i);
1342 ActiveSessionIpVector.erase(ActiveSessionIpVector.begin() + i);
1343 ActiveSessionUserIdVector.erase(ActiveSessionUserIdVector.begin() + i);
1344 ActiveSessionStartTimeVector.erase(ActiveSessionStartTimeVector.begin() + i);
1345 ActiveSessionIndex.erase(ActiveSessionIndex.begin() + i);
1371 std::string WebUsers::refreshCookieCode(
unsigned int i,
bool enableRefresh)
1374 for (uint64_t j = ActiveSessionUserIdVector.size() - 1; j != (uint64_t)-1; --j)
1375 if (ActiveSessionUserIdVector[j] == ActiveSessionUserIdVector[i] &&
1376 ActiveSessionIndex[j] == ActiveSessionIndex[i])
1381 if (enableRefresh && (time(0) - ActiveSessionStartTimeVector[j] > ACTIVE_SESSION_EXPIRATION_TIME / 2))
1384 ActiveSessionStartTimeVector[j] = time(0) - ACTIVE_SESSION_EXPIRATION_TIME +
1385 ACTIVE_SESSION_COOKIE_OVERLAP_TIME;
1388 return createNewActiveSession(ActiveSessionUserIdVector[i], ActiveSessionIpVector[i], ActiveSessionIndex[i]);
1391 return ActiveSessionCookieCodeVector[j];
1402 uint64_t WebUsers::isCookieCodeActiveForLogin(std::string uuid, std::string &cookieCode,
1403 std::string &username)
1405 if (!CareAboutCookieCodes_)
1406 return getAdminUserID();
1411 if (!ActiveSessionStartTimeVector.size())
return NOT_FOUND_IN_DATABASE;
1416 if ((i = searchLoginSessionDatabaseForUUID(uuid)) == NOT_FOUND_IN_DATABASE)
1418 __COUT__ <<
"uuid not found: " << uuid << std::endl;
1419 return NOT_FOUND_IN_DATABASE;
1422 username = dejumble(username, LoginSessionIdVector[i]);
1425 if ((i = searchActiveSessionDatabaseForCookie(cookieCode)) == NOT_FOUND_IN_DATABASE)
1427 __COUT__ <<
"Cookie code not found" << std::endl;
1428 return NOT_FOUND_IN_DATABASE;
1432 if ((j = searchUsersDatabaseForUserId(ActiveSessionUserIdVector[i])) == NOT_FOUND_IN_DATABASE)
1434 __COUT__ <<
"User ID not found" << std::endl;
1435 return NOT_FOUND_IN_DATABASE;
1439 if (UsersUsernameVector[j] != username)
1442 __COUT__ <<
"cookieCode: " << cookieCode <<
" was.." << std::endl;
1443 __COUT__ <<
"username: " << username <<
" is not found" << std::endl;
1444 return NOT_FOUND_IN_DATABASE;
1447 username = UsersDisplayNameVector[j];
1448 cookieCode = refreshCookieCode(i);
1449 return UsersUserIdVector[j];
1455 uint64_t WebUsers::getActiveSessionCountForUser(uint64_t uid)
1458 std::vector<uint64_t> uniqueAsi;
1461 for (i = 0; i < ActiveSessionUserIdVector.size(); ++i)
1462 if (ActiveSessionUserIdVector[i] == uid)
1467 for (j = 0; j < uniqueAsi.size(); ++j)
1468 if (uniqueAsi[j] == ActiveSessionIndex[i])
1470 unique =
false;
break;
1474 uniqueAsi.push_back(ActiveSessionIndex[i]);
1477 __COUT__ <<
"Found " << uniqueAsi.size() <<
" active sessions for uid " << uid << std::endl;
1479 return uniqueAsi.size();
1484 std::string WebUsers::getUsersDisplayName(uint64_t uid)
1487 if ((i = searchUsersDatabaseForUserId(uid)) == NOT_FOUND_IN_DATABASE)
return "";
1488 return UsersDisplayNameVector[i];
1493 std::string WebUsers::getUsersUsername(uint64_t uid)
1496 if ((i = searchUsersDatabaseForUserId(uid)) == NOT_FOUND_IN_DATABASE)
return "";
1497 return UsersUsernameVector[i];
1510 uint64_t WebUsers::cookieCodeLogout(std::string cookieCode,
bool logoutOtherUserSessions, uint64_t *userId, std::string ip)
1517 if ((i = searchActiveSessionDatabaseForCookie(cookieCode)) == NOT_FOUND_IN_DATABASE)
1519 __COUT__ <<
"Cookie code not found" << std::endl;
1520 return NOT_FOUND_IN_DATABASE;
1524 if (ActiveSessionIpVector[i] != ip)
1526 __COUT__ <<
"IP does not match active session" << std::endl;
1527 return NOT_FOUND_IN_DATABASE;
1536 uint64_t asi = ActiveSessionIndex[i];
1537 uint64_t uid = ActiveSessionUserIdVector[i];
1538 if (userId) *userId = uid;
1539 uint64_t logoutCount = 0;
1542 while (i < ActiveSessionIndex.size())
1544 if ((logoutOtherUserSessions && ActiveSessionUserIdVector[i] == uid &&
1545 ActiveSessionIndex[i] != asi) ||
1546 (!logoutOtherUserSessions && ActiveSessionUserIdVector[i] == uid &&
1547 ActiveSessionIndex[i] == asi))
1549 __COUT__ <<
"Logging out of active session " << ActiveSessionUserIdVector[i]
1550 <<
"-" << ActiveSessionIndex[i] << std::endl;
1551 removeActiveSessionEntry(i);
1558 __COUT__ <<
"Found and removed active session count = " << logoutCount << std::endl;
1565 bool WebUsers::getUserInfoForCookie(std::string &cookieCode,
1566 std::string *userName, std::string *displayName,
1567 uint64_t *activeSessionIndex)
1569 if (userName) *userName =
"";
1570 if (displayName) *displayName =
"";
1572 if (!CareAboutCookieCodes_)
1574 uint64_t uid = getAdminUserID();
1575 if (userName) *userName = getUsersUsername(uid);
1576 if (displayName) *displayName = getUsersDisplayName(uid);
1577 if (activeSessionIndex) *activeSessionIndex = -1;
1584 if ((i = searchActiveSessionDatabaseForCookie(cookieCode)) == NOT_FOUND_IN_DATABASE)
1586 __COUT__ <<
"cookieCode NOT_FOUND_IN_DATABASE" << std::endl;
1591 if ((j = searchUsersDatabaseForUserId(ActiveSessionUserIdVector[i])) == NOT_FOUND_IN_DATABASE)
1593 __COUT__ <<
"ActiveSessionUserIdVector NOT_FOUND_IN_DATABASE" << std::endl;
1597 if (userName) *userName = UsersUsernameVector[j];
1598 if (displayName) *displayName = UsersDisplayNameVector[j];
1599 if (activeSessionIndex) *activeSessionIndex = ActiveSessionIndex[i];
1614 bool WebUsers::cookieCodeIsActiveForRequest(std::string &cookieCode,
1615 uint8_t *userPermissions, uint64_t *uid, std::string ip,
1616 bool refresh, std::string *userWithLock)
1619 cleanupExpiredEntries();
1626 if (!CareAboutCookieCodes_)
1628 if (userPermissions) *userPermissions = -1;
1629 if (uid) *uid = getAdminUserID();
1630 if (userWithLock) *userWithLock = usersUsernameWithLock_;
1632 if(cookieCode.size() != COOKIE_CODE_LENGTH)
1633 cookieCode = genCookieCode();
1640 if ((i = searchActiveSessionDatabaseForCookie(cookieCode)) == NOT_FOUND_IN_DATABASE)
1642 __COUT__ <<
"Cookie code not found" << std::endl;
1643 cookieCode = REQ_NO_LOGIN_RESPONSE;
1648 if (ActiveSessionIpVector[i] != ip)
1650 __COUT__ <<
"IP does not match active session" << std::endl;
1651 cookieCode = REQ_NO_LOGIN_RESPONSE;
1656 if ((j = searchUsersDatabaseForUserId(ActiveSessionUserIdVector[i])) == NOT_FOUND_IN_DATABASE)
1658 __COUT__ <<
"User ID not found" << std::endl;
1659 cookieCode = REQ_NO_LOGIN_RESPONSE;
1663 uint8_t tmpPerm = getPermissionsForUser(UsersUserIdVector[j]);
1667 cookieCode = REQ_NO_PERMISSION_RESPONSE;
1672 if (userPermissions) *userPermissions = tmpPerm;
1673 if (uid) *uid = UsersUserIdVector[j];
1674 if (userWithLock) *userWithLock = usersUsernameWithLock_;
1676 cookieCode = refreshCookieCode(i, refresh);
1687 void WebUsers::cleanupExpiredEntries(std::vector<std::string> *loggedOutUsernames)
1692 if (loggedOutUsernames)
1694 for (i = 0; i < UsersLoggedOutUsernames_.size(); ++i)
1695 loggedOutUsernames->push_back(UsersLoggedOutUsernames_[i]);
1696 UsersLoggedOutUsernames_.clear();
1702 for (i = 0; i < LoginSessionStartTimeVector.size(); ++i)
1703 if (LoginSessionStartTimeVector[i] + LOGIN_SESSION_EXPIRATION_TIME < time(0) ||
1704 LoginSessionAttemptsVector[i] > LOGIN_SESSION_ATTEMPTS_MAX)
1709 removeLoginSessionEntry(i);
1722 for (i = 0; i < ActiveSessionStartTimeVector.size(); ++i)
1723 if (ActiveSessionStartTimeVector[i] + ACTIVE_SESSION_EXPIRATION_TIME <= time(0))
1730 tmpUid = ActiveSessionUserIdVector[i];
1731 removeActiveSessionEntry(i);
1735 if (!isUserIdActive(tmpUid))
1737 if (loggedOutUsernames)
1738 loggedOutUsernames->push_back(UsersUsernameVector[searchUsersDatabaseForUserId(tmpUid)]);
1740 UsersLoggedOutUsernames_.push_back(UsersUsernameVector[searchUsersDatabaseForUserId(tmpUid)]);
1757 if (CareAboutCookieCodes_ && !isUsernameActive(usersUsernameWithLock_))
1758 usersUsernameWithLock_ =
"";
1768 std::string WebUsers::createNewLoginSession(std::string UUID, std::string ip)
1770 __COUT__ <<
"UUID: " << UUID << std::endl << std::endl;
1772 for (; i < LoginSessionUUIDVector.size(); ++i)
1773 if (LoginSessionUUIDVector[i] == UUID)
break;
1775 if (i != LoginSessionUUIDVector.size())
1777 __COUT__ <<
"UUID: " << UUID <<
" is not unique" << std::endl;
1782 LoginSessionUUIDVector.push_back(UUID);
1786 std::string sid =
"";
1787 for (i = 0; i < SESSION_ID_LENGTH / 2; ++i)
1789 intToHexStr(rand(), hexStr);
1792 LoginSessionIdVector.push_back(sid);
1793 LoginSessionIpVector.push_back(
"");
1794 LoginSessionStartTimeVector.push_back(time(0));
1795 LoginSessionAttemptsVector.push_back(0);
1807 std::string WebUsers::sha512(std::string user, std::string password, std::string &salt)
1809 SHA512_CTX sha512_context;
1814 SHA512_Init(&sha512_context);
1816 for (
unsigned int i = 0; i < 8; ++i)
1817 sha512_context.h[i] += rand();
1819 for (
unsigned int i = 0; i <
sizeof(SHA512_CTX); ++i)
1821 intToHexStr((uint8_t)(((uint8_t *)(&sha512_context))[i]), hexStr);
1823 salt.append(hexStr);
1832 for (
unsigned int i = 0; i <
sizeof(SHA512_CTX); ++i)
1833 ((uint8_t *)(&sha512_context))[i] = hexByteStrToInt(&(salt.c_str()[i * 2]));
1836 std::string strToHash = salt + user + password;
1839 unsigned char hash[SHA512_DIGEST_LENGTH];
1841 char retHash[SHA512_DIGEST_LENGTH * 2 + 1];
1846 SHA512_Update(&sha512_context, strToHash.c_str(), strToHash.length());
1848 SHA512_Final(hash, &sha512_context);
1852 for (i = 0; i < SHA512_DIGEST_LENGTH; i++)
1853 sprintf(retHash + (i * 2),
"%02x", hash[i]);
1856 retHash[SHA512_DIGEST_LENGTH * 2] =
'\0';
1870 std::string WebUsers::dejumble(std::string u, std::string s)
1873 if (s.length() != SESSION_ID_LENGTH)
return "";
1875 const int ss = s.length() / 2;
1876 int p = hexByteStrToInt(&(s.c_str()[0])) % ss;
1877 int n = hexByteStrToInt(&(s.c_str()[p * 2])) % ss;
1878 int len = (hexByteStrToInt(&(u.c_str()[p * 2])) - p - n + ss * 3) % ss;
1880 std::vector<bool> x(ss);
1881 for (
int i = 0; i < ss; ++i) x[i] = 0;
1884 int c = hexByteStrToInt(&(u.c_str()[p * 2]));
1886 std::string user =
"";
1888 for (
int l = 0; l < len; ++l)
1890 p = (p + hexByteStrToInt(&(s.c_str()[p * 2]))) % ss;
1891 while (x[p]) p = (p + 1) % ss;
1893 n = hexByteStrToInt(&(s.c_str()[p * 2]));
1894 user.append(1, (hexByteStrToInt(&(u.c_str()[p * 2])) - c - n + ss * 4) % ss);
1895 c = hexByteStrToInt(&(u.c_str()[p * 2]));
1904 uint8_t WebUsers::getPermissionsForUser(uint64_t uid)
1906 uint64_t userIndex = searchUsersDatabaseForUserId(uid);
1907 return (userIndex < UsersPermissionsVector.size()) ? UsersPermissionsVector[userIndex] : 0;
1914 std::string WebUsers::getTooltipFilename(
1915 const std::string& username,
const std::string &srcFile,
1916 const std::string &srcFunc,
const std::string &srcId)
1918 std::string filename = (std::string)WEB_LOGIN_DB_PATH + TOOLTIP_DB_PATH +
"/";
1922 mkdir(((std::string)WEB_LOGIN_DB_PATH).c_str(), 0755);
1923 mkdir(((std::string)WEB_LOGIN_DB_PATH + USERS_DB_PATH).c_str(), 0755);
1924 mkdir(filename.c_str(), 0755);
1926 for (
const char& c : username)
1928 (c >=
'a' && c <=
'z') ||
1929 (c >=
'A' && c <=
'Z') ||
1930 (c >=
'0' && c <=
'9'))
1935 mkdir(filename.c_str(), 0755);
1937 for (
const char& c : srcFile)
1939 (c >=
'a' && c <=
'z') ||
1940 (c >=
'A' && c <=
'Z') ||
1941 (c >=
'0' && c <=
'9'))
1944 for (
const char& c : srcFunc)
1946 (c >=
'a' && c <=
'z') ||
1947 (c >=
'A' && c <=
'Z') ||
1948 (c >=
'0' && c <=
'9'))
1951 for (
const char& c : srcId)
1953 (c >=
'a' && c <=
'z') ||
1954 (c >=
'A' && c <=
'Z') ||
1955 (c >=
'0' && c <=
'9'))
1958 __COUT__ <<
"filename " << filename << std::endl;
1962 std::string ots::WebUsers::getUserEmailFromFingerprint(std::string fingerprint)
1964 std::ifstream f(WEB_LOGIN_CERTDATA_PATH);
1971 certFingerprints_[email] = fp;
1973 remove(WEB_LOGIN_CERTDATA_PATH.c_str());
1976 for (
auto fp : certFingerprints_)
1978 if (fp.second == fingerprint)
return fp.first;
1986 void WebUsers::tooltipSetNeverShowForUsername(
const std::string& username,
1988 const std::string &srcFile,
const std::string &srcFunc,
1989 const std::string &srcId,
bool doNeverShow,
bool temporarySilence)
1992 __COUT__ <<
"Setting tooltip never show for user: " << username <<
1993 " to " << doNeverShow <<
" (temporarySilence=" <<
1994 temporarySilence <<
")" << std::endl;
1997 std::string filename = getTooltipFilename(username, srcFile, srcFunc, srcId);
1998 FILE *fp = fopen(filename.c_str(),
"w");
2001 if (temporarySilence)
2002 fprintf(fp,
"%ld", time(0) + 60 * 60);
2004 fputc(doNeverShow ?
'1' :
'0', fp);
2008 __COUT_ERR__ <<
"Big problme with tooltips! File not accessible: " << filename << std::endl;
2018 void WebUsers::tooltipCheckForUsername(
const std::string& username,
2020 const std::string &srcFile,
const std::string &srcFunc,
2021 const std::string &srcId)
2023 if (srcId ==
"ALWAYS")
2026 xmldoc->addTextElementToData(
"ShowTooltip",
"1");
2034 __COUT__ <<
"Checking tooltip for user: " << username << std::endl;
2038 std::string filename = getTooltipFilename(username, srcFile, srcFunc, srcId);
2039 FILE *fp = fopen(filename.c_str(),
"r");
2044 fgets(line, 100, fp);
2046 sscanf(line,
"%ld", &val);
2047 __COUT__ <<
"tooltip value read = " << val << std::endl;
2052 xmldoc->addTextElementToData(
"ShowTooltip", val == 1 ?
"0" :
2053 (time(0) > val ?
"1" :
"0"));
2056 xmldoc->addTextElementToData(
"ShowTooltip",
"1");
2061 void WebUsers::resetAllUserTooltips(
const std::string &userNeedle)
2063 std::system((
"rm -rf " + (std::string)WEB_LOGIN_DB_PATH + TOOLTIP_DB_PATH +
2064 "/" + userNeedle).c_str());
2065 __COUT__ <<
"Successfully reset Tooltips for user " << userNeedle << std::endl;
2086 void WebUsers::insertSettingsForUser(uint64_t uid,
HttpXmlDocument *xmldoc,
bool includeAccounts)
2088 uint8_t p = getPermissionsForUser(uid);
2091 uint64_t userIndex = searchUsersDatabaseForUserId(uid);
2092 __COUT__ <<
"Gettings settings for user: " << UsersUsernameVector[userIndex] << std::endl;
2094 std::string fn = (std::string)WEB_LOGIN_DB_PATH + (std::string)USERS_PREFERENCES_PATH + UsersUsernameVector[userIndex] +
"." + (std::string)USERS_PREFERENCES_FILETYPE;
2098 __COUT__ <<
"Preferences file: " << fn << std::endl;
2100 if (!prefXml.loadXmlDocument(fn))
2102 __COUT__ <<
"Preferences are defaults." << std::endl;
2104 xmldoc->addTextElementToData(PREF_XML_BGCOLOR_FIELD, PREF_XML_BGCOLOR_DEFAULT);
2105 xmldoc->addTextElementToData(PREF_XML_DBCOLOR_FIELD, PREF_XML_DBCOLOR_DEFAULT);
2106 xmldoc->addTextElementToData(PREF_XML_WINCOLOR_FIELD, PREF_XML_WINCOLOR_DEFAULT);
2107 xmldoc->addTextElementToData(PREF_XML_LAYOUT_FIELD, PREF_XML_LAYOUT_DEFAULT);
2111 __COUT__ <<
"Saved Preferences found." << std::endl;
2112 xmldoc->copyDataChildren(prefXml);
2118 if (includeAccounts && p == (uint8_t)-1)
2121 __COUT__ <<
"Super User on our hands" << std::endl;
2123 xmldoc->addTextElementToData(PREF_XML_ACCOUNTS_FIELD,
"");
2127 for (uint64_t i = 0; i < UsersUsernameVector.size(); ++i)
2129 xmldoc->addTextElementToParent(
"username", UsersUsernameVector[i], PREF_XML_ACCOUNTS_FIELD);
2130 xmldoc->addTextElementToParent(
"display_name", UsersDisplayNameVector[i], PREF_XML_ACCOUNTS_FIELD);
2131 if (UsersUserEmailVector.size() > i)
2133 xmldoc->addTextElementToParent(
"useremail", UsersUserEmailVector[i], PREF_XML_ACCOUNTS_FIELD);
2137 xmldoc->addTextElementToParent(
"useremail",
"", PREF_XML_ACCOUNTS_FIELD);
2140 sprintf(permStr,
"%d", UsersPermissionsVector[i]);
2141 xmldoc->addTextElementToParent(
"permissions", permStr, PREF_XML_ACCOUNTS_FIELD);
2142 if (UsersSaltVector[i] ==
"")
2143 sprintf(permStr,
"%d",
int(UsersAccountCreatedTimeVector[i] & 0xffff));
2146 xmldoc->addTextElementToParent(
"nac", permStr, PREF_XML_ACCOUNTS_FIELD);
2151 fn = (std::string)WEB_LOGIN_DB_PATH + (std::string)USERS_PREFERENCES_PATH +
2152 (std::string)SYSTEM_PREFERENCES_PREFIX +
"." + (std::string)USERS_PREFERENCES_FILETYPE;
2153 if (!prefXml.loadXmlDocument(fn))
2155 __COUT__ <<
"System Preferences are defaults." << std::endl;
2157 xmldoc->addTextElementToData(PREF_XML_SYSLAYOUT_FIELD, PREF_XML_SYSLAYOUT_DEFAULT);
2161 __COUT__ <<
"Saved System Preferences found." << std::endl;
2162 xmldoc->copyDataChildren(prefXml);
2166 sprintf(permStr,
"%d", p);
2167 xmldoc->addTextElementToData(PREF_XML_PERMISSIONS_FIELD, permStr);
2170 xmldoc->addTextElementToData(PREF_XML_USERLOCK_FIELD, usersUsernameWithLock_);
2172 xmldoc->addTextElementToData(PREF_XML_USERNAME_FIELD, getUsersUsername(uid));
2178 void WebUsers::setGenericPreference(uint64_t uid,
const std::string &preferenceName,
2179 const std::string &preferenceValue)
2181 uint64_t userIndex = searchUsersDatabaseForUserId(uid);
2185 std::string safePreferenceName =
"";
2186 for (
const auto &c : preferenceName)
2187 if ((c >=
'a' && c <=
'z') ||
2188 (c >=
'A' && c <=
'Z') ||
2189 (c >=
'0' && c <=
'9') ||
2190 (c >=
'-' || c <=
'_'))
2191 safePreferenceName += c;
2193 std::string dir = (std::string)WEB_LOGIN_DB_PATH + (std::string)USERS_PREFERENCES_PATH +
2194 "generic_" + safePreferenceName +
"/";
2197 mkdir(dir.c_str(), 0755);
2199 std::string fn = UsersUsernameVector[userIndex] +
"_" + safePreferenceName +
2200 "." + (std::string)USERS_PREFERENCES_FILETYPE;
2202 __COUT__ <<
"Preferences file: " << (dir + fn) << std::endl;
2204 FILE *fp = fopen((dir + fn).c_str(),
"w");
2207 fprintf(fp,
"%s", preferenceValue.c_str());
2211 __COUT_ERR__ <<
"Preferences file could not be opened for writing!" << std::endl;
2218 std::string WebUsers::getGenericPreference(uint64_t uid,
const std::string &preferenceName,
2221 uint64_t userIndex = searchUsersDatabaseForUserId(uid);
2225 std::string safePreferenceName =
"";
2226 for (
const auto &c : preferenceName)
2227 if ((c >=
'a' && c <=
'z') ||
2228 (c >=
'A' && c <=
'Z') ||
2229 (c >=
'0' && c <=
'9') ||
2230 (c >=
'-' || c <=
'_'))
2231 safePreferenceName += c;
2233 std::string dir = (std::string)WEB_LOGIN_DB_PATH + (std::string)USERS_PREFERENCES_PATH +
2234 "generic_" + safePreferenceName +
"/";
2236 std::string fn = UsersUsernameVector[userIndex] +
"_" + safePreferenceName +
2237 "." + (std::string)USERS_PREFERENCES_FILETYPE;
2239 __COUT__ <<
"Preferences file: " << (dir + fn) << std::endl;
2242 FILE *fp = fopen((dir + fn).c_str(),
"rb");
2245 fseek(fp, 0, SEEK_END);
2246 long size = ftell(fp);
2248 line.reserve(size + 1);
2250 fgets(&line[0], size + 1, fp);
2253 __COUT__ <<
"Read value " << line << std::endl;
2254 if (xmldoc) xmldoc->addTextElementToData(safePreferenceName, line);
2258 __COUT__ <<
"Using default value." << std::endl;
2261 if (xmldoc) xmldoc->addTextElementToData(safePreferenceName,
"");
2267 void WebUsers::changeSettingsForUser(uint64_t uid,
const std::string &bgcolor,
const std::string &dbcolor,
2268 const std::string &wincolor,
const std::string &layout,
const std::string &syslayout)
2270 uint8_t p = getPermissionsForUser(uid);
2273 uint64_t userIndex = searchUsersDatabaseForUserId(uid);
2274 __COUT__ <<
"Changing settings for user: " << UsersUsernameVector[userIndex] << std::endl;
2276 std::string fn = (std::string)WEB_LOGIN_DB_PATH + (std::string)USERS_PREFERENCES_PATH + UsersUsernameVector[userIndex] +
"." + (std::string)USERS_PREFERENCES_FILETYPE;
2278 __COUT__ <<
"Preferences file: " << fn << std::endl;
2281 prefXml.addTextElementToData(PREF_XML_BGCOLOR_FIELD, bgcolor);
2282 prefXml.addTextElementToData(PREF_XML_DBCOLOR_FIELD, dbcolor);
2283 prefXml.addTextElementToData(PREF_XML_WINCOLOR_FIELD, wincolor);
2284 prefXml.addTextElementToData(PREF_XML_LAYOUT_FIELD, layout);
2286 prefXml.saveXmlDocument(fn);
2289 if (p < 255)
return;
2292 fn = (std::string)WEB_LOGIN_DB_PATH + (std::string)USERS_PREFERENCES_PATH +
2293 (std::string)SYSTEM_PREFERENCES_PREFIX +
"." + (std::string)USERS_PREFERENCES_FILETYPE;
2296 sysPrefXml.addTextElementToData(PREF_XML_SYSLAYOUT_FIELD, syslayout);
2298 sysPrefXml.saveXmlDocument(fn);
2307 bool WebUsers::setUserWithLock(uint64_t uid_master,
bool lock, std::
string username)
2309 uint8_t p = getPermissionsForUser(uid_master);
2311 __COUT__ <<
"permissions " << (int)p << std::endl;
2312 __COUT__ <<
"usersUsernameWithLock_ " << usersUsernameWithLock_ << std::endl;
2313 __COUT__ <<
"lock " << lock << std::endl;
2314 __COUT__ <<
"username " << username << std::endl;
2315 __COUT__ <<
"isUsernameActive(username) " << isUsernameActive(username) << std::endl;
2317 if (p != (uint8_t)-1)
return false;
2320 if (lock && (isUsernameActive(username) || !CareAboutCookieCodes_))
2322 if (!CareAboutCookieCodes_ && username != DEFAULT_ADMIN_USERNAME)
2324 __COUT__ <<
"User tried to lock for a user other than admin in wiz mode. Not allowed." << std::endl;
2327 usersUsernameWithLock_ = username;
2329 else if (!lock && usersUsernameWithLock_ == username)
2330 usersUsernameWithLock_ =
"";
2333 if (!isUsernameActive(username))
2334 __COUT__ <<
"User is inactive." << std::endl;
2335 __MOUT_WARN__ <<
"Failed to lock for user '" << username <<
".'" << std::endl;
2339 __MOUT_INFO__ <<
"User '" << username <<
"' has locked out the system!" << std::endl;
2343 std::string securityFileName = USER_WITH_LOCK_FILE;
2344 FILE *fp = fopen(securityFileName.c_str(),
"w");
2347 __COUT_INFO__ <<
"USER_WITH_LOCK_FILE " << USER_WITH_LOCK_FILE <<
2348 " not found. Ignoring." << std::endl;
2352 fprintf(fp,
"%s", usersUsernameWithLock_.c_str());
2361 void WebUsers::modifyAccountSettings(uint64_t uid_master, uint8_t cmd_type, std::string username, std::string displayname, std::string email, std::string permissions)
2364 uint8_t p = getPermissionsForUser(uid_master);
2365 if (p != (uint8_t)-1)
return;
2367 uint64_t modi = searchUsersDatabaseForUsername(username);
2370 __COUT__ <<
"Cannot modify first user" << std::endl;
2374 if (username.length() < USERNAME_LENGTH || displayname.length() < DISPLAY_NAME_LENGTH)
2376 __COUT__ <<
"Invalid Username or Display Name must be length " << USERNAME_LENGTH <<
" or " << DISPLAY_NAME_LENGTH << std::endl;
2381 sscanf(permissions.c_str(),
"%d", &inputp);
2383 __COUT__ <<
"Input Permissions " << inputp << std::endl;
2387 case MOD_TYPE_UPDATE:
2388 __COUT__ <<
"MOD_TYPE_UPDATE " << username <<
" := " << inputp << std::endl;
2389 if (modi == NOT_FOUND_IN_DATABASE)
2391 __COUT__ <<
"User not found!? Should not happen." << std::endl;
2395 UsersDisplayNameVector[modi] = displayname;
2396 UsersUserEmailVector[modi] = email;
2400 if (!UsersPermissionsVector[modi] && inputp)
2402 UsersLoginFailureCountVector[modi] = 0;
2403 UsersSaltVector[modi] =
"";
2405 UsersPermissionsVector[modi] = inputp;
2409 uint64_t i = searchUsersDatabaseForUserId(uid_master);
2410 if (i == NOT_FOUND_IN_DATABASE)
2412 __COUT__ <<
"Master User not found!? Should not happen." << std::endl;
2415 UsersLastModifierUsernameVector[modi] = UsersUsernameVector[i];
2416 UsersLastModifiedTimeVector[modi] = time(0);
2420 __COUT__ <<
"MOD_TYPE_ADD " << username <<
" - " << displayname << std::endl;
2421 createNewAccount(username, displayname, email);
2423 case MOD_TYPE_DELETE:
2424 __COUT__ <<
"MOD_TYPE_DELETE " << username <<
" - " << displayname << std::endl;
2425 deleteAccount(username, displayname);
2428 __COUT__ <<
"Undefined command - do nothing " << username << std::endl;
2431 saveDatabaseToFile(DB_USERS);
2436 std::string WebUsers::getActiveUsersString()
2438 std::string ret =
"";
2441 for (uint64_t i = 0; i < ActiveSessionUserIdVector.size(); ++i)
2445 for (uint64_t j = 0; j < i; ++j)
2446 if (ActiveSessionUserIdVector[i] == ActiveSessionUserIdVector[j])
2448 repeat =
true;
break;
2451 if (!repeat && (u = searchUsersDatabaseForUserId(ActiveSessionUserIdVector[i])) !=
2452 NOT_FOUND_IN_DATABASE)
2453 ret += UsersDisplayNameVector[u] +
",";
2455 if (ret.length() > 1) ret.erase(ret.length() - 1);
2461 uint64_t WebUsers::getAdminUserID()
2463 uint64_t uid = searchUsersDatabaseForUsername(DEFAULT_ADMIN_USERNAME);
2471 void WebUsers::loadUserWithLock()
2473 char username[300] =
"";
2475 std::string securityFileName = USER_WITH_LOCK_FILE;
2476 FILE *fp = fopen(securityFileName.c_str(),
"r");
2479 __COUT_INFO__ <<
"USER_WITH_LOCK_FILE " << USER_WITH_LOCK_FILE <<
2480 " not found. Defaulting to admin lock." << std::endl;
2483 sprintf(username,
"%s", DEFAULT_ADMIN_USERNAME.c_str());
2487 fgets(username, 300, fp);
2488 username[299] =
'\0';
2493 __COUT__ <<
"Attempting to load username with lock: " << username << std::endl;
2495 if (strlen(username) == 0)
2497 __COUT_INFO__ <<
"Loaded state for user-with-lock is unlocked." << std::endl;
2501 uint64_t i = searchUsersDatabaseForUsername(username);
2502 if (i == NOT_FOUND_IN_DATABASE)
2504 __COUT_INFO__ <<
"username " << username <<
2505 " not found in database. Ignoring." << std::endl;
2508 __COUT__ <<
"Setting lock" << std::endl;
2509 setUserWithLock(UsersUserIdVector[i],
true, username);
2515 std::string WebUsers::getSecurity()
2517 return securityType_;
2522 void WebUsers::loadSecuritySelection()
2524 std::string securityFileName = SECURITY_FILE_NAME;
2525 FILE *fp = fopen(securityFileName.c_str(),
"r");
2526 char line[100] =
"";
2527 if (fp) fgets(line, 100, fp);
2531 while (i < strlen(line) && line[i] >=
'A' && line[i] <=
'z') ++i;
2535 if (strcmp(line, SECURITY_TYPE_NONE.c_str()) == 0 ||
2536 strcmp(line, SECURITY_TYPE_DIGEST_ACCESS.c_str()) == 0)
2537 securityType_ = line;
2539 securityType_ = SECURITY_TYPE_DIGEST_ACCESS;
2541 __COUT__ <<
"The current security type is " << securityType_ << std::endl;
2546 if (securityType_ == SECURITY_TYPE_NONE)
2547 CareAboutCookieCodes_ =
false;
2549 CareAboutCookieCodes_ =
true;
2551 __COUT__ <<
"CareAboutCookieCodes_: " <<
2552 CareAboutCookieCodes_ << std::endl;
2559 void WebUsers::NACDisplayThread(std::string nac, std::string user)
2561 INIT_MF(
"WebUsers_NAC");
2570 std::this_thread::sleep_for(std::chrono::seconds(2));
2571 __COUT__ << __COUT_HDR_P__ <<
"\n******************************************************************** " << std::endl;
2572 __COUT__ << __COUT_HDR_P__ <<
"\n******************************************************************** " << std::endl;
2573 __COUT__ << __COUT_HDR_P__ <<
"\n\nNew account code = " << nac <<
" for user: " << user <<
"\n" << std::endl;
2574 __COUT__ << __COUT_HDR_P__ <<
"\n******************************************************************** " << std::endl;
2575 __COUT__ << __COUT_HDR_P__ <<
"\n******************************************************************** " << std::endl;
2580 void WebUsers::deleteUserData()
2583 std::system((
"rm -rf " + (std::string)WEB_LOGIN_DB_PATH + HASHES_DB_PATH +
"/*").c_str());
2584 std::system((
"rm -rf " + (std::string)WEB_LOGIN_DB_PATH + USERS_DB_PATH +
"/*").c_str());
2585 std::system((
"rm -rf " + (std::string)WEB_LOGIN_DB_PATH + USERS_LOGIN_HISTORY_PATH +
"/*").c_str());
2586 std::system((
"rm -rf " + (std::string)WEB_LOGIN_DB_PATH + USERS_PREFERENCES_PATH +
"/*").c_str());
2587 std::system((
"rm -rf " + (std::string)WEB_LOGIN_DB_PATH + TOOLTIP_DB_PATH).c_str());
2589 std::string serviceDataPath = getenv(
"SERVICE_DATA_PATH");
2591 std::system((
"rm -rf " + std::string(serviceDataPath) +
"/MacroData/").c_str());
2592 std::system((
"rm -rf " + std::string(serviceDataPath) +
"/MacroHistory/").c_str());
2593 std::system((
"rm -rf " + std::string(serviceDataPath) +
"/MacroExport/").c_str());
2596 std::system((
"rm -rf " + std::string(serviceDataPath) +
"/ConsolePreferences/").c_str());
2599 std::system((
"rm -rf " + std::string(serviceDataPath) +
"/OtsWizardData/").c_str());
2602 std::system((
"rm -rf " + std::string(serviceDataPath) +
"/ProgressBarData/").c_str());
2605 std::system((
"rm -rf " + std::string(serviceDataPath) +
"/RunNumber/").c_str());
2606 std::system((
"rm -rf " + std::string(serviceDataPath) +
"/RunControlData/").c_str());
2609 std::system((
"rm -rf " + std::string(serviceDataPath) +
"/VisualizerData/").c_str());
2612 std::system((
"rm -rf " + std::string(serviceDataPath) +
"/ActiveConfigurationGroups.cfg").c_str());
2615 std::system((
"rm -rf " + std::string(getenv(
"LOGBOOK_DATA_PATH")) +
"/").c_str());
2617 std::cout << __COUT_HDR_FL__ <<
"$$$$$$$$$$$$$$ Successfully deleted ALL service user data $$$$$$$$$$$$" << std::endl;