Merge tizen_4.0 into tizen
[platform/core/security/ode.git] / fota / fota.cpp
index ccbdafe..a81cfa3 100644 (file)
  *  See the License for the specific language governing permissions and
  *  limitations under the License
  */
-
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
 #include <stdlib.h>
+#include <strings.h>
+#include <blkid.h>
 
 #include <string>
 #include <iostream>
@@ -29,6 +34,77 @@ audit::LogSink *SINK = nullptr;
 
 namespace ode {
 
+struct AbstractDevice {
+       AbstractDevice() {}
+       virtual ~AbstractDevice() {}
+       virtual std::string findNode(const std::string &name) = 0;
+};
+
+struct MmcDevice : public AbstractDevice {
+public:
+       MmcDevice(int id) : device("/dev/mmcblk" + std::to_string(id)), deviceHandle(-1)
+       {
+               deviceHandle = ::open(device.c_str(), O_RDONLY);
+               if (deviceHandle == -1)
+                       throw std::runtime_error("Invalid device: " + device);
+       }
+
+       virtual ~MmcDevice()
+       {
+               if (deviceHandle != -1)
+                       ::close(deviceHandle);
+       }
+
+       virtual std::string findNode(const std::string &name)
+       {
+               blkid_partlist partlist;
+               blkid_probe probe;
+               int partno = 0;
+
+               probe = ::blkid_new_probe();
+               if (!probe) {
+                       throw std::runtime_error("Failed to call blkid_new_probe");
+               }
+
+               if (::blkid_probe_set_device(probe, deviceHandle, 0, 0) < 0) {
+                       ::blkid_free_probe(probe);
+                       throw std::runtime_error("Failed to set prove device: " + device);
+               }
+
+               partlist = ::blkid_probe_get_partitions(probe);
+               if (!partlist) {
+                       ::blkid_free_probe(probe);
+                       throw std::runtime_error("Failed to get partition list in device: " + device);
+               }
+
+               int num = ::blkid_partlist_numof_partitions(partlist);
+               for (int i = 1; i <= num; i++) {
+                       blkid_partition par = ::blkid_partlist_get_partition(partlist, i);
+
+                       const char *n = ::blkid_partition_get_name(par);
+                       if (!n)
+                               break;
+
+                       if (::strcasecmp(n, name.c_str()) == 0) {
+                               partno = ::blkid_partition_get_partno(par);
+                               break;
+                       }
+               }
+
+               ::blkid_free_probe(probe);
+
+               if (partno <= 0) {
+                       throw std::runtime_error("Failed to get partition number with " +  name);
+               }
+
+               return device + "p" + std::to_string(partno);
+       }
+
+private:
+       std::string device;
+       int deviceHandle;
+};
+
 // dummy implementation
 ProgressBar::ProgressBar(UpdateFunc const&) : updateValue(0) {}
 ProgressBar::~ProgressBar() {}
@@ -41,18 +117,18 @@ void ProgressBar::done(void) {}
 namespace {
 
 const std::string MOUNT = "mount";
+const std::string UMOUNT = "umount";
 const std::string REMOVE = "remove";
 
-const std::string DEV_PATH = ode::findDevPath();
-
 void usage()
 {
        std::cout <<
                "Usage: ode-fota [Operation]" << std::endl <<
                std::endl <<
                "Operations :" << std::endl <<
-               "  mount   Mount internal memory using stored master key" << std::endl <<
-               "  remove  Remove stored internal memory master key" << std::endl;
+               "  mount [path]   Mount internal memory using stored master key" << std::endl <<
+               "  umount [path]  Unmount internal memory" << std::endl <<
+               "  remove         Remove stored internal memory master key" << std::endl;
 }
 
 } // anonymous namespace
@@ -62,20 +138,34 @@ int main(int argc, char* argv[])
        try {
                using namespace ode;
 
-               if (argc < 2) {
+               if (argc < 2 || argc > 3) {
                        usage();
                        return EXIT_FAILURE;
                }
 
+               MmcDevice dev(0);
+               std::string devpath = dev.findNode("user");
+
                if (MOUNT == argv[1]) {
-                       auto masterKey = UpgradeSupport::loadMasterKey(DEV_PATH);
+                       auto masterKey = UpgradeSupport::loadMasterKey(devpath);
+                       std::string path = INTERNAL_PATH;
+                       if (argc == 3)
+                               path = argv[2];
 
-                       DMCryptEngine dmcrypt(DEV_PATH, INTERNAL_PATH, ProgressBar([](unsigned){}));
+                       DMCryptEngine dmcrypt(devpath, path, ProgressBar([](unsigned){}));
 
                        // mount options are ignored by mount()
                        dmcrypt.mount(masterKey, 0);
+                       UpgradeSupport::createUpgradeFlag();
+               } else if (UMOUNT == argv[1]) {
+                       std::string path = INTERNAL_PATH;
+                       if (argc == 3)
+                               path = argv[2];
+
+                       DMCryptEngine dmcrypt(devpath, path, ProgressBar([](int){}));
+                       dmcrypt.umount();
                } else if (REMOVE == argv[1]) {
-                       UpgradeSupport::removeMasterKey(DEV_PATH);
+                       UpgradeSupport::removeMasterKey(devpath);
                } else {
                        usage();
                        return EXIT_FAILURE;