| Richard Marian Thomaiyar | 4654d99 | 2018-04-19 05:38:37 +0530 | [diff] [blame] | 1 | /* | 
|  | 2 | // Copyright (c) 2018 Intel Corporation | 
|  | 3 | // | 
|  | 4 | // Licensed under the Apache License, Version 2.0 (the "License"); | 
|  | 5 | // you may not use this file except in compliance with the License. | 
|  | 6 | // You may obtain a copy of the License at | 
|  | 7 | // | 
|  | 8 | //      http://www.apache.org/licenses/LICENSE-2.0 | 
|  | 9 | // | 
|  | 10 | // Unless required by applicable law or agreed to in writing, software | 
|  | 11 | // distributed under the License is distributed on an "AS IS" BASIS, | 
|  | 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|  | 13 | // See the License for the specific language governing permissions and | 
|  | 14 | // limitations under the License. | 
|  | 15 | */ | 
|  | 16 |  | 
|  | 17 | #include "passwd_mgr.hpp" | 
|  | 18 |  | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 19 | #include "file.hpp" | 
| Richard Marian Thomaiyar | 4654d99 | 2018-04-19 05:38:37 +0530 | [diff] [blame] | 20 | #include "shadowlock.hpp" | 
|  | 21 |  | 
|  | 22 | #include <openssl/hmac.h> | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 23 | #include <openssl/rand.h> | 
| Richard Marian Thomaiyar | 4654d99 | 2018-04-19 05:38:37 +0530 | [diff] [blame] | 24 | #include <openssl/sha.h> | 
|  | 25 | #include <string.h> | 
|  | 26 | #include <sys/stat.h> | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 27 | #include <unistd.h> | 
| Richard Marian Thomaiyar | 4654d99 | 2018-04-19 05:38:37 +0530 | [diff] [blame] | 28 |  | 
| George Liu | 82844ef | 2024-07-17 17:03:56 +0800 | [diff] [blame] | 29 | #include <phosphor-logging/lg2.hpp> | 
| Patrick Williams | fbc6c9d | 2023-05-10 07:50:16 -0500 | [diff] [blame] | 30 |  | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 31 | #include <cerrno> | 
| Richard Marian Thomaiyar | 4654d99 | 2018-04-19 05:38:37 +0530 | [diff] [blame] | 32 | #include <cstring> | 
|  | 33 | #include <fstream> | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 34 | #include <iomanip> | 
| Richard Marian Thomaiyar | 4654d99 | 2018-04-19 05:38:37 +0530 | [diff] [blame] | 35 |  | 
|  | 36 | namespace ipmi | 
|  | 37 | { | 
|  | 38 |  | 
|  | 39 | static const char* passwdFileName = "/etc/ipmi_pass"; | 
|  | 40 | static const char* encryptKeyFileName = "/etc/key_file"; | 
|  | 41 | static const size_t maxKeySize = 8; | 
|  | 42 |  | 
| Richard Marian Thomaiyar | 6ba8d31 | 2020-04-10 23:52:50 +0530 | [diff] [blame] | 43 | constexpr mode_t modeMask = | 
|  | 44 | (S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO); | 
|  | 45 |  | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 46 | #define META_PASSWD_SIG "=OPENBMC=" | 
|  | 47 |  | 
| Richard Marian Thomaiyar | 4654d99 | 2018-04-19 05:38:37 +0530 | [diff] [blame] | 48 | /* | 
|  | 49 | * Meta data struct for encrypted password file | 
|  | 50 | */ | 
| Richard Marian Thomaiyar | 48e5558 | 2018-12-20 15:58:04 +0530 | [diff] [blame] | 51 | struct MetaPassStruct | 
| Richard Marian Thomaiyar | 4654d99 | 2018-04-19 05:38:37 +0530 | [diff] [blame] | 52 | { | 
|  | 53 | char signature[10]; | 
|  | 54 | unsigned char reseved[2]; | 
| Tim Lee | 65a9168 | 2022-11-30 17:14:13 +0800 | [diff] [blame] | 55 | size_t hashSize; | 
|  | 56 | size_t ivSize; | 
|  | 57 | size_t dataSize; | 
|  | 58 | size_t padSize; | 
|  | 59 | size_t macSize; | 
| Richard Marian Thomaiyar | 4654d99 | 2018-04-19 05:38:37 +0530 | [diff] [blame] | 60 | }; | 
|  | 61 |  | 
| Richard Marian Thomaiyar | 4654d99 | 2018-04-19 05:38:37 +0530 | [diff] [blame] | 62 | PasswdMgr::PasswdMgr() | 
|  | 63 | { | 
| Richard Marian Thomaiyar | 6ba8d31 | 2020-04-10 23:52:50 +0530 | [diff] [blame] | 64 | restrictFilesPermission(); | 
| Richard Marian Thomaiyar | 4654d99 | 2018-04-19 05:38:37 +0530 | [diff] [blame] | 65 | initPasswordMap(); | 
|  | 66 | } | 
|  | 67 |  | 
| Richard Marian Thomaiyar | 6ba8d31 | 2020-04-10 23:52:50 +0530 | [diff] [blame] | 68 | void PasswdMgr::restrictFilesPermission(void) | 
|  | 69 | { | 
|  | 70 | struct stat st = {}; | 
|  | 71 | // Restrict file permission to owner read & write | 
|  | 72 | if (stat(passwdFileName, &st) == 0) | 
|  | 73 | { | 
|  | 74 | if ((st.st_mode & modeMask) != (S_IRUSR | S_IWUSR)) | 
|  | 75 | { | 
| PavanKumarIntel | 3771f5f | 2023-11-02 06:26:42 +0000 | [diff] [blame] | 76 | if (chmod(passwdFileName, S_IRUSR | S_IWUSR) == -1) | 
|  | 77 | { | 
| George Liu | 82844ef | 2024-07-17 17:03:56 +0800 | [diff] [blame] | 78 | lg2::debug("Error setting chmod for ipmi_pass file"); | 
| PavanKumarIntel | 3771f5f | 2023-11-02 06:26:42 +0000 | [diff] [blame] | 79 | } | 
| Richard Marian Thomaiyar | 6ba8d31 | 2020-04-10 23:52:50 +0530 | [diff] [blame] | 80 | } | 
|  | 81 | } | 
|  | 82 |  | 
|  | 83 | if (stat(encryptKeyFileName, &st) == 0) | 
|  | 84 | { | 
|  | 85 | if ((st.st_mode & modeMask) != (S_IRUSR | S_IWUSR)) | 
|  | 86 | { | 
| PavanKumarIntel | 3771f5f | 2023-11-02 06:26:42 +0000 | [diff] [blame] | 87 | if (chmod(encryptKeyFileName, S_IRUSR | S_IWUSR) == -1) | 
|  | 88 | { | 
| George Liu | 82844ef | 2024-07-17 17:03:56 +0800 | [diff] [blame] | 89 | lg2::debug("Error setting chmod for ipmi_pass file"); | 
| PavanKumarIntel | 3771f5f | 2023-11-02 06:26:42 +0000 | [diff] [blame] | 90 | } | 
| Richard Marian Thomaiyar | 6ba8d31 | 2020-04-10 23:52:50 +0530 | [diff] [blame] | 91 | } | 
|  | 92 | } | 
|  | 93 | } | 
|  | 94 |  | 
| Vernon Mauery | 1e22a0f | 2021-07-30 13:36:54 -0700 | [diff] [blame] | 95 | SecureString PasswdMgr::getPasswdByUserName(const std::string& userName) | 
| Richard Marian Thomaiyar | 4654d99 | 2018-04-19 05:38:37 +0530 | [diff] [blame] | 96 | { | 
|  | 97 | checkAndReload(); | 
|  | 98 | auto iter = passwdMapList.find(userName); | 
|  | 99 | if (iter == passwdMapList.end()) | 
|  | 100 | { | 
| Vernon Mauery | 1e22a0f | 2021-07-30 13:36:54 -0700 | [diff] [blame] | 101 | return SecureString(); | 
| Richard Marian Thomaiyar | 4654d99 | 2018-04-19 05:38:37 +0530 | [diff] [blame] | 102 | } | 
|  | 103 | return iter->second; | 
|  | 104 | } | 
|  | 105 |  | 
| Richard Marian Thomaiyar | 42bed64 | 2018-09-21 12:28:57 +0530 | [diff] [blame] | 106 | int PasswdMgr::updateUserEntry(const std::string& userName, | 
|  | 107 | const std::string& newUserName) | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 108 | { | 
|  | 109 | std::time_t updatedTime = getUpdatedFileTime(); | 
|  | 110 | // Check file time stamp to know passwdMapList is up-to-date. | 
|  | 111 | // If not up-to-date, then updatePasswdSpecialFile will read and | 
|  | 112 | // check the user entry existance. | 
|  | 113 | if (fileLastUpdatedTime == updatedTime && updatedTime != -EIO) | 
|  | 114 | { | 
|  | 115 | if (passwdMapList.find(userName) == passwdMapList.end()) | 
|  | 116 | { | 
| George Liu | 82844ef | 2024-07-17 17:03:56 +0800 | [diff] [blame] | 117 | lg2::debug("User not found"); | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 118 | return 0; | 
|  | 119 | } | 
|  | 120 | } | 
|  | 121 |  | 
|  | 122 | // Write passwdMap to Encryted file | 
| Richard Marian Thomaiyar | 42bed64 | 2018-09-21 12:28:57 +0530 | [diff] [blame] | 123 | if (updatePasswdSpecialFile(userName, newUserName) != 0) | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 124 | { | 
| George Liu | 82844ef | 2024-07-17 17:03:56 +0800 | [diff] [blame] | 125 | lg2::debug("Passwd file update failed"); | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 126 | return -EIO; | 
|  | 127 | } | 
|  | 128 |  | 
| George Liu | 82844ef | 2024-07-17 17:03:56 +0800 | [diff] [blame] | 129 | lg2::debug("Passwd file updated successfully"); | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 130 | return 0; | 
|  | 131 | } | 
|  | 132 |  | 
| Richard Marian Thomaiyar | 4654d99 | 2018-04-19 05:38:37 +0530 | [diff] [blame] | 133 | void PasswdMgr::checkAndReload(void) | 
|  | 134 | { | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 135 | std::time_t updatedTime = getUpdatedFileTime(); | 
|  | 136 | if (fileLastUpdatedTime != updatedTime && updatedTime != -1) | 
| Richard Marian Thomaiyar | 4654d99 | 2018-04-19 05:38:37 +0530 | [diff] [blame] | 137 | { | 
| George Liu | 82844ef | 2024-07-17 17:03:56 +0800 | [diff] [blame] | 138 | lg2::debug("Reloading password map list"); | 
| Richard Marian Thomaiyar | 4654d99 | 2018-04-19 05:38:37 +0530 | [diff] [blame] | 139 | passwdMapList.clear(); | 
|  | 140 | initPasswordMap(); | 
|  | 141 | } | 
|  | 142 | } | 
|  | 143 |  | 
| Patrick Williams | 1318a5e | 2024-08-16 15:19:54 -0400 | [diff] [blame] | 144 | int PasswdMgr::encryptDecryptData( | 
|  | 145 | bool doEncrypt, const EVP_CIPHER* cipher, uint8_t* key, size_t keyLen, | 
|  | 146 | uint8_t* iv, size_t ivLen, uint8_t* inBytes, size_t inBytesLen, | 
|  | 147 | uint8_t* mac, size_t* macLen, unsigned char* outBytes, size_t* outBytesLen) | 
| Richard Marian Thomaiyar | 4654d99 | 2018-04-19 05:38:37 +0530 | [diff] [blame] | 148 | { | 
| Jayanth Othayoth | a6fb32d | 2024-12-15 10:55:22 -0600 | [diff] [blame] | 149 | if (cipher == nullptr || key == nullptr || iv == nullptr || | 
|  | 150 | inBytes == nullptr || outBytes == nullptr || mac == nullptr || | 
|  | 151 | inBytesLen == 0 || (size_t)EVP_CIPHER_key_length(cipher) > keyLen || | 
| Richard Marian Thomaiyar | 4654d99 | 2018-04-19 05:38:37 +0530 | [diff] [blame] | 152 | (size_t)EVP_CIPHER_iv_length(cipher) > ivLen) | 
|  | 153 | { | 
| George Liu | 82844ef | 2024-07-17 17:03:56 +0800 | [diff] [blame] | 154 | lg2::debug("Error Invalid Inputs"); | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 155 | return -EINVAL; | 
| Richard Marian Thomaiyar | 4654d99 | 2018-04-19 05:38:37 +0530 | [diff] [blame] | 156 | } | 
|  | 157 |  | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 158 | if (!doEncrypt) | 
| Richard Marian Thomaiyar | 4654d99 | 2018-04-19 05:38:37 +0530 | [diff] [blame] | 159 | { | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 160 | // verify MAC before decrypting the data. | 
|  | 161 | std::array<uint8_t, EVP_MAX_MD_SIZE> calMac; | 
|  | 162 | size_t calMacLen = calMac.size(); | 
|  | 163 | // calculate MAC for the encrypted message. | 
| Jayanth Othayoth | a6fb32d | 2024-12-15 10:55:22 -0600 | [diff] [blame] | 164 | if (nullptr == | 
| Patrick Williams | 1318a5e | 2024-08-16 15:19:54 -0400 | [diff] [blame] | 165 | HMAC(EVP_sha256(), key, keyLen, inBytes, inBytesLen, calMac.data(), | 
|  | 166 | reinterpret_cast<unsigned int*>(&calMacLen))) | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 167 | { | 
| George Liu | 82844ef | 2024-07-17 17:03:56 +0800 | [diff] [blame] | 168 | lg2::debug("Error: Failed to calculate MAC"); | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 169 | return -EIO; | 
|  | 170 | } | 
|  | 171 | if (!((calMacLen == *macLen) && | 
|  | 172 | (std::memcmp(calMac.data(), mac, calMacLen) == 0))) | 
|  | 173 | { | 
| George Liu | 82844ef | 2024-07-17 17:03:56 +0800 | [diff] [blame] | 174 | lg2::debug("Authenticated message doesn't match"); | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 175 | return -EBADMSG; | 
|  | 176 | } | 
| Richard Marian Thomaiyar | 4654d99 | 2018-04-19 05:38:37 +0530 | [diff] [blame] | 177 | } | 
|  | 178 |  | 
|  | 179 | std::unique_ptr<EVP_CIPHER_CTX, decltype(&::EVP_CIPHER_CTX_free)> ctx( | 
|  | 180 | EVP_CIPHER_CTX_new(), ::EVP_CIPHER_CTX_free); | 
| Richard Marian Thomaiyar | 4654d99 | 2018-04-19 05:38:37 +0530 | [diff] [blame] | 181 |  | 
| P Dheeraj Srujan Kumar | bf30c8d | 2021-07-20 04:06:37 +0530 | [diff] [blame] | 182 | if (!ctx) | 
|  | 183 | { | 
| George Liu | 82844ef | 2024-07-17 17:03:56 +0800 | [diff] [blame] | 184 | lg2::debug("Error: EVP_CIPHER_CTX is NULL"); | 
| P Dheeraj Srujan Kumar | bf30c8d | 2021-07-20 04:06:37 +0530 | [diff] [blame] | 185 | return -ENOMEM; | 
|  | 186 | } | 
|  | 187 |  | 
| P Dheeraj Srujan Kumar | a67caed | 2021-08-25 21:55:09 +0530 | [diff] [blame] | 188 | EVP_CIPHER_CTX_set_padding(ctx.get(), 1); | 
|  | 189 |  | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 190 | // Set key & IV | 
| Jayanth Othayoth | a6fb32d | 2024-12-15 10:55:22 -0600 | [diff] [blame] | 191 | int retval = EVP_CipherInit_ex(ctx.get(), cipher, nullptr, key, iv, | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 192 | static_cast<int>(doEncrypt)); | 
| Richard Marian Thomaiyar | 4654d99 | 2018-04-19 05:38:37 +0530 | [diff] [blame] | 193 | if (!retval) | 
|  | 194 | { | 
| George Liu | 82844ef | 2024-07-17 17:03:56 +0800 | [diff] [blame] | 195 | lg2::debug("EVP_CipherInit_ex failed: {RET_VAL}", "RET_VAL", retval); | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 196 | return -EIO; | 
| Richard Marian Thomaiyar | 4654d99 | 2018-04-19 05:38:37 +0530 | [diff] [blame] | 197 | } | 
|  | 198 |  | 
|  | 199 | int outLen = 0, outEVPLen = 0; | 
|  | 200 | if ((retval = EVP_CipherUpdate(ctx.get(), outBytes + outLen, &outEVPLen, | 
|  | 201 | inBytes, inBytesLen))) | 
|  | 202 | { | 
|  | 203 | outLen += outEVPLen; | 
| Patrick Williams | 1318a5e | 2024-08-16 15:19:54 -0400 | [diff] [blame] | 204 | if ((retval = | 
|  | 205 | EVP_CipherFinal(ctx.get(), outBytes + outLen, &outEVPLen))) | 
| Richard Marian Thomaiyar | 4654d99 | 2018-04-19 05:38:37 +0530 | [diff] [blame] | 206 | { | 
|  | 207 | outLen += outEVPLen; | 
|  | 208 | *outBytesLen = outLen; | 
|  | 209 | } | 
|  | 210 | else | 
|  | 211 | { | 
| George Liu | 82844ef | 2024-07-17 17:03:56 +0800 | [diff] [blame] | 212 | lg2::debug("EVP_CipherFinal fails: {RET_VAL}", "RET_VAL", retval); | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 213 | return -EIO; | 
| Richard Marian Thomaiyar | 4654d99 | 2018-04-19 05:38:37 +0530 | [diff] [blame] | 214 | } | 
|  | 215 | } | 
|  | 216 | else | 
|  | 217 | { | 
| George Liu | 82844ef | 2024-07-17 17:03:56 +0800 | [diff] [blame] | 218 | lg2::debug("EVP_CipherUpdate fails: {RET_VAL}", "RET_VAL", retval); | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 219 | return -EIO; | 
|  | 220 | } | 
|  | 221 |  | 
|  | 222 | if (doEncrypt) | 
|  | 223 | { | 
|  | 224 | // Create MAC for the encrypted message | 
| Jayanth Othayoth | a6fb32d | 2024-12-15 10:55:22 -0600 | [diff] [blame] | 225 | if (nullptr == HMAC(EVP_sha256(), key, keyLen, outBytes, *outBytesLen, | 
|  | 226 | mac, reinterpret_cast<unsigned int*>(macLen))) | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 227 | { | 
| George Liu | 82844ef | 2024-07-17 17:03:56 +0800 | [diff] [blame] | 228 | lg2::debug("Failed to create authentication"); | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 229 | return -EIO; | 
|  | 230 | } | 
| Richard Marian Thomaiyar | 4654d99 | 2018-04-19 05:38:37 +0530 | [diff] [blame] | 231 | } | 
|  | 232 | return 0; | 
|  | 233 | } | 
|  | 234 |  | 
|  | 235 | void PasswdMgr::initPasswordMap(void) | 
|  | 236 | { | 
| Andrew Geissler | 2f0ad74 | 2021-05-14 13:39:15 -0500 | [diff] [blame] | 237 | // TODO  phosphor-host-ipmid#170 phosphor::user::shadow::Lock lock{}; | 
| Vernon Mauery | 1e22a0f | 2021-07-30 13:36:54 -0700 | [diff] [blame] | 238 | SecureString dataBuf; | 
| Richard Marian Thomaiyar | 4654d99 | 2018-04-19 05:38:37 +0530 | [diff] [blame] | 239 |  | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 240 | if (readPasswdFileData(dataBuf) != 0) | 
|  | 241 | { | 
| George Liu | 82844ef | 2024-07-17 17:03:56 +0800 | [diff] [blame] | 242 | lg2::debug("Error in reading the encrypted pass file"); | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 243 | return; | 
|  | 244 | } | 
|  | 245 |  | 
|  | 246 | if (dataBuf.size() != 0) | 
|  | 247 | { | 
|  | 248 | // populate the user list with password | 
| Vernon Mauery | 1e22a0f | 2021-07-30 13:36:54 -0700 | [diff] [blame] | 249 | char* outPtr = dataBuf.data(); | 
| Jayanth Othayoth | a6fb32d | 2024-12-15 10:55:22 -0600 | [diff] [blame] | 250 | char* nToken = nullptr; | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 251 | char* linePtr = strtok_r(outPtr, "\n", &nToken); | 
| Patrick Venture | 51d0c40 | 2019-08-19 11:19:19 -0700 | [diff] [blame] | 252 | size_t lineSize = 0; | 
| Jayanth Othayoth | a6fb32d | 2024-12-15 10:55:22 -0600 | [diff] [blame] | 253 | while (linePtr != nullptr) | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 254 | { | 
| Patrick Venture | 51d0c40 | 2019-08-19 11:19:19 -0700 | [diff] [blame] | 255 | size_t userEPos = 0; | 
| Vernon Mauery | 1e22a0f | 2021-07-30 13:36:54 -0700 | [diff] [blame] | 256 | SecureString lineStr(linePtr); | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 257 | if ((userEPos = lineStr.find(":")) != std::string::npos) | 
|  | 258 | { | 
|  | 259 | lineSize = lineStr.size(); | 
|  | 260 | passwdMapList.emplace( | 
|  | 261 | lineStr.substr(0, userEPos), | 
|  | 262 | lineStr.substr(userEPos + 1, lineSize - (userEPos + 1))); | 
|  | 263 | } | 
| Jayanth Othayoth | a6fb32d | 2024-12-15 10:55:22 -0600 | [diff] [blame] | 264 | linePtr = strtok_r(nullptr, "\n", &nToken); | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 265 | } | 
|  | 266 | } | 
|  | 267 |  | 
|  | 268 | // Update the timestamp | 
|  | 269 | fileLastUpdatedTime = getUpdatedFileTime(); | 
|  | 270 | return; | 
|  | 271 | } | 
|  | 272 |  | 
| Vernon Mauery | 1e22a0f | 2021-07-30 13:36:54 -0700 | [diff] [blame] | 273 | int PasswdMgr::readPasswdFileData(SecureString& outBytes) | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 274 | { | 
| Richard Marian Thomaiyar | 4654d99 | 2018-04-19 05:38:37 +0530 | [diff] [blame] | 275 | std::array<uint8_t, maxKeySize> keyBuff; | 
|  | 276 | std::ifstream keyFile(encryptKeyFileName, std::ios::in | std::ios::binary); | 
|  | 277 | if (!keyFile.is_open()) | 
|  | 278 | { | 
| George Liu | 82844ef | 2024-07-17 17:03:56 +0800 | [diff] [blame] | 279 | lg2::debug("Error in opening encryption key file"); | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 280 | return -EIO; | 
| Richard Marian Thomaiyar | 4654d99 | 2018-04-19 05:38:37 +0530 | [diff] [blame] | 281 | } | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 282 | keyFile.read(reinterpret_cast<char*>(keyBuff.data()), keyBuff.size()); | 
| Richard Marian Thomaiyar | 4654d99 | 2018-04-19 05:38:37 +0530 | [diff] [blame] | 283 | if (keyFile.fail()) | 
|  | 284 | { | 
| George Liu | 82844ef | 2024-07-17 17:03:56 +0800 | [diff] [blame] | 285 | lg2::debug("Error in reading encryption key file"); | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 286 | return -EIO; | 
| Richard Marian Thomaiyar | 4654d99 | 2018-04-19 05:38:37 +0530 | [diff] [blame] | 287 | } | 
|  | 288 |  | 
|  | 289 | std::ifstream passwdFile(passwdFileName, std::ios::in | std::ios::binary); | 
|  | 290 | if (!passwdFile.is_open()) | 
|  | 291 | { | 
| George Liu | 82844ef | 2024-07-17 17:03:56 +0800 | [diff] [blame] | 292 | lg2::debug("Error in opening ipmi password file"); | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 293 | return -EIO; | 
| Richard Marian Thomaiyar | 4654d99 | 2018-04-19 05:38:37 +0530 | [diff] [blame] | 294 | } | 
|  | 295 |  | 
|  | 296 | // calculate file size and read the data | 
| Richard Marian Thomaiyar | 4654d99 | 2018-04-19 05:38:37 +0530 | [diff] [blame] | 297 | passwdFile.seekg(0, std::ios::end); | 
|  | 298 | ssize_t fileSize = passwdFile.tellg(); | 
|  | 299 | passwdFile.seekg(0, std::ios::beg); | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 300 | std::vector<uint8_t> input(fileSize); | 
|  | 301 | passwdFile.read(reinterpret_cast<char*>(input.data()), fileSize); | 
| Richard Marian Thomaiyar | 4654d99 | 2018-04-19 05:38:37 +0530 | [diff] [blame] | 302 | if (passwdFile.fail()) | 
|  | 303 | { | 
| George Liu | 82844ef | 2024-07-17 17:03:56 +0800 | [diff] [blame] | 304 | lg2::debug("Error in reading encryption key file"); | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 305 | return -EIO; | 
| Richard Marian Thomaiyar | 4654d99 | 2018-04-19 05:38:37 +0530 | [diff] [blame] | 306 | } | 
|  | 307 |  | 
|  | 308 | // verify the signature first | 
| Richard Marian Thomaiyar | 48e5558 | 2018-12-20 15:58:04 +0530 | [diff] [blame] | 309 | MetaPassStruct* metaData = reinterpret_cast<MetaPassStruct*>(input.data()); | 
| Richard Marian Thomaiyar | 4654d99 | 2018-04-19 05:38:37 +0530 | [diff] [blame] | 310 | if (std::strncmp(metaData->signature, META_PASSWD_SIG, | 
|  | 311 | sizeof(metaData->signature))) | 
|  | 312 | { | 
| George Liu | 82844ef | 2024-07-17 17:03:56 +0800 | [diff] [blame] | 313 | lg2::debug("Error signature mismatch in password file"); | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 314 | return -EBADMSG; | 
|  | 315 | } | 
|  | 316 |  | 
|  | 317 | size_t inBytesLen = metaData->dataSize + metaData->padSize; | 
|  | 318 | // If data is empty i.e no password map then return success | 
|  | 319 | if (inBytesLen == 0) | 
|  | 320 | { | 
| George Liu | 82844ef | 2024-07-17 17:03:56 +0800 | [diff] [blame] | 321 | lg2::debug("Empty password file"); | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 322 | return 0; | 
| Richard Marian Thomaiyar | 4654d99 | 2018-04-19 05:38:37 +0530 | [diff] [blame] | 323 | } | 
|  | 324 |  | 
|  | 325 | // compute the key needed to decrypt | 
|  | 326 | std::array<uint8_t, EVP_MAX_KEY_LENGTH> key; | 
|  | 327 | auto keyLen = key.size(); | 
| Jayanth Othayoth | a6fb32d | 2024-12-15 10:55:22 -0600 | [diff] [blame] | 328 | if (nullptr == HMAC(EVP_sha256(), keyBuff.data(), keyBuff.size(), | 
|  | 329 | input.data() + sizeof(*metaData), metaData->hashSize, | 
|  | 330 | key.data(), reinterpret_cast<unsigned int*>(&keyLen))) | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 331 | { | 
| George Liu | 82844ef | 2024-07-17 17:03:56 +0800 | [diff] [blame] | 332 | lg2::debug("Failed to create MAC for authentication"); | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 333 | return -EIO; | 
|  | 334 | } | 
| Richard Marian Thomaiyar | 4654d99 | 2018-04-19 05:38:37 +0530 | [diff] [blame] | 335 |  | 
|  | 336 | // decrypt the data | 
|  | 337 | uint8_t* iv = input.data() + sizeof(*metaData) + metaData->hashSize; | 
|  | 338 | size_t ivLen = metaData->ivSize; | 
|  | 339 | uint8_t* inBytes = iv + ivLen; | 
| Richard Marian Thomaiyar | 4654d99 | 2018-04-19 05:38:37 +0530 | [diff] [blame] | 340 | uint8_t* mac = inBytes + inBytesLen; | 
|  | 341 | size_t macLen = metaData->macSize; | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 342 |  | 
|  | 343 | size_t outBytesLen = 0; | 
|  | 344 | // Resize to actual data size | 
| Vernon Mauery | 1e22a0f | 2021-07-30 13:36:54 -0700 | [diff] [blame] | 345 | outBytes.resize(inBytesLen + EVP_MAX_BLOCK_LENGTH, '\0'); | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 346 | if (encryptDecryptData(false, EVP_aes_128_cbc(), key.data(), keyLen, iv, | 
|  | 347 | ivLen, inBytes, inBytesLen, mac, &macLen, | 
| Vernon Mauery | 1e22a0f | 2021-07-30 13:36:54 -0700 | [diff] [blame] | 348 | reinterpret_cast<unsigned char*>(outBytes.data()), | 
|  | 349 | &outBytesLen) != 0) | 
| Richard Marian Thomaiyar | 4654d99 | 2018-04-19 05:38:37 +0530 | [diff] [blame] | 350 | { | 
| George Liu | 82844ef | 2024-07-17 17:03:56 +0800 | [diff] [blame] | 351 | lg2::debug("Error in decryption"); | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 352 | return -EIO; | 
| Richard Marian Thomaiyar | 4654d99 | 2018-04-19 05:38:37 +0530 | [diff] [blame] | 353 | } | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 354 | // Resize the vector to outBytesLen | 
|  | 355 | outBytes.resize(outBytesLen); | 
|  | 356 |  | 
| Richard Marian Thomaiyar | 4654d99 | 2018-04-19 05:38:37 +0530 | [diff] [blame] | 357 | OPENSSL_cleanse(key.data(), keyLen); | 
|  | 358 | OPENSSL_cleanse(iv, ivLen); | 
|  | 359 |  | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 360 | return 0; | 
|  | 361 | } | 
|  | 362 |  | 
| Richard Marian Thomaiyar | 42bed64 | 2018-09-21 12:28:57 +0530 | [diff] [blame] | 363 | int PasswdMgr::updatePasswdSpecialFile(const std::string& userName, | 
|  | 364 | const std::string& newUserName) | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 365 | { | 
| Andrew Geissler | 2f0ad74 | 2021-05-14 13:39:15 -0500 | [diff] [blame] | 366 | // TODO  phosphor-host-ipmid#170 phosphor::user::shadow::Lock lock{}; | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 367 |  | 
|  | 368 | size_t bytesWritten = 0; | 
|  | 369 | size_t inBytesLen = 0; | 
|  | 370 | size_t isUsrFound = false; | 
|  | 371 | const EVP_CIPHER* cipher = EVP_aes_128_cbc(); | 
| Vernon Mauery | 1e22a0f | 2021-07-30 13:36:54 -0700 | [diff] [blame] | 372 | SecureString dataBuf; | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 373 |  | 
|  | 374 | // Read the encrypted file and get the file data | 
|  | 375 | // Check user existance and return if not exist. | 
|  | 376 | if (readPasswdFileData(dataBuf) != 0) | 
| Richard Marian Thomaiyar | 4654d99 | 2018-04-19 05:38:37 +0530 | [diff] [blame] | 377 | { | 
| George Liu | 82844ef | 2024-07-17 17:03:56 +0800 | [diff] [blame] | 378 | lg2::debug("Error in reading the encrypted pass file"); | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 379 | return -EIO; | 
| Richard Marian Thomaiyar | 4654d99 | 2018-04-19 05:38:37 +0530 | [diff] [blame] | 380 | } | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 381 |  | 
|  | 382 | if (dataBuf.size() != 0) | 
|  | 383 | { | 
| Patrick Williams | fbc6c9d | 2023-05-10 07:50:16 -0500 | [diff] [blame] | 384 | inBytesLen = dataBuf.size() + newUserName.size() + | 
|  | 385 | EVP_CIPHER_block_size(cipher); | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 386 | } | 
|  | 387 |  | 
| Vernon Mauery | 1e22a0f | 2021-07-30 13:36:54 -0700 | [diff] [blame] | 388 | SecureString inBytes(inBytesLen, '\0'); | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 389 | if (inBytesLen != 0) | 
|  | 390 | { | 
|  | 391 | char* outPtr = reinterpret_cast<char*>(dataBuf.data()); | 
| Jayanth Othayoth | a6fb32d | 2024-12-15 10:55:22 -0600 | [diff] [blame] | 392 | char* nToken = nullptr; | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 393 | char* linePtr = strtok_r(outPtr, "\n", &nToken); | 
| Jayanth Othayoth | a6fb32d | 2024-12-15 10:55:22 -0600 | [diff] [blame] | 394 | while (linePtr != nullptr) | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 395 | { | 
| Patrick Venture | 51d0c40 | 2019-08-19 11:19:19 -0700 | [diff] [blame] | 396 | size_t userEPos = 0; | 
|  | 397 |  | 
| Vernon Mauery | 1e22a0f | 2021-07-30 13:36:54 -0700 | [diff] [blame] | 398 | SecureString lineStr(linePtr); | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 399 | if ((userEPos = lineStr.find(":")) != std::string::npos) | 
|  | 400 | { | 
|  | 401 | if (userName.compare(lineStr.substr(0, userEPos)) == 0) | 
|  | 402 | { | 
|  | 403 | isUsrFound = true; | 
| Richard Marian Thomaiyar | 42bed64 | 2018-09-21 12:28:57 +0530 | [diff] [blame] | 404 | if (!newUserName.empty()) | 
|  | 405 | { | 
|  | 406 | bytesWritten += std::snprintf( | 
| Vernon Mauery | 1e22a0f | 2021-07-30 13:36:54 -0700 | [diff] [blame] | 407 | &inBytes[0] + bytesWritten, | 
| Richard Marian Thomaiyar | 42bed64 | 2018-09-21 12:28:57 +0530 | [diff] [blame] | 408 | (inBytesLen - bytesWritten), "%s%s\n", | 
|  | 409 | newUserName.c_str(), | 
|  | 410 | lineStr.substr(userEPos, lineStr.size()).data()); | 
|  | 411 | } | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 412 | } | 
|  | 413 | else | 
|  | 414 | { | 
| Vernon Mauery | 1e22a0f | 2021-07-30 13:36:54 -0700 | [diff] [blame] | 415 | bytesWritten += std::snprintf(&inBytes[0] + bytesWritten, | 
|  | 416 | (inBytesLen - bytesWritten), | 
|  | 417 | "%s\n", lineStr.data()); | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 418 | } | 
|  | 419 | } | 
| Jayanth Othayoth | a6fb32d | 2024-12-15 10:55:22 -0600 | [diff] [blame] | 420 | linePtr = strtok_r(nullptr, "\n", &nToken); | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 421 | } | 
| Richard Marian Thomaiyar | 161f20d | 2019-01-28 20:33:16 +0530 | [diff] [blame] | 422 | inBytesLen = bytesWritten; | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 423 | } | 
|  | 424 | if (!isUsrFound) | 
|  | 425 | { | 
| George Liu | 82844ef | 2024-07-17 17:03:56 +0800 | [diff] [blame] | 426 | lg2::debug("User doesn't exist"); | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 427 | return 0; | 
|  | 428 | } | 
|  | 429 |  | 
|  | 430 | // Read the key buff from key file | 
|  | 431 | std::array<uint8_t, maxKeySize> keyBuff; | 
|  | 432 | std::ifstream keyFile(encryptKeyFileName, std::ios::in | std::ios::binary); | 
|  | 433 | if (!keyFile.good()) | 
|  | 434 | { | 
| George Liu | 82844ef | 2024-07-17 17:03:56 +0800 | [diff] [blame] | 435 | lg2::debug("Error in opening encryption key file"); | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 436 | return -EIO; | 
|  | 437 | } | 
|  | 438 | keyFile.read(reinterpret_cast<char*>(keyBuff.data()), keyBuff.size()); | 
|  | 439 | if (keyFile.fail()) | 
|  | 440 | { | 
| George Liu | 82844ef | 2024-07-17 17:03:56 +0800 | [diff] [blame] | 441 | lg2::debug("Error in reading encryption key file"); | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 442 | return -EIO; | 
|  | 443 | } | 
|  | 444 | keyFile.close(); | 
|  | 445 |  | 
|  | 446 | // Read the original passwd file mode | 
|  | 447 | struct stat st = {}; | 
|  | 448 | if (stat(passwdFileName, &st) != 0) | 
|  | 449 | { | 
| George Liu | 82844ef | 2024-07-17 17:03:56 +0800 | [diff] [blame] | 450 | lg2::debug("Error in getting password file fstat()"); | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 451 | return -EIO; | 
|  | 452 | } | 
|  | 453 |  | 
|  | 454 | // Create temporary file for write | 
|  | 455 | std::string pwdFile(passwdFileName); | 
|  | 456 | std::vector<char> tempFileName(pwdFile.begin(), pwdFile.end()); | 
|  | 457 | std::vector<char> fileTemplate = {'_', '_', 'X', 'X', 'X', | 
|  | 458 | 'X', 'X', 'X', '\0'}; | 
|  | 459 | tempFileName.insert(tempFileName.end(), fileTemplate.begin(), | 
|  | 460 | fileTemplate.end()); | 
|  | 461 | int fd = mkstemp((char*)tempFileName.data()); | 
|  | 462 | if (fd == -1) | 
|  | 463 | { | 
| George Liu | 82844ef | 2024-07-17 17:03:56 +0800 | [diff] [blame] | 464 | lg2::debug("Error creating temp file"); | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 465 | return -EIO; | 
|  | 466 | } | 
|  | 467 |  | 
|  | 468 | std::string strTempFileName(tempFileName.data()); | 
|  | 469 | // Open the temp file for writing from provided fd | 
|  | 470 | // By "true", remove it at exit if still there. | 
|  | 471 | // This is needed to cleanup the temp file at exception | 
|  | 472 | phosphor::user::File temp(fd, strTempFileName, "w", true); | 
| Jayanth Othayoth | a6fb32d | 2024-12-15 10:55:22 -0600 | [diff] [blame] | 473 | if ((temp)() == nullptr) | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 474 | { | 
|  | 475 | close(fd); | 
| George Liu | 82844ef | 2024-07-17 17:03:56 +0800 | [diff] [blame] | 476 | lg2::debug("Error creating temp file"); | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 477 | return -EIO; | 
|  | 478 | } | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 479 |  | 
| Vernon Mauery | b265455 | 2020-04-03 14:28:53 -0700 | [diff] [blame] | 480 | // Set the file mode as read-write for owner only | 
|  | 481 | if (fchmod(fileno((temp)()), S_IRUSR | S_IWUSR) < 0) | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 482 | { | 
| George Liu | 82844ef | 2024-07-17 17:03:56 +0800 | [diff] [blame] | 483 | lg2::debug("Error setting fchmod for temp file"); | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 484 | return -EIO; | 
|  | 485 | } | 
|  | 486 |  | 
|  | 487 | const EVP_MD* digest = EVP_sha256(); | 
|  | 488 | size_t hashLen = EVP_MD_block_size(digest); | 
|  | 489 | std::vector<uint8_t> hash(hashLen); | 
|  | 490 | size_t ivLen = EVP_CIPHER_iv_length(cipher); | 
|  | 491 | std::vector<uint8_t> iv(ivLen); | 
|  | 492 | std::array<uint8_t, EVP_MAX_KEY_LENGTH> key; | 
|  | 493 | size_t keyLen = key.size(); | 
|  | 494 | std::array<uint8_t, EVP_MAX_MD_SIZE> mac; | 
|  | 495 | size_t macLen = mac.size(); | 
|  | 496 |  | 
|  | 497 | // Create random hash and generate hash key which will be used for | 
|  | 498 | // encryption. | 
|  | 499 | if (RAND_bytes(hash.data(), hashLen) != 1) | 
|  | 500 | { | 
| George Liu | 82844ef | 2024-07-17 17:03:56 +0800 | [diff] [blame] | 501 | lg2::debug("Hash genertion failed, bailing out"); | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 502 | return -EIO; | 
|  | 503 | } | 
| Jayanth Othayoth | a6fb32d | 2024-12-15 10:55:22 -0600 | [diff] [blame] | 504 | if (nullptr == | 
| Patrick Williams | 1318a5e | 2024-08-16 15:19:54 -0400 | [diff] [blame] | 505 | HMAC(digest, keyBuff.data(), keyBuff.size(), hash.data(), hashLen, | 
|  | 506 | key.data(), reinterpret_cast<unsigned int*>(&keyLen))) | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 507 | { | 
| George Liu | 82844ef | 2024-07-17 17:03:56 +0800 | [diff] [blame] | 508 | lg2::debug("Failed to create MAC for authentication"); | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 509 | return -EIO; | 
|  | 510 | } | 
|  | 511 |  | 
|  | 512 | // Generate IV values | 
|  | 513 | if (RAND_bytes(iv.data(), ivLen) != 1) | 
|  | 514 | { | 
| George Liu | 82844ef | 2024-07-17 17:03:56 +0800 | [diff] [blame] | 515 | lg2::debug("UV genertion failed, bailing out"); | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 516 | return -EIO; | 
|  | 517 | } | 
|  | 518 |  | 
|  | 519 | // Encrypt the input data | 
|  | 520 | std::vector<uint8_t> outBytes(inBytesLen + EVP_MAX_BLOCK_LENGTH); | 
|  | 521 | size_t outBytesLen = 0; | 
|  | 522 | if (inBytesLen != 0) | 
|  | 523 | { | 
| Vernon Mauery | 1e22a0f | 2021-07-30 13:36:54 -0700 | [diff] [blame] | 524 | if (encryptDecryptData( | 
|  | 525 | true, EVP_aes_128_cbc(), key.data(), keyLen, iv.data(), ivLen, | 
|  | 526 | reinterpret_cast<unsigned char*>(inBytes.data()), inBytesLen, | 
|  | 527 | mac.data(), &macLen, outBytes.data(), &outBytesLen) != 0) | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 528 | { | 
| George Liu | 82844ef | 2024-07-17 17:03:56 +0800 | [diff] [blame] | 529 | lg2::debug("Error while encrypting the data"); | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 530 | return -EIO; | 
|  | 531 | } | 
|  | 532 | outBytes[outBytesLen] = 0; | 
|  | 533 | } | 
|  | 534 | OPENSSL_cleanse(key.data(), keyLen); | 
|  | 535 |  | 
|  | 536 | // Update the meta password structure. | 
| Richard Marian Thomaiyar | 48e5558 | 2018-12-20 15:58:04 +0530 | [diff] [blame] | 537 | MetaPassStruct metaData = {META_PASSWD_SIG, {0, 0}, 0, 0, 0, 0, 0}; | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 538 | metaData.hashSize = hashLen; | 
|  | 539 | metaData.ivSize = ivLen; | 
|  | 540 | metaData.dataSize = bytesWritten; | 
|  | 541 | metaData.padSize = outBytesLen - bytesWritten; | 
|  | 542 | metaData.macSize = macLen; | 
|  | 543 |  | 
|  | 544 | if (fwrite(&metaData, 1, sizeof(metaData), (temp)()) != sizeof(metaData)) | 
|  | 545 | { | 
| George Liu | 82844ef | 2024-07-17 17:03:56 +0800 | [diff] [blame] | 546 | lg2::debug("Error in writing meta data"); | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 547 | return -EIO; | 
|  | 548 | } | 
|  | 549 |  | 
|  | 550 | if (fwrite(&hash[0], 1, hashLen, (temp)()) != hashLen) | 
|  | 551 | { | 
| George Liu | 82844ef | 2024-07-17 17:03:56 +0800 | [diff] [blame] | 552 | lg2::debug("Error in writing hash data"); | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 553 | return -EIO; | 
|  | 554 | } | 
|  | 555 |  | 
|  | 556 | if (fwrite(&iv[0], 1, ivLen, (temp)()) != ivLen) | 
|  | 557 | { | 
| George Liu | 82844ef | 2024-07-17 17:03:56 +0800 | [diff] [blame] | 558 | lg2::debug("Error in writing IV data"); | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 559 | return -EIO; | 
|  | 560 | } | 
|  | 561 |  | 
|  | 562 | if (fwrite(&outBytes[0], 1, outBytesLen, (temp)()) != outBytesLen) | 
|  | 563 | { | 
| George Liu | 82844ef | 2024-07-17 17:03:56 +0800 | [diff] [blame] | 564 | lg2::debug("Error in writing encrypted data"); | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 565 | return -EIO; | 
|  | 566 | } | 
|  | 567 |  | 
|  | 568 | if (fwrite(&mac[0], 1, macLen, (temp)()) != macLen) | 
|  | 569 | { | 
| George Liu | 82844ef | 2024-07-17 17:03:56 +0800 | [diff] [blame] | 570 | lg2::debug("Error in writing MAC data"); | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 571 | return -EIO; | 
|  | 572 | } | 
|  | 573 |  | 
|  | 574 | if (fflush((temp)())) | 
|  | 575 | { | 
| George Liu | 82844ef | 2024-07-17 17:03:56 +0800 | [diff] [blame] | 576 | lg2::debug("File fflush error while writing entries to special file"); | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 577 | return -EIO; | 
|  | 578 | } | 
|  | 579 |  | 
|  | 580 | OPENSSL_cleanse(iv.data(), ivLen); | 
|  | 581 |  | 
|  | 582 | // Rename the tmp  file to actual file | 
|  | 583 | if (std::rename(strTempFileName.data(), passwdFileName) != 0) | 
|  | 584 | { | 
| George Liu | 82844ef | 2024-07-17 17:03:56 +0800 | [diff] [blame] | 585 | lg2::debug("Failed to rename tmp file to ipmi-pass"); | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 586 | return -EIO; | 
|  | 587 | } | 
|  | 588 |  | 
|  | 589 | return 0; | 
|  | 590 | } | 
|  | 591 |  | 
|  | 592 | std::time_t PasswdMgr::getUpdatedFileTime() | 
|  | 593 | { | 
| Richard Marian Thomaiyar | 4654d99 | 2018-04-19 05:38:37 +0530 | [diff] [blame] | 594 | struct stat fileStat = {}; | 
|  | 595 | if (stat(passwdFileName, &fileStat) != 0) | 
|  | 596 | { | 
| George Liu | 82844ef | 2024-07-17 17:03:56 +0800 | [diff] [blame] | 597 | lg2::debug("Error - Getting passwd file time stamp"); | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 598 | return -EIO; | 
| Richard Marian Thomaiyar | 4654d99 | 2018-04-19 05:38:37 +0530 | [diff] [blame] | 599 | } | 
| AppaRao Puli | b29b5ab | 2018-05-17 10:28:48 +0530 | [diff] [blame] | 600 | return fileStat.st_mtime; | 
| Richard Marian Thomaiyar | 4654d99 | 2018-04-19 05:38:37 +0530 | [diff] [blame] | 601 | } | 
|  | 602 |  | 
|  | 603 | } // namespace ipmi |