1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
|
/*
* ========================================================
*
* NeKernel
* Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
*
* File: UserMgr.cc
* Purpose: User Manager, used to provide authentication and security.
*
* ========================================================
*/
#include <KernelKit/FileMgr.h>
#include <KernelKit/HeapMgr.h>
#include <KernelKit/KPC.h>
#include <KernelKit/ThreadLocalStorage.h>
#include <KernelKit/UserMgr.h>
#include <NeKit/KString.h>
#include <NeKit/KernelPanic.h>
#include <NeKit/Utils.h>
#define kStdUserType (0xEE)
#define kSuperUserType (0xEF)
/// @file UserMgr.cc
/// @brief Multi-user support.
namespace Kernel {
namespace Detail {
////////////////////////////////////////////////////////////
/// \brief Constructs a password by hashing the password.
/// \param password password to hash.
/// \return the hashed password
////////////////////////////////////////////////////////////
STATIC UInt64 user_fnv_generator(const Char* password, User* user) {
if (!password || !user) return 0;
if (*password == 0) return 0;
kout << "user_fnv_generator: Hashing user password...\r";
const UInt64 kFnvOffsetBasis = 0xcbf29ce484222325ULL;
const UInt64 fFnvPrime = 0x100000001b3ULL;
UInt64 hash = kFnvOffsetBasis;
while (*password) {
hash ^= (Char) (*password++);
hash *= fFnvPrime;
}
kout << "user_fnv_generator: Hashed user password.\r";
return hash;
}
} // namespace Detail
////////////////////////////////////////////////////////////
/// @brief User ring constructor.
////////////////////////////////////////////////////////////
User::User(const Int32& sel, const Char* user_name) : mUserRing((UserRingKind) sel) {
MUST_PASS(sel >= 0);
rt_copy_memory_safe((VoidPtr) user_name, this->mUserName, rt_string_len(user_name),
kMaxUserNameLen);
}
////////////////////////////////////////////////////////////
/// @brief User ring constructor.
////////////////////////////////////////////////////////////
User::User(const UserRingKind& ring_kind, const Char* user_name) : mUserRing(ring_kind) {
rt_copy_memory_safe((VoidPtr) user_name, this->mUserName, rt_string_len(user_name),
kMaxUserNameLen);
}
////////////////////////////////////////////////////////////
/// @brief User destructor class.
////////////////////////////////////////////////////////////
User::~User() = default;
Bool User::Save(const UserPublicKey password) noexcept {
if (!password || *password == 0) return No;
this->mUserFNV = Detail::user_fnv_generator(password, this);
kout << "User::Save: Saved password successfully...\r";
return Yes;
}
Bool User::Login(const UserPublicKey password) noexcept {
if (!password || !*password) return No;
// now check if the password matches.
if (this->mUserFNV == Detail::user_fnv_generator(password, this)) {
kout << "User::Login: Password matches.\r";
return Yes;
}
kout << "User::Login: Password doesn't match.\r";
return No;
}
Bool User::operator==(const User& lhs) {
return lhs.mUserRing == this->mUserRing;
}
Bool User::operator!=(const User& lhs) {
return lhs.mUserRing != this->mUserRing;
}
////////////////////////////////////////////////////////////
/// @brief Returns the user's name.
////////////////////////////////////////////////////////////
Char* User::Name() noexcept {
return this->mUserName;
}
////////////////////////////////////////////////////////////
/// @brief Returns the user's ring.
/// @return The king of ring the user is attached to.
////////////////////////////////////////////////////////////
const UserRingKind& User::Ring() noexcept {
return this->mUserRing;
}
Bool User::IsStdUser() noexcept {
return this->Ring() == UserRingKind::kRingStdUser;
}
Bool User::IsSuperUser() noexcept {
return this->Ring() == UserRingKind::kRingSuperUser;
}
} // namespace Kernel
|