diff --git a/src/vdv/certs/cert-downloader.cpp b/src/vdv/certs/cert-downloader.cpp index 4f92244..f2878df 100644 --- a/src/vdv/certs/cert-downloader.cpp +++ b/src/vdv/certs/cert-downloader.cpp @@ -1,122 +1,130 @@ /* Copyright (C) 2019 Volker Krause This program is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include using namespace KItinerary; static std::vector listCerts() { QProcess proc; proc.setProgram(QStringLiteral("kioclient5")); proc.setArguments({QStringLiteral("ls"), QStringLiteral("ldap://ldap-vdv-ion.telesec.de:389/ou=VDV%20KA,o=VDV%20Kernapplikations%20GmbH,c=de")}); + proc.setProcessChannelMode(QProcess::ForwardedErrorChannel); proc.start(); - proc.waitForFinished(); + if (!proc.waitForFinished() || proc.exitStatus() != QProcess::NormalExit) { + qFatal("Failed to list certificates from LDAP server."); + } std::vector certs; for (const auto &line : proc.readAllStandardOutput().split('\n')) { if (line.size() <= 5) { continue; } certs.push_back(QString::fromUtf8(line.left(line.size() - 5))); } return certs; } static void downloadCert(const QString &certName) { QProcess proc; proc.setProgram(QStringLiteral("kioclient5")); proc.setArguments({QStringLiteral("cat"), QStringLiteral("ldap://ldap-vdv-ion.telesec.de:389/cn=") + certName + QStringLiteral(",ou=VDV%20KA,o=VDV%20Kernapplikations%20GmbH,c=de")}); + proc.setProcessChannelMode(QProcess::ForwardedErrorChannel); proc.start(); - proc.waitForFinished(); + if (!proc.waitForFinished() || proc.exitStatus() != QProcess::NormalExit) { + qFatal("Failed to download certificate %s from LDAP server.", qPrintable(certName)); + } // primitive LDIF parser, would be nicer with something like KLDAP const auto certLdif = QString::fromUtf8(proc.readAllStandardOutput()); QRegularExpression regExp(QStringLiteral("cACertificate:: ([\\w\\W]*?)\n[^ ]")); const auto match = regExp.match(certLdif); const auto certData = match.captured(1).remove(QLatin1Char('\n')).remove(QLatin1Char(' ')).toUtf8(); QFile f(certName + QLatin1String(".vdv-cert")); f.open(QFile::WriteOnly); f.write(QByteArray::fromBase64(certData)); } static void writeQrc(const std::vector &certNames) { QFile qrc(QStringLiteral("vdv-certs.qrc")); - qrc.open(QFile::WriteOnly); + if (!qrc.open(QFile::WriteOnly)) { + qFatal("Failed to open file %s: %s", qPrintable(qrc.fileName()), qPrintable(qrc.errorString())); + } qrc.write("\n \n"); for (const auto &certName : certNames) { qrc.write(" "); qrc.write(certName.toUtf8()); qrc.write(".vdv-cert\n"); } qrc.write(" \n\n"); } static void decodeCert(const QString &certName) { QFile f(certName + QLatin1String(".vdv-cert")); f.open(QFile::ReadOnly); VdvCertificate cert(f.readAll()); if (cert.needsCaKey()) { qDebug() << certName << "needs decoding"; // TODO } else { qDebug() << certName << "is already decoded"; } } int main(int argc, char **argv) { QCoreApplication app(argc, argv); // (1) list all certificates auto certNames = listCerts(); // (2) load all certificates we don't have yet for (const auto &certName : certNames) { qDebug() << "checking certificate" << certName; if (QFile::exists(certName + QLatin1String(".vdv-cert"))) { continue; } downloadCert(certName); } // (3) decode certificates (avoids runtime cost and shrinks the file size) for (const auto &certName : certNames) { decodeCert(certName); } // (4) discard old sub-CA certificates we don't need // TODO // (5) write qrc file std::sort(certNames.begin(), certNames.end()); writeQrc(certNames); return 0; }