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
|
/*
* ========================================================
*
* NeKernel
* Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
*
* 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;
auto ret = this->mUserFNV == Detail::user_fnv_generator(password, this);
// now check if the password matches.
kout << (ret ? "User::Login: Password matches.\r" : "User::Login: Password doesn't match.\r");
return ret;
}
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
|