diff --git a/CMakeLists.txt b/CMakeLists.txt index 1b4c37de..2ad0186b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -29,3 +29,4 @@ macro_optional_add_subdirectory (ksnapshot) macro_optional_add_subdirectory (kupdatenotifier) macro_optional_add_subdirectory (knetpkg) macro_optional_add_subdirectory (kfirewall) +macro_optional_add_subdirectory (khash) diff --git a/khash/CMakeLists.txt b/khash/CMakeLists.txt new file mode 100644 index 00000000..db082f5a --- /dev/null +++ b/khash/CMakeLists.txt @@ -0,0 +1,36 @@ +project(khash) + +if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR}) + include(FeatureSummary) + + find_package(KDE4 4.23.0 REQUIRED) + include(KDE4Defaults) + include_directories(${KDE4_INCLUDES}) + add_definitions(${QT_DEFINITIONS} ${KDE4_DEFINITIONS}) +endif() + +set(khash_SRCS + khash.cpp +) + +add_executable(khash ${khash_SRCS}) + +target_link_libraries(khash + ${KDE4_KDEUI_LIBS} + ${KDE4_KFILE_LIBS} + ${QT_QTNETWORK_LIBRARY} +) + +install(TARGETS khash ${INSTALL_TARGETS_DEFAULT_ARGS}) + +########### install files ############### + +install( + PROGRAMS khash.desktop + DESTINATION ${KDE4_XDG_APPS_INSTALL_DIR} +) + +install( + FILES khash_checksum.desktop DESTINATION + ${KDE4_SERVICES_INSTALL_DIR}/ServiceMenus +) diff --git a/khash/khash.cpp b/khash/khash.cpp new file mode 100644 index 00000000..95fac834 --- /dev/null +++ b/khash/khash.cpp @@ -0,0 +1,187 @@ +/* This file is part of the KDE project + Copyright (C) 2023 Ivailo Monev + + This library 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 library 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 Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +class KHashDialog : public KDialog +{ + Q_OBJECT +public: + KHashDialog(QWidget *parent = 0); + ~KHashDialog(); + + void setAlgorithm(const QCryptographicHash::Algorithm algorithm); + void setSource(const KUrl &source); + + void start(); + +private: + QCryptographicHash::Algorithm m_algorithm; + KUrl m_source; + QGridLayout* m_dialoglayout; + KLineEdit* m_checksumedit; +}; + + +KHashDialog::KHashDialog(QWidget *parent) + : KDialog(parent), + m_algorithm(QCryptographicHash::Sha1), + m_dialoglayout(nullptr), + m_checksumedit(nullptr) +{ + QWidget* dialogwidget = new QWidget(this); + m_dialoglayout = new QGridLayout(dialogwidget); + + QLabel* checksumlabel = new QLabel(i18n("Checksum:"), dialogwidget); + m_dialoglayout->addWidget(checksumlabel, 0, 0); + + m_checksumedit = new KLineEdit(dialogwidget); + m_checksumedit->setReadOnly(true); + m_dialoglayout->addWidget(m_checksumedit, 0, 1); + + // TODO: progress bar and threading + + setMainWidget(dialogwidget); +} + +KHashDialog::~KHashDialog() +{ +} + +void KHashDialog::setAlgorithm(const QCryptographicHash::Algorithm algorithm) +{ + m_algorithm = algorithm; + QFontMetrics dialoglinemetric(m_checksumedit->font()); + switch (algorithm) { + case QCryptographicHash::Md5: { + m_dialoglayout->setColumnMinimumWidth(1, 32 * dialoglinemetric.width('x')); + break; + } + case QCryptographicHash::Sha1: { + m_dialoglayout->setColumnMinimumWidth(1, 40 * dialoglinemetric.width('x')); + break; + } + case QCryptographicHash::Sha256: { + m_dialoglayout->setColumnMinimumWidth(1, 64 * dialoglinemetric.width('x')); + break; + } + case QCryptographicHash::Sha512: { + // NOTE: it is 128 long but don't want it to extend too much (small screens) + m_dialoglayout->setColumnMinimumWidth(1, 64 * dialoglinemetric.width('x')); + break; + } + case QCryptographicHash::KAT: { + m_dialoglayout->setColumnMinimumWidth(1, 64 * dialoglinemetric.width('x')); + break; + } + } +} + +void KHashDialog::setSource(const KUrl &source) +{ + m_source = source; + setCaption(KDialog::makeStandardCaption(QFileInfo(source.prettyUrl()).fileName(), this)); +} + +void KHashDialog::start() +{ + QFile checksumfile(m_source.toLocalFile()); + if (!checksumfile.open(QFile::ReadOnly)) { + m_checksumedit->setText(checksumfile.errorString()); + return; + } + QCryptographicHash checksumer(m_algorithm); + if (!checksumer.addData(&checksumfile)) { + m_checksumedit->setText(i18n("Checksummer error")); + return; + } + const QByteArray checksumhex = checksumer.result().toHex(); + m_checksumedit->setText(checksumhex); +} + + +int main(int argc, char **argv) +{ + KAboutData aboutData( + "security-high", 0, ki18n("KHash"), + "1.0.0", ki18n("KDE checksum calculation utility"), KAboutData::License_GPL, + ki18n("(c) 2023 Ivailo Monev") + ); + aboutData.addAuthor(ki18n("Ivailo Monev"), KLocalizedString(), "xakepa10@gmail.com"); + + KCmdLineArgs::init(argc, argv, &aboutData); + KCmdLineOptions options; + options.add("algorithm ", ki18n("Checksum algorithm to use, default value"), "sha1"); + options.add("+[url]", ki18n("URL to be opened")); + KCmdLineArgs::addCmdLineOptions(options); + + KApplication app; + + KHashDialog khashdialog; + + KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); + const QString hashtype = args->getOption("algorithm"); + if (hashtype == QLatin1String("md5")) { + khashdialog.setAlgorithm(QCryptographicHash::Md5); + } else if (hashtype == QLatin1String("sha1")) { + khashdialog.setAlgorithm(QCryptographicHash::Sha1); + } else if (hashtype == QLatin1String("sha256")) { + khashdialog.setAlgorithm(QCryptographicHash::Sha256); + } else if (hashtype == QLatin1String("sha512")) { + khashdialog.setAlgorithm(QCryptographicHash::Sha512); + } else if (hashtype == QLatin1String("kat")) { + khashdialog.setAlgorithm(QCryptographicHash::KAT); + } else { + KCmdLineArgs::usageError(i18n("Algorithm must be one of: md5, sha1, sha256, sha512 or kat")); + return 1; + } + + bool shouldstart = false; + for (int pos = 0; pos < args->count(); ++pos) { + khashdialog.setSource(args->url(pos)); + shouldstart = true; + } + + khashdialog.show(); + khashdialog.setButtons(KDialog::Ok | KDialog::Close | KDialog::Help); + KHelpMenu khelpmenu(&khashdialog, &aboutData, true); + khashdialog.setButtonMenu(KDialog::Help, (QMenu*)khelpmenu.menu()); + + if (shouldstart) { + khashdialog.start(); + } + + return app.exec(); +} + +#include "khash.moc" diff --git a/khash/khash.desktop b/khash/khash.desktop new file mode 100755 index 00000000..e191b4b9 --- /dev/null +++ b/khash/khash.desktop @@ -0,0 +1,13 @@ +[Desktop Entry] +Name=KHash +GenericName=Checksum calculation utility +MimeType=all/allfiles; +Exec=khash --icon '%i' --caption '%c' %U +Icon=security-high +Type=Application +Terminal=false +StartupNotify=false +X-DocPath=khash/index.html +X-KDE-StartupNotify=false +X-DBUS-StartupType=Multi +Categories=Qt;KDE;Utility; diff --git a/khash/khash_checksum.desktop b/khash/khash_checksum.desktop new file mode 100644 index 00000000..d6d5cb81 --- /dev/null +++ b/khash/khash_checksum.desktop @@ -0,0 +1,38 @@ +[Desktop Entry] +Actions=KHashChecksumMD5;KHashChecksumSHA1;KHashChecksumSHA256;KHashChecksumSHA512;KHashChecksumKAT; +Type=Service +X-KDE-ServiceTypes=KonqPopupMenu/Plugin,all/allfiles +X-KDE-Protocol=file +X-KDE-Priority=TopLevel +X-KDE-StartupNotify=false +X-KDE-Submenu=Checksum + +[Desktop Action KHashChecksumMD5] +Exec=khash --algorithm=md5 %U +Icon=security-low +Name=Calculate MD5 checksum +Name[x-test]=xxCalculate MD5 checksumxx + +[Desktop Action KHashChecksumSHA1] +Exec=khash --algorithm=sha1 %U +Icon=security-low +Name=Calculate SHA-1 checksum +Name[x-test]=xxCalculate SHA-1 checksumxx + +[Desktop Action KHashChecksumSHA256] +Exec=khash --algorithm=sha256 %U +Icon=security-medium +Name=Calculate SHA-256 checksum +Name[x-test]=xxCalculate SHA-256 checksumxx + +[Desktop Action KHashChecksumSHA512] +Exec=khash --algorithm=sha512 %U +Icon=security-high +Name=Calculate SHA-512 checksum +Name[x-test]=xxCalculate SHA-512 checksumxx + +[Desktop Action KHashChecksumKAT] +Exec=khash --algorithm=kat %U +Icon=security-medium +Name=Calculate KAT checksum +Name[x-test]=xxCalculate KAT checksumxx