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 #pragma once
18 #include "channel_layer.hpp"
19 
20 #include <boost/interprocess/sync/file_lock.hpp>
21 #include <boost/interprocess/sync/named_recursive_mutex.hpp>
22 #include <cstdint>
23 #include <ctime>
24 #include <nlohmann/json.hpp>
25 #include <sdbusplus/bus.hpp>
26 
27 namespace ipmi
28 {
29 
30 using Json = nlohmann::json;
31 
32 using DbusVariant =
33     sdbusplus::message::variant<std::vector<std::string>, std::string, bool>;
34 
35 using DbusChObjProperties = std::vector<std::pair<std::string, DbusVariant>>;
36 
37 static constexpr const char* ipmiChannelMutex = "ipmi_channel_mutex";
38 static constexpr const char* ipmiChMutexCleanupLockFile =
39     "/var/lib/ipmi/ipmi_channel_mutex_cleanup";
40 
41 struct ChannelAccessData
42 {
43     ChannelAccess chNonVolatileData;
44     ChannelAccess chVolatileData;
45 };
46 
47 struct ChannelData
48 {
49     std::string chName;
50     uint8_t chID;
51     bool isChValid;
52     uint8_t activeSessCount;
53     ChannelInfo chInfo;
54     ChannelAccessData chAccess;
55 };
56 
57 class ChannelConfig;
58 
59 ChannelConfig& getChannelConfigObject();
60 
61 class ChannelConfig
62 {
63   public:
64     ChannelConfig(const ChannelConfig&) = delete;
65     ChannelConfig& operator=(const ChannelConfig&) = delete;
66     ChannelConfig(ChannelConfig&&) = delete;
67     ChannelConfig& operator=(ChannelConfig&&) = delete;
68 
69     ~ChannelConfig();
70     ChannelConfig();
71 
72     /** @brief determines valid channel
73      *
74      *  @param[in] chNum - channel number
75      *
76      *  @return true if valid, false otherwise
77      */
78     bool isValidChannel(const uint8_t& chNum);
79 
80     /** @brief determines valid authentication type
81      *
82      *  @param[in] chNum - channel number
83      *  @param[in] authType - authentication type
84      *
85      *  @return true if valid, false otherwise
86      */
87     bool isValidAuthType(const uint8_t& chNum, const EAuthType& authType);
88 
89     /** @brief determines supported session type of a channel
90      *
91      *  @param[in] chNum - channel number
92      *
93      *  @return EChannelSessSupported - supported session type
94      */
95     EChannelSessSupported getChannelSessionSupport(const uint8_t& chNum);
96 
97     /** @brief determines number of active sessions on a channel
98      *
99      *  @param[in] chNum - channel number
100      *
101      *  @return numer of active sessions
102      */
103     int getChannelActiveSessions(const uint8_t& chNum);
104 
105     /** @brief provides channel info details
106      *
107      *  @param[in] chNum - channel number
108      *  @param[out] chInfo - channel info details
109      *
110      *  @return IPMI_CC_OK for success, others for failure.
111      */
112     ipmi_ret_t getChannelInfo(const uint8_t& chNum, ChannelInfo& chInfo);
113 
114     /** @brief provides channel access data
115      *
116      *  @param[in] chNum - channel number
117      *  @param[out] chAccessData - channel access data
118      *
119      *  @return IPMI_CC_OK for success, others for failure.
120      */
121     ipmi_ret_t getChannelAccessData(const uint8_t& chNum,
122                                     ChannelAccess& chAccessData);
123 
124     /** @brief to set channel access data
125      *
126      *  @param[in] chNum - channel number
127      *  @param[in] chAccessData - channel access data
128      *  @param[in] setFlag - flag to indicate updatable fields
129      *
130      *  @return IPMI_CC_OK for success, others for failure.
131      */
132     ipmi_ret_t setChannelAccessData(const uint8_t& chNum,
133                                     const ChannelAccess& chAccessData,
134                                     const uint8_t& setFlag);
135 
136     /** @brief to get channel access data persistent data
137      *
138      *  @param[in] chNum - channel number
139      *  @param[out] chAccessData - channel access data
140      *
141      *  @return IPMI_CC_OK for success, others for failure.
142      */
143     ipmi_ret_t getChannelAccessPersistData(const uint8_t& chNum,
144                                            ChannelAccess& chAccessData);
145 
146     /** @brief to set channel access data persistent data
147      *
148      *  @param[in] chNum - channel number
149      *  @param[in] chAccessData - channel access data
150      *  @param[in] setFlag - flag to indicate updatable fields
151      *
152      *  @return IPMI_CC_OK for success, others for failure.
153      */
154     ipmi_ret_t setChannelAccessPersistData(const uint8_t& chNum,
155                                            const ChannelAccess& chAccessData,
156                                            const uint8_t& setFlag);
157 
158     /** @brief provides supported authentication type for the channel
159      *
160      *  @param[in] chNum - channel number
161      *  @param[out] authTypeSupported - supported authentication type
162      *
163      *  @return IPMI_CC_OK for success, others for failure.
164      */
165     ipmi_ret_t getChannelAuthTypeSupported(const uint8_t& chNum,
166                                            uint8_t& authTypeSupported);
167 
168     /** @brief provides enabled authentication type for the channel
169      *
170      *  @param[in] chNum - channel number
171      *  @param[in] priv - privilege
172      *  @param[out] authType - enabled authentication type
173      *
174      *  @return IPMI_CC_OK for success, others for failure.
175      */
176     ipmi_ret_t getChannelEnabledAuthType(const uint8_t& chNum,
177                                          const uint8_t& priv,
178                                          EAuthType& authType);
179 
180     /** @brief conver to channel privilege from system privilege
181      *
182      *  @param[in] value - privilege value
183      *
184      *  @return Channel privilege
185      */
186     CommandPrivilege convertToPrivLimitIndex(const std::string& value);
187 
188     /** @brief function to write persistent channel configuration to config file
189      *
190      *  @return 0 for success, -errno for failure.
191      */
192     int writeChannelPersistData();
193 
194     /** @brief function to write volatile channel configuration to config file
195      *
196      *  @return 0 for success, -errno for failure.
197      */
198     int writeChannelVolatileData();
199 
200     /** @brief function to get channel data based on channel number
201      *
202      *  @param[in] chNum - channel number
203      *
204      *  @return 0 for success, -errno for failure.
205      */
206     ChannelData* getChannelDataPtr(const uint8_t& chNum);
207 
208     uint32_t signalFlag = 0;
209 
210     std::unique_ptr<boost::interprocess::named_recursive_mutex> channelMutex{
211         nullptr};
212 
213   private:
214     ChannelData channelData[maxIpmiChannels];
215     std::time_t nvFileLastUpdatedTime;
216     std::time_t voltFileLastUpdatedTime;
217     std::time_t getUpdatedFileTime(const std::string& fileName);
218     boost::interprocess::file_lock mutexCleanupLock;
219     sdbusplus::bus::bus bus;
220     bool signalHndlrObjectState = false;
221     boost::interprocess::file_lock sigHndlrLock;
222 
223     /** @brief function to initialize persistent channel configuration
224      *
225      */
226     void initChannelPersistData();
227 
228     /** @brief function to set default channel configuration based on channel
229      * number
230      *
231      *  @param[in] chNum - channel number
232      *  @param[in] chName - channel name
233      */
234     void setDefaultChannelConfig(const uint8_t& chNum,
235                                  const std::string& chName);
236 
237     /** @brief function to load all channel configuration
238      *
239      *  @return 0 for success, -errno for failure.
240      */
241     int loadChannelConfig();
242 
243     /** @brief function to read persistent channel data
244      *
245      *  @return 0 for success, -errno for failure.
246      */
247     int readChannelPersistData();
248 
249     /** @brief function to read volatile channel data
250      *
251      *  @return 0 for success, -errno for failure.
252      */
253     int readChannelVolatileData();
254 
255     /** @brief function to check and reload persistent channel data
256      *
257      *  @return 0 for success, -errno for failure.
258      */
259     int checkAndReloadNVData();
260 
261     /** @brief function to check and reload volatile channel data
262      *
263      *  @return 0 for success, -errno for failure.
264      */
265     int checkAndReloadVolatileData();
266 
267     /** @brief function to sync channel privilege with system network channel
268      * privilege
269      *
270      *  @return 0 for success, -errno for failure.
271      */
272     int syncNetworkChannelConfig();
273 
274     /** @brief function to set D-Bus property value
275      *
276      *  @param[in] bus - bus
277      *  @param[in] service - service name
278      *  @param[in] objPath - object path
279      *  @param[in] interface - interface
280      *  @param[in] property - property name
281      *  @param[in] value - property value
282      *
283      *  @return 0 for success, -errno for failure.
284      */
285     int setDbusProperty(sdbusplus::bus::bus& bus, const std::string& service,
286                         const std::string& objPath,
287                         const std::string& interface,
288                         const std::string& property, const DbusVariant& value);
289 
290     /** @brief function to get D-Bus property value
291      *
292      *  @param[in] bus - bus
293      *  @param[in] service - service name
294      *  @param[in] objPath - object path
295      *  @param[in] interface - interface
296      *  @param[in] property - property name
297      *  @param[out] value - property value
298      *
299      *  @return 0 for success, -errno for failure.
300      */
301     int getDbusProperty(sdbusplus::bus::bus& bus, const std::string& service,
302                         const std::string& objPath,
303                         const std::string& interface,
304                         const std::string& property, DbusVariant& value);
305 
306     /** @brief function to read json config file
307      *
308      *  @param[in] configFile - configuration file name
309      *
310      *  @return Json object
311      */
312     Json readJsonFile(const std::string& configFile);
313 
314     /** @brief function to write json config file
315      *
316      *  @param[in] configFile - configuration file name
317      *  @param[in] jsonData - json object
318      *
319      *  @return 0 for success, -errno for failure.
320      */
321     int writeJsonFile(const std::string& configFile, const Json& jsonData);
322 
323     /** @brief function to convert system access mode to Channel access mode
324      * type
325      *
326      *  @param[in] mode - access mode in string
327      *
328      *  @return Channel access mode.
329      */
330     EChannelAccessMode convertToAccessModeIndex(const std::string& mode);
331 
332     /** @brief function to convert access mode value to string
333      *
334      *  @param[in] value - acess mode value
335      *
336      *  @return access mode in string
337      */
338     std::string convertToAccessModeString(const uint8_t& value);
339 
340     /** @brief function to convert privilege value to string
341      *
342      *  @param[in] value - privilege value
343      *
344      *  @return privilege in string
345      */
346     std::string convertToPrivLimitString(const uint8_t& value);
347 
348     /** @brief function to convert session support string to value type
349      *
350      *  @param[in] value - session support type in string
351      *
352      *  @return support session type
353      */
354     EChannelSessSupported
355         convertToSessionSupportIndex(const std::string& value);
356 
357     /** @brief function to convert medium type string to value type
358      *
359      *  @param[in] value - medium type in string
360      *
361      *  @return channel medium type
362      */
363     EChannelMediumType convertToMediumTypeIndex(const std::string& value);
364 
365     /** @brief function to convert protocol type string to value type
366      *
367      *  @param[in] value - protocol type in string
368      *
369      *  @return channel protocol  type
370      */
371     EChannelProtocolType convertToProtocolTypeIndex(const std::string& value);
372 
373     /** @brief function to convert channel number to channel index
374      *
375      *  @param[in] chNum - channel number
376      *
377      *  @return channel index
378      */
379     uint8_t convertToChannelIndexNumber(const uint8_t& chNum);
380 
381     /** @brief function to convert channel name to network interface name
382      *
383      *  @param[in] value - channel interface name - ipmi centric
384      *
385      *  @return network channel interface name
386      */
387     std::string convertToNetInterface(const std::string& value);
388 };
389 
390 } // namespace ipmi
391