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