/************************************************************************* * UrBackup - Client/Server backup system * Copyright (C) 2021 Martin Raiber * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . **************************************************************************/ #include "ClouddriveFactory.h" #include "CloudFile.h" #include "KvStoreFrontend.h" #include "KvStoreBackendS3.h" #include "../cryptoplugin/cryptopp_inc.h" using namespace CryptoPPCompat; static std::string pbkdf2_sha256(const std::string& key) { std::string ret; ret.resize(CryptoPP::SHA256::DIGESTSIZE); CryptoPP::PKCS5_PBKDF2_HMAC pkcs; pkcs.DeriveKey(reinterpret_cast(&ret[0]), CryptoPP::SHA256::DIGESTSIZE, 0, (byte*)key.c_str(), key.size(), nullptr, 0, 100000, 0); return ret; } bool ClouddriveFactory::checkConnectivity(CloudSettings settings, int64 timeoutms) { return false; } IKvStoreBackend* ClouddriveFactory::createBackend(IBackupFileSystem* cachefs, CloudSettings settings) { std::string aes_key = pbkdf2_sha256(settings.encryption_key); return createBackend(cachefs, aes_key, settings); } IFile* ClouddriveFactory::createCloudFile(IBackupFileSystem* cachefs, CloudSettings settings) { return createCloudFile(cachefs, settings, false); } IFile* ClouddriveFactory::createCloudFile(IBackupFileSystem* cachefs, CloudSettings settings, bool check_only) { IOnlineKvStore* online_kv_store; std::string aes_key = pbkdf2_sha256(settings.encryption_key); IKvStoreBackend* backend = createBackend(cachefs, aes_key, settings); if (settings.endpoint == CloudEndpoint::S3) { try { online_kv_store = new KvStoreFrontend(settings.s3_settings.cache_db_path, backend, !check_only, std::string(), std::string(), nullptr, std::string(), false, false, cachefs); } catch (const std::exception&) { return nullptr; } } else { return nullptr; } return new CloudFile(std::string(), cachefs, settings.size, settings.size, online_kv_store, aes_key, get_compress_encrypt_factory(), settings.verify_cache, settings.cpu_multiplier, settings.background_compress, settings.no_compress_cpu_mult, settings.reserved_cache_device_space, settings.min_metadata_cache_free, settings.with_prev_link, settings.allow_evict, settings.with_submitted_files, settings.resubmit_compressed_ratio, settings.memcache_size, std::string(), settings.memory_usage_factor, settings.only_memfiles, std::string(), std::string(), static_cast(settings.background_compression), std::string(), -1, false, static_cast(settings.cache_object_compression), static_cast(settings.metadata_cache_object_compression)); } IKvStoreBackend* ClouddriveFactory::createBackend(IBackupFileSystem* cachefs, const std::string& aes_key, CloudSettings settings) { if (settings.endpoint == CloudEndpoint::S3) { IKvStoreBackend* s3_backend = new KvStoreBackendS3(aes_key, settings.s3_settings.access_key, settings.s3_settings.secret_access_key, settings.s3_settings.bucket_name, get_compress_encrypt_factory(), settings.s3_settings.endpoint, settings.s3_settings.region, settings.s3_settings.storage_class, static_cast(settings.submit_compression), static_cast(settings.metadata_submit_compression), cachefs); return s3_backend; } return nullptr; } int64 ClouddriveFactory::getCfTransid(IFile* cloudfile) { CloudFile* cd = dynamic_cast(cloudfile); if (cd == nullptr) return -1; return cd->get_transid(); } bool ClouddriveFactory::flush(IFile* cloudfile, bool do_submit) { if (cloudfile == nullptr) return false; CloudFile* cd = dynamic_cast(cloudfile); if (cd == nullptr) return false; return cd->Flush(do_submit); } std::string ClouddriveFactory::getCfNumDirtyItems(IFile* cloudfile) { if (cloudfile == nullptr) return std::string(); CloudFile* cd = dynamic_cast(cloudfile); if (cd == nullptr) return std::string(); return cd->getNumDirtyItems(); } bool ClouddriveFactory::isCloudFile(IFile* cloudfile) { return dynamic_cast(cloudfile)!=nullptr; } bool ClouddriveFactory::runBackgroundWorker(IFile* cloudFile, const std::string& output_fn) { CloudFile* cd = dynamic_cast(cloudFile); if (cd == nullptr) return false; if (!cd->has_background_task()) return false; cd->set_background_worker_result_fn(output_fn + ".new"); if (!cd->start_background_worker()) return false; while (cd->is_background_worker_running()) { Server->wait(100); } if (cd->has_background_task()) return false; return os_rename_file(output_fn + ".new", output_fn); } bool ClouddriveFactory::setTopFs(IFile* cloudFile, IBackupFileSystem* fs) { CloudFile* cd = dynamic_cast(cloudFile); if (cd == nullptr) return false; cd->set_is_mounted(std::string(), fs); return true; }