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