#ifndef KEYGENERATOR_H #define KEYGENERATOR_H #include <QObject> #include <QString> #include <QStringList> // Simple QML object to generate SSH key pairs by calling ssh-keygen. class KeyGenerator : public QObject { Q_OBJECT Q_PROPERTY(QString type READ type WRITE setType NOTIFY typeChanged) Q_PROPERTY(QStringList types READ types NOTIFY typesChanged) Q_PROPERTY(QString filename READ filename WRITE setFilename NOTIFY filenameChanged) Q_PROPERTY(QString passphrase READ passphrase WRITE setPassphrase NOTIFY passphraseChanged) public: KeyGenerator(); ~KeyGenerator(); QString type(); void setType(const QString &t); QStringList types(); QString filename(); void setFilename(const QString &f); QString passphrase(); void setPassphrase(const QString &p); public slots: void generateKey(); signals: void typeChanged(); void typesChanged(); void filenameChanged(); void passphraseChanged(); void keyGenerated(bool success); private: QString _type; QString _filename; QString _passphrase; QStringList _types; }; #endif
#include <QFile> #include <QProcess> #include "KeyGenerator.h" KeyGenerator::KeyGenerator() : _type("rsa"), _types{"dsa", "ecdsa", "rsa", "rsa1"} { } KeyGenerator::~KeyGenerator() { } QString KeyGenerator::type() { return _type; } void KeyGenerator::setType(const QString &t) { // Check for valid type. if (!_types.contains(t)) return; if (t != _type) { _type = t; emit typeChanged(); } } QStringList KeyGenerator::types() { return _types; } QString KeyGenerator::filename() { return _filename; } void KeyGenerator::setFilename(const QString &f) { if (f != _filename) { _filename = f; emit filenameChanged(); } } QString KeyGenerator::passphrase() { return _passphrase; } void KeyGenerator::setPassphrase(const QString &p) { if (p != _passphrase) { _passphrase = p; emit passphraseChanged(); } } void KeyGenerator::generateKey() { // Sanity check on arguments if (_type.isEmpty() or _filename.isEmpty() or (_passphrase.length() > 0 and _passphrase.length() < 5)) { emit keyGenerated(false); return; } // Remove key file if it already exists if (QFile::exists(_filename)) { QFile::remove(_filename); } // Execute ssh-keygen -t type -N passphrase -f keyfileq QProcess *proc = new QProcess; QString prog = "ssh-keygen"; QStringList args{"-t", _type, "-N", _passphrase, "-f", _filename}; proc->start(prog, args); proc->waitForFinished(); emit keyGenerated(proc->exitCode() == 0); delete proc; }
// SSH key generator UI import QtQuick 2.1 import QtQuick.Controls 1.0 import QtQuick.Layouts 1.0 import QtQuick.Dialogs 1.0 import com.ics.demo 1.0 ApplicationWindow { title: qsTr("SSH Key Generator") statusBar: StatusBar { RowLayout { Label { id: status } } } width: 369 height: 166 ColumnLayout { x: 10 y: 10 // Key type RowLayout { Label { text: qsTr("Key type:") } ComboBox { id: combobox Layout.fillWidth: true model: keygen.types currentIndex: 2 } } // Filename RowLayout { Label { text: qsTr("Filename:") } TextField { id: filename implicitWidth: 200 onTextChanged: updateStatusBar() } Button { text: qsTr("&Browse...") onClicked: filedialog.visible = true } } // Passphrase RowLayout { Label { text: qsTr("Pass phrase:") } TextField { id: passphrase Layout.fillWidth: true echoMode: TextInput.Password onTextChanged: updateStatusBar() } } // Confirm Passphrase RowLayout { Label { text: qsTr("Confirm pass phrase:") } TextField { id: confirm Layout.fillWidth: true echoMode: TextInput.Password onTextChanged: updateStatusBar() } } // Buttons: Generate, Quit RowLayout { Button { id: generate text: qsTr("&Generate") onClicked: keygen.generateKey() } Button { text: qsTr("&Quit") onClicked: Qt.quit() } } } FileDialog { id: filedialog title: qsTr("Select a file") selectMultiple: false selectFolder: false nameFilters: [ "All files (*)" ] selectedNameFilter: "All files (*)" onAccepted: { filename.text = fileUrl.toString().replace("file://", "") } } KeyGenerator { id: keygen filename: filename.text passphrase: passphrase.text type: combobox.currentText onKeyGenerated: { if (success) { status.text = qsTr('<font color="green">Key generation succeeded.</font>') } else { status.text = qsTr('<font color="red">Key generation failed</font>') } } } function updateStatusBar() { if (passphrase.text != confirm.text) { status.text = qsTr('<font color="red">Pass phrase does not match.</font>') generate.enabled = false } else if (passphrase.text.length > 0 && passphrase.text.length < 5) { status.text = qsTr('<font color="red">Pass phrase too short.</font>') generate.enabled = false } else if (filename.text == "") { status.text = qsTr('<font color="red">Enter a filename.</font>') generate.enabled = false } else { status.text = "" generate.enabled = true } } Component.onCompleted: updateStatusBar() }
qmlRegisterType<KeyGenerator>("com.ics.demo", 1, 0, "KeyGenerator");
#include <QApplication> #include <QObject> #include <QQmlComponent> #include <QQmlEngine> #include <QQuickWindow> #include <QSurfaceFormat> #include "KeyGenerator.h" // Main wrapper program. // Special handling is needed when using Qt Quick Controls for the top window. // The code here is based on what qmlscene does. int main(int argc, char ** argv) { QApplication app(argc, argv); // Register our component type with QML. qmlRegisterType<KeyGenerator>("com.ics.demo", 1, 0, "KeyGenerator"); int rc = 0; QQmlEngine engine; QQmlComponent *component = new QQmlComponent(&engine); QObject::connect(&engine, SIGNAL(quit()), QCoreApplication::instance(), SLOT(quit())); component->loadUrl(QUrl("main.qml")); if (!component->isReady() ) { qWarning("%s", qPrintable(component->errorString())); return -1; } QObject *topLevel = component->create(); QQuickWindow *window = qobject_cast<QQuickWindow *>(topLevel); QSurfaceFormat surfaceFormat = window->requestedFormat(); window->setFormat(surfaceFormat); window->show(); rc = app.exec(); delete component; return rc; }
Source: https://habr.com/ru/post/197374/
All Articles