Example #1
0
void CardReader::onSocketError(QAbstractSocket::SocketError error)
{
	// See http://stackoverflow.com/a/16390227
	const QMetaObject & metaObject = QAbstractSocket::staticMetaObject;
	QMetaEnum metaEnum = metaObject.enumerator(metaObject.indexOfEnumerator("SocketError"));
	frontend_error(QStringLiteral("Socket error: ") + metaEnum.valueToKey(error), false);
}
Example #2
0
bool CardReader::setupSsl(QString certificatePath, QString keyPath)
{
	// FIXME: This function leaks both QFile objects

	QFile *certificateFile = new QFile(certificatePath);
	certificateFile->open(QIODevice::ReadOnly);
	if(!certificateFile->exists()) {
		frontend_error("Certificate file doesn't exist", false);
		return false;
	}

	QList<QSslCertificate> certificateChain = QSslCertificate::fromDevice(certificateFile);
	certificateFile->close();
	if (certificateChain.size() == 0) {
		frontend_error("Invalid certificate chain specified", false);
		return false;
	}

	QFile *keyFile = new QFile(keyPath);
	keyFile->open(QIODevice::ReadOnly);
	if(!keyFile->exists()) {
		frontend_error("Key file doesn't exist", false);
		return false;
	}

	QSslKey key(keyFile, QSsl::Rsa);
	keyFile->close();
	if(key.isNull()) {
		frontend_error("Invalid key specified", false);
		return false;
	}

	QSslConfiguration sslConfiguration = QSslConfiguration::defaultConfiguration();
	sslConfiguration.setPeerVerifyMode(QSslSocket::VerifyNone);
	sslConfiguration.setProtocol(QSsl::SecureProtocols);
	sslConfiguration.setLocalCertificateChain(certificateChain);
	sslConfiguration.setPrivateKey(key);

	server = new QWebSocketServer(QStringLiteral("Arago Card Reader"), QWebSocketServer::SecureMode, this);
	server->setSslConfiguration(sslConfiguration);
	return true;
}
Example #3
0
void CardReader::setup()
{
	// Load configuration
	QString configurationFile = QCoreApplication::applicationDirPath() + QDir::separator() + "arago-card-reader.ini";
	QSettings settings(configurationFile, QSettings::IniFormat);
	quint64 port = settings.value("websocket/port", 3000).toInt();
	bool wants_tls = settings.value("websocket/tls", false).toBool();

	if(wants_tls && !QSslSocket::supportsSsl()) {
		frontend_message("Requested TLS, but TLS not supported by Qt platform...");
		wants_tls = false;
	}

	if(wants_tls &&
		this->setupSsl(settings.value("websocket/certificate", "").toString(), settings.value("websocket/key", "").toString())) {
		frontend_message("Enabling TLS on server...");
	} else {
		server = new QWebSocketServer(QStringLiteral("Arago Card Reader"), QWebSocketServer::NonSecureMode, this);
		frontend_message("Not enabling TLS on server...");
	}

	// Setup socket server
	frontend_message(QStringLiteral("Starting websocket server on port %1...").arg(port));
	if(!server->listen(QHostAddress::Any, port)) {
		frontend_error(QStringLiteral("Failed to setup server: %1").arg(server->errorString()), true);
		return;
	}

	connect(server, &QWebSocketServer::newConnection, this, &CardReader::onNewConnection);
	connect(server, &QWebSocketServer::acceptError, this, &CardReader::onSocketError);
	connect(server, &QWebSocketServer::serverError, this, &CardReader::onServerError);
	connect(server, &QWebSocketServer::sslErrors, this, &CardReader::onSslError);

	nfcThread = new NfcThread(settings.value("nfc/device", "").toString());
	connect(nfcThread, &NfcThread::cardScanned, this, &CardReader::onCardScanned);
	connect(nfcThread, &NfcThread::finished, nfcThread, &QObject::deleteLater);
	nfcThread->start();

	frontend_message("Started all processes...");
	emit started();
}
Example #4
0
	foreach(QSslError error, errors)
	{
		frontend_error(QStringLiteral("SSL error: ") + error.errorString(), false);
	}
Example #5
0
void CardReader::onServerError(QWebSocketProtocol::CloseCode closeCode)
{
	frontend_error(QStringLiteral("Server error: ") + QString(closeCode), false);
}
Example #6
0
////////////////////////////////////////////////////////////
// Argument Parsing
////////////////////////////////////////////////////////////
void Sigil::parseOptions(int argc, char *argv[])
{
    /* custom parsing, by order of the arguments */
    ArgGroup arg_group;

    /* Pass through args to frontend/backend. */
    arg_group.addGroup(frontend, false);
    arg_group.addGroup(backend, true);
    arg_group.addGroup(executable, true);
    arg_group.parse(argc, argv);

    /* The number of 'threads' Sigil2 will use */
    /* MDL20160805 Currently only valid with DynamoRIO frontend. 
     * This will cause 'n' event streams between Sigil2 and DynamoRIO
     * to be generated, and 'n' separate backend instances will
     * read from those event streams as separate threads */
    num_threads = 1;
    if (arg_group.getOpt(numthreads).empty() == false)
    {
        num_threads = stoi(arg_group.getOpt(numthreads));
        if (num_threads > 16 || num_threads < 1)
        {
            SigiLog::fatal("Invalid number of threads specified");
        }
    }

    /* check frontend */
    std::string frontend_name;

    if (arg_group.getGroup(frontend).empty() == false)
    {
        frontend_name = arg_group.getGroup(frontend)[0];
    }
    else /*set default*/
    {
        frontend_name = "valgrind"; //default
    }

    std::transform(frontend_name.begin(), frontend_name.end(), frontend_name.begin(), ::tolower);

    if (frontend_registry.find(frontend_name) != frontend_registry.cend())
    {
        start_frontend = [this, arg_group, frontend_name]() mutable
        {
            Sigil::Args args;
            if (arg_group.getGroup(frontend).size() > 1)
            {
                auto start = arg_group.getGroup(frontend).cbegin() + 1;
                auto end = arg_group.getGroup(frontend).cend();
                args = {start, end};
            }

            frontend_registry[frontend_name](arg_group.getGroup(executable),
                                             args,
                                             num_threads,
                                             instance_id);
        };
    }
    else
    {
        std::string frontend_error(" invalid frontend argument ");
        frontend_error.append(frontend_name).append("\n");

        frontend_error.append("\tAvailable frontends: ");

        for (auto p : frontend_registry)
        {
            frontend_error.append("\n\t").append(p.first);
        }

        SigiLog::fatal(frontend_error);
    }

    /* check backend */
    std::string backend_name = arg_group.getGroup(backend)[0];
    std::transform(backend_name.begin(), backend_name.end(), backend_name.begin(), ::tolower);

    if (backend_registry.find(backend_name) != backend_registry.cend())
    {
        /* send args to backend */
        Sigil::Args args;

        if (arg_group.getGroup(backend).size() > 1)
        {
            auto start = arg_group.getGroup(backend).cbegin() + 1;
            auto end = arg_group.getGroup(backend).cend();
            args = {start, end};
        }

        /* Register the backend
         *
         * Each backend thread creates a new
         * backend instance via 'create_backend' */
        parse_backend = [this, backend_name, args]()
        {
            std::get<1>(backend_registry[backend_name])(args);
        };
        create_backend = std::get<0>(backend_registry[backend_name]);
        exit_backend = std::get<2>(backend_registry[backend_name]);
    }
    else
    {
        std::string backend_error(" invalid backend argument ");
        backend_error.append(backend_name).append("\n");

        backend_error.append("\tAvailable backends: ");

        for (auto p : backend_registry)
        {
            backend_error.append("\n\t").append(p.first);
        }

        SigiLog::fatal(backend_error);
    }
}