blob: 3b1b0c9fc90b37ac6e2d06d58d6d36178cad74df [file] [log] [blame]
Gunnar Mills392f2942017-04-12 11:04:37 -05001#include <iostream>
2#include <string>
3#include <sstream>
4#include <fstream>
5#include <stdexcept>
Gunnar Millsaae1b2b2017-10-06 13:42:39 -05006#include <openssl/sha.h>
Gunnar Mills392f2942017-04-12 11:04:37 -05007#include <phosphor-logging/log.hpp>
Gunnar Millsaae1b2b2017-10-06 13:42:39 -05008#include <phosphor-logging/elog-errors.hpp>
9#include "xyz/openbmc_project/Common/error.hpp"
Eddie James6d873712017-09-01 11:29:07 -050010#include "config.h"
Gunnar Mills392f2942017-04-12 11:04:37 -050011#include "version.hpp"
12
13namespace phosphor
14{
15namespace software
16{
17namespace manager
18{
19
20using namespace phosphor::logging;
Gunnar Millsaae1b2b2017-10-06 13:42:39 -050021using Argument = xyz::openbmc_project::Common::InvalidArgument;
22using namespace sdbusplus::xyz::openbmc_project::Common::Error;
Gunnar Mills392f2942017-04-12 11:04:37 -050023
Gunnar Millscebd1022017-04-17 16:10:15 -050024std::string Version::getValue(const std::string& manifestFilePath,
25 std::string key)
Gunnar Mills392f2942017-04-12 11:04:37 -050026{
Gunnar Millscebd1022017-04-17 16:10:15 -050027 key = key + "=";
28 auto keySize = key.length();
Gunnar Mills392f2942017-04-12 11:04:37 -050029
30 if (manifestFilePath.empty())
31 {
32 log<level::ERR>("Error MANIFESTFilePath is empty");
Gunnar Millsaae1b2b2017-10-06 13:42:39 -050033 elog<InvalidArgument>(
Adriana Kobylak2285fe02018-02-27 15:36:59 -060034 Argument::ARGUMENT_NAME("manifestFilePath"),
35 Argument::ARGUMENT_VALUE(manifestFilePath.c_str()));
Gunnar Mills392f2942017-04-12 11:04:37 -050036 }
37
Gunnar Millscebd1022017-04-17 16:10:15 -050038 std::string value{};
Gunnar Mills392f2942017-04-12 11:04:37 -050039 std::ifstream efile;
40 std::string line;
Adriana Kobylak2285fe02018-02-27 15:36:59 -060041 efile.exceptions(std::ifstream::failbit | std::ifstream::badbit |
Gunnar Millsaae1b2b2017-10-06 13:42:39 -050042 std::ifstream::eofbit);
Gunnar Mills392f2942017-04-12 11:04:37 -050043
44 // Too many GCC bugs (53984, 66145) to do this the right way...
45 try
46 {
47 efile.open(manifestFilePath);
48 while (getline(efile, line))
49 {
Gunnar Millscebd1022017-04-17 16:10:15 -050050 if (line.compare(0, keySize, key) == 0)
Gunnar Mills392f2942017-04-12 11:04:37 -050051 {
Gunnar Millscebd1022017-04-17 16:10:15 -050052 value = line.substr(keySize);
Gunnar Mills392f2942017-04-12 11:04:37 -050053 break;
54 }
55 }
56 efile.close();
57 }
58 catch (const std::exception& e)
59 {
Gunnar Millscebd1022017-04-17 16:10:15 -050060 log<level::ERR>("Error in reading MANIFEST file");
Gunnar Mills392f2942017-04-12 11:04:37 -050061 }
62
Gunnar Millscebd1022017-04-17 16:10:15 -050063 return value;
Gunnar Mills392f2942017-04-12 11:04:37 -050064}
65
66std::string Version::getId(const std::string& version)
67{
Gunnar Mills392f2942017-04-12 11:04:37 -050068
69 if (version.empty())
70 {
Gunnar Millscebd1022017-04-17 16:10:15 -050071 log<level::ERR>("Error version is empty");
Gunnar Millsaae1b2b2017-10-06 13:42:39 -050072 elog<InvalidArgument>(Argument::ARGUMENT_NAME("Version"),
73 Argument::ARGUMENT_VALUE(version.c_str()));
Gunnar Mills392f2942017-04-12 11:04:37 -050074 }
75
Saqib Khan26a960d2017-09-19 14:23:28 -050076 unsigned char digest[SHA512_DIGEST_LENGTH];
77 SHA512_CTX ctx;
78 SHA512_Init(&ctx);
79 SHA512_Update(&ctx, version.c_str(), strlen(version.c_str()));
80 SHA512_Final(digest, &ctx);
Adriana Kobylak2285fe02018-02-27 15:36:59 -060081 char mdString[SHA512_DIGEST_LENGTH * 2 + 1];
Saqib Khan26a960d2017-09-19 14:23:28 -050082 for (int i = 0; i < SHA512_DIGEST_LENGTH; i++)
83 {
Adriana Kobylak2285fe02018-02-27 15:36:59 -060084 snprintf(&mdString[i * 2], 3, "%02x", (unsigned int)digest[i]);
Saqib Khan26a960d2017-09-19 14:23:28 -050085 }
86
87 // Only need 8 hex digits.
88 std::string hexId = std::string(mdString);
89 return (hexId.substr(0, 8));
Gunnar Mills392f2942017-04-12 11:04:37 -050090}
91
Saqib Khan1eef62d2017-08-10 15:29:34 -050092std::string Version::getBMCVersion(const std::string& releaseFilePath)
Saqib Khanba239882017-05-26 08:41:54 -050093{
94 std::string versionKey = "VERSION_ID=";
95 std::string version{};
96 std::ifstream efile;
97 std::string line;
Saqib Khan1eef62d2017-08-10 15:29:34 -050098 efile.open(releaseFilePath);
Saqib Khanba239882017-05-26 08:41:54 -050099
100 while (getline(efile, line))
101 {
102 if (line.substr(0, versionKey.size()).find(versionKey) !=
103 std::string::npos)
104 {
105 std::size_t pos = line.find_first_of('"') + 1;
106 version = line.substr(pos, line.find_last_of('"') - pos);
107 break;
108 }
109 }
110 efile.close();
111
112 if (version.empty())
113 {
114 log<level::ERR>("Error BMC current version is empty");
Gunnar Millsaae1b2b2017-10-06 13:42:39 -0500115 elog<InternalFailure>();
Saqib Khanba239882017-05-26 08:41:54 -0500116 }
117
118 return version;
119}
120
Eddie James6d873712017-09-01 11:29:07 -0500121bool Version::isFunctional()
122{
123 return versionStr == getBMCVersion(OS_RELEASE_FILE);
124}
125
Saqib Khanee13e832017-10-23 12:53:11 -0500126void Delete::delete_()
127{
128 if (parent.eraseCallback)
129 {
130 parent.eraseCallback(parent.getId(parent.version()));
131 }
132}
133
Gunnar Mills392f2942017-04-12 11:04:37 -0500134} // namespace manager
135} // namespace software
136} // namepsace phosphor