Skip to content
Snippets Groups Projects
Commit 992e41b9 authored by Lasse Tjernaes Wardenaer's avatar Lasse Tjernaes Wardenaer
Browse files

Resolve "Enhance cta-readtp to handle encryption"

parent f941d481
Branches
Tags
No related merge requests found
# v.NEXT
### Features
- cta/CTA#211 - Add functionality for reading encrypted tapes with cta-readtp
# v4.7.14-1
## Summary
......
......@@ -29,6 +29,7 @@
#include "rdbms/Login.hpp"
#include "scheduler/RetrieveJob.hpp"
#include "tapeserver/castor/tape/Constants.hpp"
#include "tapeserver/castor/tape/tapeserver/daemon/EncryptionControl.hpp"
#include "tapeserver/castor/tape/tapeserver/daemon/Payload.hpp"
#include "tapeserver/castor/tape/tapeserver/file/ReadSession.hpp"
#include "tapeserver/castor/tape/tapeserver/file/ReadSessionFactory.hpp"
......@@ -39,7 +40,6 @@
#include "tapeserver/readtp/TapeFseqRange.hpp"
#include "tapeserver/readtp/TapeFseqRangeListSequence.hpp"
namespace cta {
namespace tapeserver {
namespace readtp {
......@@ -49,14 +49,16 @@ namespace readtp {
//------------------------------------------------------------------------------
ReadtpCmd::ReadtpCmd(std::istream &inStream, std::ostream &outStream,
std::ostream &errStream, cta::log::StdoutLogger &log, cta::log::DummyLogger &dummyLog,
cta::mediachanger::MediaChangerFacade &mc):
cta::mediachanger::MediaChangerFacade &mc, const bool useEncryption,
const std::string& externalEncryptionKeyScript):
CmdLineTool(inStream, outStream, errStream),
m_log(log),
m_dummyLog(dummyLog),
m_mc(mc),
m_useLbp(true),
m_nbSuccessReads(0),
m_nbFailedReads(0) {
m_nbFailedReads(0),
m_encryptionControl(useEncryption, externalEncryptionKeyScript) {
}
//------------------------------------------------------------------------------
......@@ -107,6 +109,16 @@ int ReadtpCmd::exceptionThrowingMain(const int argc, char *const *const argv) {
returnCode = 1;
}
unloadTape(m_vid, drive);
// Disable encryption (or at least try)
try {
if (m_encryptionControl.disable(drive)) {
m_log(cta::log::INFO, "Turned encryption off before unmounting");
}
} catch (cta::exception::Exception& ex) {
m_log(cta::log::ERR, "Failed to turn off encryption before unmounting");
}
dismountTape(m_vid);
return returnCode;
......@@ -425,6 +437,9 @@ void ReadtpCmd::readTapeFile(
volInfo.nbFiles = 0;
volInfo.mountType = cta::common::dataStructures::MountType::Retrieve;
volInfo.labelFormat = labelFormat;
configureEncryption(m_vid, drive);
const auto readSession = castor::tape::tapeFile::ReadSessionFactory::create(drive, volInfo, m_useLbp);
catalogue::TapeFileSearchCriteria searchCriteria;
......@@ -561,6 +576,38 @@ void ReadtpCmd::rewindDrive(
m_log(cta::log::INFO, "Successfully rewound tape", params);
}
//------------------------------------------------------------------------------
// enableEncryption
//------------------------------------------------------------------------------
void ReadtpCmd::configureEncryption(
const std::string &vid,
castor::tape::tapeserver::drive::DriveInterface &drive) {
try {
// We want those scoped params to last for the whole mount.
// This will allow each session to be logged with its encryption
// status:
std::list<cta::log::Param> params;
{
auto encryptionStatus = m_encryptionControl.enable(drive, vid, castor::tape::tapeserver::daemon::EncryptionControl::SetTag::NO_SET_TAG);
if (encryptionStatus.on) {
params.push_back(cta::log::Param("encryption", "on"));
params.push_back(cta::log::Param("encryptionKey", encryptionStatus.keyName));
params.push_back(cta::log::Param("stdout", encryptionStatus.stdout));
m_log(cta::log::INFO, "Drive encryption enabled for this mount", params);
} else {
params.push_back(cta::log::Param("encryption", "off"));
m_log(cta::log::INFO, "Drive encryption not enabled for this mount", params);
}
}
}
catch (cta::exception::Exception& ex) {
std::list<cta::log::Param> params;
params.push_back(cta::log::Param("ErrorMessage", ex.getMessage().str()));
m_log(cta::log::ERR, "Drive encryption could not be enabled for this mount.", params);
throw;
}
}
//------------------------------------------------------------------------------
// printUsage
//------------------------------------------------------------------------------
......
......@@ -41,6 +41,7 @@ namespace catalogue {
class Catalogue;
}
namespace tapeserver {
namespace readtp {
......@@ -62,7 +63,8 @@ public:
ReadtpCmd(std::istream &inStream, std::ostream &outStream,
std::ostream &errStream, cta::log::StdoutLogger &log,
cta::log::DummyLogger &dummyLog,
cta::mediachanger::MediaChangerFacade &mc);
cta::mediachanger::MediaChangerFacade &mc, const bool useEncryption,
const std::string& externalEncryptionKeyScript);
/**
* Destructor.
......@@ -97,6 +99,14 @@ private:
*/
void readAndSetConfiguration(const std::string &userName, const ReadtpCmdLineArgs &cmdLineArgs);
/**
* Configures encryption to be able to read from an encrypted tape
*
* @param vid The volume identifier of the tape to be mounted.
* @param drive The tape drive.
*/
void configureEncryption(const std::string &vid, castor::tape::tapeserver::drive::DriveInterface &drive);
/**
* Reads a file line by line, strips comments and returns a list of the file lines.
*
......@@ -286,7 +296,7 @@ private:
* The object representing the media changer.
*/
cta::mediachanger::MediaChangerFacade &m_mc;
/**
* The boolean variable which determinate logical block protection usage by
* readtp commands. Hard coded when we create the class.
......@@ -307,6 +317,12 @@ private:
* Number of failed reads.
*/
uint64_t m_nbFailedReads;
/**
* Encryption helper object
*/
castor::tape::tapeserver::daemon::EncryptionControl m_encryptionControl;
}; // class ReadtpCmd
CTA_GENERATE_EXCEPTION_CLASS(NoSuchFSeqException);
......
......@@ -17,12 +17,17 @@
#include <iostream>
#include "tapeserver/castor/tape/tapeserver/daemon/EncryptionControl.hpp"
#include "tapeserver/daemon/TapedConfiguration.hpp"
#include "tapeserver/readtp/ReadtpCmd.hpp"
//------------------------------------------------------------------------------
// main
//------------------------------------------------------------------------------
int main(const int argc, char *const *const argv) {
const std::string DAEMON_CONFIG = "/etc/cta/cta-taped.conf";
char buf[256];
std::string hostName;
if (gethostname(buf, sizeof(buf))) {
......@@ -35,6 +40,22 @@ int main(const int argc, char *const *const argv) {
cta::log::DummyLogger dummyLog("dummy", "dummy");
cta::mediachanger::MediaChangerFacade mc(log);
cta::tapeserver::readtp::ReadtpCmd cmd(std::cin, std::cout, std::cerr, log, dummyLog, mc);
bool useEncryption;
std::string externalEncryptionKeyScript;
try {
// Config file needed to find the cta-get-encryption-key script
const cta::tape::daemon::TapedConfiguration tapedConfig =
cta::tape::daemon::TapedConfiguration::createFromCtaConf(DAEMON_CONFIG, log);
externalEncryptionKeyScript = tapedConfig.externalEncryptionKeyScript.value();
useEncryption = tapedConfig.useEncryption.value() == "yes" ? true : false;
}
catch(...) {
cta::exception::Exception ex;
ex.getMessage() << "ReadtpCmd: Error while trying to read TapedConfiguration config file: " << DAEMON_CONFIG;
throw ex;
}
cta::tapeserver::readtp::ReadtpCmd cmd(std::cin, std::cout, std::cerr, log, dummyLog, mc, useEncryption, externalEncryptionKeyScript);
return cmd.main(argc, argv);
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment