Print force killed process list for debugging
[platform/core/security/ode.git] / fota / fota.cpp
1 /*
2  *  Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
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 #include <sys/types.h>
17 #include <sys/stat.h>
18 #include <fcntl.h>
19 #include <unistd.h>
20 #include <stdlib.h>
21 #include <strings.h>
22 #include <blkid.h>
23
24 #include <string>
25 #include <iostream>
26
27 #include <klay/audit/dlog-sink.h>
28
29 #include <upgrade-support.h>
30 #include <internal-encryption-common.h>
31 #include <engine/encryption/dmcrypt-engine.h>
32
33 audit::LogSink *SINK = nullptr;
34
35 namespace ode {
36
37 struct AbstractDevice {
38         AbstractDevice() {}
39         virtual ~AbstractDevice() {}
40         virtual std::string findNode(const std::string &name) = 0;
41 };
42
43 struct MmcDevice : public AbstractDevice {
44 public:
45         MmcDevice(int id) : device("/dev/mmcblk" + std::to_string(id)), deviceHandle(-1)
46         {
47                 deviceHandle = ::open(device.c_str(), O_RDONLY);
48                 if (deviceHandle == -1)
49                         throw std::runtime_error("Invalid device: " + device);
50         }
51
52         virtual ~MmcDevice()
53         {
54                 if (deviceHandle != -1)
55                         ::close(deviceHandle);
56         }
57
58         virtual std::string findNode(const std::string &name)
59         {
60                 blkid_partlist partlist;
61                 blkid_probe probe;
62                 int partno = 0;
63
64                 probe = ::blkid_new_probe();
65                 if (!probe) {
66                         throw std::runtime_error("Failed to call blkid_new_probe");
67                 }
68
69                 if (::blkid_probe_set_device(probe, deviceHandle, 0, 0) < 0) {
70                         ::blkid_free_probe(probe);
71                         throw std::runtime_error("Failed to set prove device: " + device);
72                 }
73
74                 partlist = ::blkid_probe_get_partitions(probe);
75                 if (!partlist) {
76                         ::blkid_free_probe(probe);
77                         throw std::runtime_error("Failed to get partition list in device: " + device);
78                 }
79
80                 int num = ::blkid_partlist_numof_partitions(partlist);
81                 for (int i = 1; i <= num; i++) {
82                         blkid_partition par = ::blkid_partlist_get_partition(partlist, i);
83
84                         const char *n = ::blkid_partition_get_name(par);
85                         if (!n)
86                                 break;
87
88                         if (::strcasecmp(n, name.c_str()) == 0) {
89                                 partno = ::blkid_partition_get_partno(par);
90                                 break;
91                         }
92                 }
93
94                 ::blkid_free_probe(probe);
95
96                 if (partno <= 0) {
97                         throw std::runtime_error("Failed to get partition number with " +  name);
98                 }
99
100                 return device + "p" + std::to_string(partno);
101         }
102
103 private:
104         std::string device;
105         int deviceHandle;
106 };
107
108 // dummy implementation
109 ProgressBar::ProgressBar(UpdateFunc const&) : updateValue(0) {}
110 ProgressBar::~ProgressBar() {}
111
112 void ProgressBar::update(int) {}
113 void ProgressBar::update(int, int, int) {}
114 void ProgressBar::done(void) {}
115
116 } // namespace ode
117
118 namespace {
119
120 const std::string MOUNT = "mount";
121 const std::string UMOUNT = "umount";
122 const std::string REMOVE = "remove";
123
124 void usage()
125 {
126         std::cout <<
127                 "Usage: ode-fota [Operation]" << std::endl <<
128                 std::endl <<
129                 "Operations :" << std::endl <<
130                 "  mount [path]   Mount internal memory using stored master key" << std::endl <<
131                 "  umount [path]  Unmount internal memory" << std::endl <<
132                 "  remove         Remove stored internal memory master key" << std::endl;
133 }
134
135 } // anonymous namespace
136
137 int main(int argc, char* argv[])
138 {
139         try {
140                 using namespace ode;
141
142                 if (argc < 2 || argc > 3) {
143                         usage();
144                         return EXIT_FAILURE;
145                 }
146
147                 MmcDevice dev(0);
148                 std::string devpath = dev.findNode("user");
149
150                 if (MOUNT == argv[1]) {
151                         auto masterKey = UpgradeSupport::loadMasterKey(devpath);
152                         std::string path = INTERNAL_PATH;
153                         if (argc == 3)
154                                 path = argv[2];
155
156                         DMCryptEngine dmcrypt(devpath, path, ProgressBar([](int){}));
157
158                         // mount options are ignored by mount()
159                         dmcrypt.mount(masterKey, 0);
160                         UpgradeSupport::createUpgradeFlag();
161                 } else if (UMOUNT == argv[1]) {
162                         std::string path = INTERNAL_PATH;
163                         if (argc == 3)
164                                 path = argv[2];
165
166                         DMCryptEngine dmcrypt(devpath, path, ProgressBar([](int){}));
167                         dmcrypt.umount();
168                 } else if (REMOVE == argv[1]) {
169                         UpgradeSupport::removeMasterKey(devpath);
170                 } else {
171                         usage();
172                         return EXIT_FAILURE;
173                 }
174                 return EXIT_SUCCESS;
175         } catch (const std::exception& e) {
176                 std::cerr << e.what() << std::endl;
177         } catch (...) {
178                 std::cerr << "Unknown exception occured" << std::endl;
179         }
180
181         return EXIT_FAILURE;
182 }