+ void Crypto::setPermission(
+ const Name &name,
+ const Label& ownerLabel,
+ const Label& accessorLabel,
+ const PermissionMask permissionMask)
+ {
+ Try {
+ PermissionTable permissionTable(this->m_connection);
+ permissionTable.setPermission(name, ownerLabel, accessorLabel, permissionMask);
+ return;
+ } Catch (SqlConnection::Exception::SyntaxError) {
+ LogError("Couldn't prepare set statement");
+ } Catch (SqlConnection::Exception::InternalError) {
+ LogError("Couldn't execute set statement");
+ }
+ ThrowMsg(Crypto::Exception::InternalError,
+ "Couldn't set permissions for name " << name );
+ }
+
+
+ void Crypto::SchemaInfo::setVersionInfo() {
+ SqlConnection::DataCommandUniquePtr insertContextCommand =
+ m_db->m_connection->PrepareDataCommand(DB_CMD_SCHEMA_SET);
+ insertContextCommand->BindString(101, DB_SCHEMA_VERSION_FIELD);
+ insertContextCommand->BindString(103, std::to_string(DB_VERSION_CURRENT).c_str());
+ insertContextCommand->Step();
+ }
+
+ bool Crypto::SchemaInfo::getVersionInfo(int & version) const
+ {
+ // Try..Catch mandatory here - we don't need to escalate the error
+ // if it happens - we just won't return the version, allowing CKM to work
+ Try {
+ SqlConnection::DataCommandUniquePtr selectCommand =
+ m_db->m_connection->PrepareDataCommand(DB_CMD_SCHEMA_GET);
+ selectCommand->BindString(101, DB_SCHEMA_VERSION_FIELD);
+
+ if(selectCommand->Step()) {
+ version = static_cast<int>(atoi(selectCommand->GetColumnString(1).c_str()));
+ return true;
+ }
+ } Catch (SqlConnection::Exception::InvalidColumn) {
+ LogError("Select statement invalid column error");
+ } Catch (SqlConnection::Exception::SyntaxError) {
+ LogError("Couldn't prepare select statement");
+ } Catch (SqlConnection::Exception::InternalError) {
+ LogError("Couldn't execute select statement");
+ }
+ return false;
+ }
+
+ void Crypto::PermissionTable::setPermission(
+ const Name &name,
+ const Label& ownerLabel,
+ const Label& accessorLabel,
+ const PermissionMask permissionMask)
+ {
+ if(permissionMask == Permission::NONE)
+ {
+ // clear permissions
+ SqlConnection::DataCommandUniquePtr deletePermissionCommand =
+ m_connection->PrepareDataCommand(DB_CMD_PERMISSION_DELETE);
+ deletePermissionCommand->BindString(104, accessorLabel.c_str());
+ deletePermissionCommand->BindString(101, name.c_str());
+ deletePermissionCommand->BindString(102, ownerLabel.c_str());
+ deletePermissionCommand->Step();
+ }
+ else
+ {
+ // add new permissions
+ SqlConnection::DataCommandUniquePtr setPermissionCommand =
+ m_connection->PrepareDataCommand(DB_CMD_PERMISSION_SET);
+ setPermissionCommand->BindString(104, accessorLabel.c_str());
+ setPermissionCommand->BindInteger(105, static_cast<int>(permissionMask));
+ setPermissionCommand->BindString(101, name.c_str());
+ setPermissionCommand->BindString(102, ownerLabel.c_str());
+ setPermissionCommand->Step();
+ }
+ }
+
+ PermissionMaskOptional Crypto::PermissionTable::getPermissionRow(
+ const Name &name,
+ const Label &ownerLabel,
+ const Label &accessorLabel) const
+ {
+ SqlConnection::DataCommandUniquePtr selectCommand =
+ m_connection->PrepareDataCommand(DB_CMD_PERMISSION_SELECT);
+ selectCommand->BindString(104, accessorLabel.c_str());
+
+ // name table reference
+ selectCommand->BindString(101, name.c_str());
+ selectCommand->BindString(102, ownerLabel.c_str());
+
+ if(selectCommand->Step())
+ {
+ // there is entry for the <name, ownerLabel> pair
+ return PermissionMaskOptional(PermissionMask(selectCommand->GetColumnInteger(0)));
+ }
+ return PermissionMaskOptional();
+ }
+
+ void Crypto::NameTable::addRow(
+ const Name &name,
+ const Label &ownerLabel)
+ {
+ // insert NAMES item
+ SqlConnection::DataCommandUniquePtr insertNameCommand =
+ m_connection->PrepareDataCommand(DB_CMD_NAME_INSERT);
+ insertNameCommand->BindString (101, name.c_str());
+ insertNameCommand->BindString (102, ownerLabel.c_str());
+ insertNameCommand->Step();
+ }
+
+ void Crypto::NameTable::deleteRow(
+ const Name &name,
+ const Label &ownerLabel)
+ {
+ SqlConnection::DataCommandUniquePtr deleteCommand =
+ m_connection->PrepareDataCommand(DB_CMD_NAME_DELETE);
+ deleteCommand->BindString(101, name.c_str());
+ deleteCommand->BindString(102, ownerLabel.c_str());
+
+ // Step() result code does not provide information whether
+ // anything was removed.
+ deleteCommand->Step();
+ }
+
+ void Crypto::NameTable::deleteAllRows(const Label &ownerLabel)
+ {
+ SqlConnection::DataCommandUniquePtr deleteData =
+ m_connection->PrepareDataCommand(DB_CMD_NAME_DELETE_BY_LABEL);
+ deleteData->BindString(102, ownerLabel.c_str());
+
+ // Step() result code does not provide information whether
+ // anything was removed.
+ deleteData->Step();
+ }
+
+ bool Crypto::NameTable::isPresent(const Name &name, const Label &ownerLabel) const
+ {
+ SqlConnection::DataCommandUniquePtr checkCmd =
+ m_connection->PrepareDataCommand(DB_CMD_NAME_COUNT_ROWS);
+ checkCmd->BindString(101, name.c_str());
+ checkCmd->BindString(102, ownerLabel.c_str());
+ if(checkCmd->Step()) {
+ int element_count = checkCmd->GetColumnInteger(0);
+ LogDebug("Item name: " << name << " ownerLabel: " << ownerLabel <<
+ " hit count: " << element_count);
+ if(element_count > 0)
+ return true;
+ }
+ return false;
+ }
+
+ void Crypto::ObjectTable::addRow(const Row &row)
+ {
+ SqlConnection::DataCommandUniquePtr insertObjectCommand =
+ m_connection->PrepareDataCommand(DB_CMD_OBJECT_INSERT);
+ insertObjectCommand->BindInteger(1, row.exportable);
+ insertObjectCommand->BindInteger(2, static_cast<int>(row.dataType));
+ insertObjectCommand->BindInteger(3, static_cast<int>(row.algorithmType));
+ insertObjectCommand->BindInteger(4, row.encryptionScheme);
+ insertObjectCommand->BindBlob (5, row.iv);
+ insertObjectCommand->BindInteger(6, row.dataSize);
+ insertObjectCommand->BindBlob (7, row.data);
+ insertObjectCommand->BindBlob (8, row.tag);
+ insertObjectCommand->BindInteger(9, static_cast<int>(row.backendId));
+
+ // name table reference
+ insertObjectCommand->BindString (101, row.name.c_str());
+ insertObjectCommand->BindString (102, row.ownerLabel.c_str());
+
+ insertObjectCommand->Step();
+ }
+
+ std::string Crypto::getSchema() {
+ SqlConnection::DataCommandUniquePtr schema =
+ m_connection->PrepareDataCommand("SELECT sql FROM "
+ "(SELECT * FROM sqlcipher_master UNION ALL "
+ "SELECT * FROM sqlcipher_temp_master) "
+ "WHERE type!='meta' "
+ "ORDER BY tbl_name, type DESC, name;");
+
+ std::stringstream ss;
+ while(schema->Step()) {
+ ss << schema->GetColumnString(0) << std::endl;
+ }
+ return ss.str();
+ }
+
+ std::string Crypto::getContent() {
+ SqlConnection::DataCommandUniquePtr tableSelect =
+ m_connection->PrepareDataCommand(
+ "SELECT name FROM sqlcipher_master "
+ "WHERE type IN ('table','view') AND name NOT LIKE 'sqlcipher_%' "
+ "UNION ALL "
+ "SELECT name FROM sqlcipher_temp_master "
+ "WHERE type IN ('table','view') "
+ "ORDER BY 1; ");
+
+ std::vector<std::string> tables;
+ while(tableSelect->Step()) {
+ tables.push_back(tableSelect->GetColumnString(0));
+ }
+
+ std::stringstream ss;
+
+ for (auto &e : tables) {
+ ss << "Table " << e << std::endl;
+ std::string query = "select * from " + e + ";";
+ SqlConnection::DataCommandUniquePtr result =
+ m_connection->PrepareDataCommand(query.c_str());
+ while(result->Step()) {
+ int maxColumn = result->GetColumnCount();
+ for (int i = 0; i < maxColumn; ++i) {
+ switch(result->GetColumnType(i)) {
+ case 1: // int64
+ ss << result->GetColumnInteger(i) << " | ";
+ break;
+ case 2: // float
+ ss << result->GetColumnFloat(i) << " | ";
+ break;
+ case 3: // string
+ ss << result->GetColumnString(i) << " | ";
+ break;
+ case 4: // Blob
+ {
+ auto buffer = result->GetColumnBlob(i);
+ ss << "BLOB (Size: " << buffer.size() << ") | ";
+ break;
+ }
+ case 5: // NULL
+ ss << "NULL | ";
+ break;
+ }
+ }
+ ss << std::endl;
+ }
+ }
+
+ return ss.str();
+ }
+} // namespace DB
+} // namespace CKM