auto-add wopi server cert to child capath

Signed-off-by: Caolán McNamara <caolan.mcnamara@collabora.com>
Change-Id: I708ae6217dc4acf3be3b80dc27a4add03e2324a0
This commit is contained in:
Caolán McNamara 2024-06-04 11:06:22 +01:00 committed by Andras Timar
parent 8e5b9e018f
commit 292e48ddf1
6 changed files with 70 additions and 0 deletions

View file

@ -1781,6 +1781,10 @@ std::shared_ptr<lok::Document> Document::load(const std::shared_ptr<ChildSession
if (!userTimezone.empty()) if (!userTimezone.empty())
options += ",Timezone=" + userTimezone; options += ",Timezone=" + userTimezone;
const std::string wopiCertDir = session->getJailedFilePath() + ".certs";
if (FileUtil::Stat(pathFromFileURL(wopiCertDir)).exists())
::setenv("LO_CERTIFICATE_AUTHORITY_PATH", wopiCertDir.c_str(), 1);
std::string spellOnline = session->getSpellOnline(); std::string spellOnline = session->getSpellOnline();
if (!_loKitDocument) if (!_loKitDocument)
{ {

View file

@ -1276,6 +1276,16 @@ public:
#endif #endif
} }
std::string getSslCert(std::string& subjectHash)
{
#if ENABLE_SSL
std::shared_ptr<StreamSocket> socket = _socket.lock();
if (socket)
return socket->getSslCert(subjectHash);
#endif
return std::string();
}
void disconnect() void disconnect()
{ {
LOG_TRC("disconnect"); LOG_TRC("disconnect");

View file

@ -185,6 +185,21 @@ bool SslStreamSocket::verifyCertificate()
return false; return false;
} }
std::string SslStreamSocket::getSslCert(std::string& subjectHash)
{
std::ostringstream strstream;
if (X509* x509 = SSL_get_peer_certificate(_ssl))
{
Poco::Net::X509Certificate cert(x509);
cert.save(strstream);
std::stringstream hexstream;
hexstream << std::setfill('0') << std::setw(8) << std::hex << X509_subject_name_hash(x509);
subjectHash = hexstream.str();
}
return strstream.str();
}
#endif //ENABLE_SSL #endif //ENABLE_SSL
// help with initialization order // help with initialization order

View file

@ -1316,6 +1316,11 @@ public:
return 0; return 0;
} }
virtual std::string getSslCert(std::string&)
{
return std::string();
}
protected: protected:
std::vector<std::pair<size_t, size_t>> findChunks(Poco::Net::HTTPRequest &request); std::vector<std::pair<size_t, size_t>> findChunks(Poco::Net::HTTPRequest &request);

View file

@ -87,6 +87,8 @@ public:
return std::string(); return std::string();
} }
std::string getSslCert(std::string& subjectHash) override;
~SslStreamSocket() ~SslStreamSocket()
{ {
LOG_TRC("SslStreamSocket dtor #" << getFD()); LOG_TRC("SslStreamSocket dtor #" << getFD());

View file

@ -504,6 +504,16 @@ std::string WopiStorage::downloadDocument(const Poco::URI& uriObject, const std:
LOG_TRC("Downloading from [" << uriAnonym << "] to [" << getRootFilePath() LOG_TRC("Downloading from [" << uriAnonym << "] to [" << getRootFilePath()
<< "]: " << httpRequest.header()); << "]: " << httpRequest.header());
std::string wopiCert;
std::string subjectHash;
http::Session::FinishedCallback finishedCallback =
[&wopiCert, &subjectHash](const std::shared_ptr<http::Session>& session)
{
wopiCert = session->getSslCert(subjectHash);
};
httpSession->setFinishedHandler(std::move(finishedCallback));
const std::shared_ptr<const http::Response> httpResponse = const std::shared_ptr<const http::Response> httpResponse =
httpSession->syncDownload(httpRequest, getRootFilePath()); httpSession->syncDownload(httpRequest, getRootFilePath());
@ -550,6 +560,30 @@ std::string WopiStorage::downloadDocument(const Poco::URI& uriObject, const std:
const std::size_t filesize = (fileStat.good() ? fileStat.size() : 0); const std::size_t filesize = (fileStat.good() ? fileStat.size() : 0);
LOG_INF("WOPI::GetFile downloaded " << filesize << " bytes from [" << uriAnonym << "] -> " LOG_INF("WOPI::GetFile downloaded " << filesize << " bytes from [" << uriAnonym << "] -> "
<< getRootFilePathAnonym() << " in " << diff); << getRootFilePathAnonym() << " in " << diff);
// Put the wopi server cert, which has been designated valid by 'online',
// into the "certs" dir so 'core' will designate it valid too.
std::string wopiCertDestDir = getRootFilePath() + ".certs";
if (::mkdir(wopiCertDestDir.c_str(), S_IRWXU) < 0)
LOG_SYS("Failed to create certificate authority directory [" << wopiCertDestDir << ']');
else
{
// save as "subjectHash".0 to be a suitable entry for caPath
std::string wopiCertDest = Poco::Path(wopiCertDestDir, subjectHash + ".0").toString();
std::ofstream outfile;
outfile.open(wopiCertDest);
if (!outfile.is_open())
{
const std::string wopiCertDestAnonym = COOLWSD::anonymizeUrl(wopiCertDest);
LOG_ERR("Cannot open file [" << wopiCertDestAnonym << "] to save wopi cert.");
}
else
{
outfile.write(wopiCert.data(), wopiCert.size());
outfile.close();
}
}
setDownloaded(true); setDownloaded(true);
// Now return the jailed path. // Now return the jailed path.