summaryrefslogtreecommitdiffhomepage
path: root/dev/kernel/src/User.cc
blob: c1a5ca948e584d548a014c0173cdbe1fff9eb485 (plain)
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
/*
 *	========================================================
 *
 *  	NeKernel
 * 		Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
 *
 *		File: User.cc
 * 		Purpose: User class, used to provide authentication and security.
 *
 * 	========================================================
 */

#include <KernelKit/FileMgr.h>
#include <KernelKit/KPC.h>
#include <KernelKit/MemoryMgr.h>
#include <KernelKit/User.h>
#include <NewKit/KernelPanic.h>

#define kStdUserType (0xEE)
#define kSuperUserType (0xEF)

/// @file User.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 1;
    if (*password == 0) return 1;

    kout << "user_fnv_generator: Hashing user password...\r";

    const UInt64 FNV_OFFSET_BASIS = 0xcbf29ce484222325ULL;
    const UInt64 FNV_PRIME        = 0x100000001b3ULL;

    UInt64 hash = FNV_OFFSET_BASIS;

    while (*password) {
      hash ^= (Utf8Char) (*password++);
      hash *= FNV_PRIME;
    }

    kout << "user_fnv_generator: Hashed user password.\r";

    return 0;
  }
}  // 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((VoidPtr) user_name, this->mUserName, rt_string_len(user_name));
}

////////////////////////////////////////////////////////////
/// @brief User ring constructor.
////////////////////////////////////////////////////////////
User::User(const UserRingKind& ring_kind, const Char* user_name) : mUserRing(ring_kind) {
  rt_copy_memory((VoidPtr) user_name, this->mUserName, rt_string_len(user_name));
}

////////////////////////////////////////////////////////////
/// @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