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 #pragma once
17 #include <openssl/evp.h>
18 
19 #include <ctime>
20 #include <unordered_map>
21 #include <vector>
22 
23 namespace ipmi
24 {
25 
26 class PasswdMgr
27 {
28   public:
29     ~PasswdMgr() = default;
30     PasswdMgr(const PasswdMgr&) = delete;
31     PasswdMgr& operator=(const PasswdMgr&) = delete;
32     PasswdMgr(PasswdMgr&&) = delete;
33     PasswdMgr& operator=(PasswdMgr&&) = delete;
34 
35     /** @brief Constructs user password list
36      *
37      */
38     PasswdMgr();
39 
40     /** @brief Get password for the user
41      *
42      *  @param[in] userName - user name
43      *
44      * @return password string. will return empty string, if unable to locate
45      * the user
46      */
47     std::string getPasswdByUserName(const std::string& userName);
48 
49     /** @brief Update / clear  username and password entry for the specified
50      * user
51      *
52      *  @param[in] userName - user name that has to be renamed / deleted
53      *  @param[in] newUserName - new user name. If empty, userName will be
54      *   deleted.
55      *
56      * @return error response
57      */
58     int updateUserEntry(const std::string& userName,
59                         const std::string& newUserName);
60 
61   private:
62     using UserName = std::string;
63     using Password = std::string;
64     std::unordered_map<UserName, Password> passwdMapList;
65     std::time_t fileLastUpdatedTime;
66     /** @brief check timestamp and reload password map if required
67      *
68      */
69     void checkAndReload(void);
70     /** @brief initializes passwdMapList by reading the encrypted file
71      *
72      * Initializes the passwordMapList members after decrypting the
73      * password file. passwordMapList will be used further in IPMI
74      * authentication.
75      */
76     void initPasswordMap(void);
77 
78     /** @brief Function to read the encrypted password file data
79      *
80      *  @param[out] outBytes - vector to hold decrypted password file data
81      *
82      * @return error response
83      */
84     int readPasswdFileData(std::vector<uint8_t>& outBytes);
85     /** @brief  Updates special password file by clearing the password entry
86      *  for the user specified.
87      *
88      *  @param[in] userName - user name that has to be renamed / deleted
89      *  @param[in] newUserName - new user name. If empty, userName will be
90      *   deleted.
91      *
92      * @return error response
93      */
94     int updatePasswdSpecialFile(const std::string& userName,
95                                 const std::string& newUserName);
96     /** @brief encrypts or decrypt the data provided
97      *
98      *  @param[in] doEncrypt - do encrypt if set to true, else do decrypt.
99      *  @param[in] cipher - cipher to be used
100      *  @param[in] key - pointer to the key
101      *  @param[in] keyLen - Length of the key to be used
102      *  @param[in] iv - pointer to initialization vector
103      *  @param[in] ivLen - Length of the iv
104      *  @param[in] inBytes - input data to be encrypted / decrypted
105      *  @param[in] inBytesLen - input size to be encrypted / decrypted
106      *  @param[in] mac - message authentication code - to figure out corruption
107      *  @param[in] macLen - size of MAC
108      *  @param[in] outBytes - ptr to store output bytes
109      *  @param[in] outBytesLen - outbut data length.
110      *
111      * @return error response
112      */
113     int encryptDecryptData(bool doEncrypt, const EVP_CIPHER* cipher,
114                            uint8_t* key, size_t keyLen, uint8_t* iv,
115                            size_t ivLen, uint8_t* inBytes, size_t inBytesLen,
116                            uint8_t* mac, size_t* macLen, uint8_t* outBytes,
117                            size_t* outBytesLen);
118 
119     /** @brief  returns updated file time of passwd file entry.
120      *
121      * @return timestamp or -1 for error.
122      */
123     std::time_t getUpdatedFileTime();
124 };
125 
126 } // namespace ipmi
127