The branch, master has been updated via fc019c57e118c79e8406dbe613f55f11e4c9beac (commit) from a992a08cf9c3f1a00b213f9bce08071154faffba (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit fc019c57e118c79e8406dbe613f55f11e4c9beac Author: Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> Date: Wed Oct 31 16:23:13 2012 +0100 create class X2GoBroker (only HTTP yet) ----------------------------------------------------------------------- Summary of changes: messagebox.cpp | 3 + messagebox.h | 8 +- profile.cpp | 2 + x2goapplication.cpp | 24 +- x2goapplication.h | 5 + x2gobroker.cpp | 296 +++++++++++++++++++++++ profiledetailconfiguratorform.h => x2gobroker.h | 64 ++--- x2goclient2.pro | 2 + 8 files changed, 372 insertions(+), 32 deletions(-) create mode 100644 x2gobroker.cpp copy profiledetailconfiguratorform.h => x2gobroker.h (61%) The diff of changes is: diff --git a/messagebox.cpp b/messagebox.cpp index 0b8ba33..ca2291d 100644 --- a/messagebox.cpp +++ b/messagebox.cpp @@ -96,7 +96,10 @@ void MessageBox::setupDialog(QString pix, QString text, int buttons, QString inp if(leInput->isHidden()) vlDisplayLayout->removeItem(hlInputLayout); else + { + leInput->selectAll(); leInput->setFocus(); + } } MessageBox::Buttons MessageBox::critical(QString text, int buttons) diff --git a/messagebox.h b/messagebox.h index 9a3f4cb..7b216dd 100644 --- a/messagebox.h +++ b/messagebox.h @@ -29,6 +29,10 @@ class MessageBox: public QMdiSubWindow, public Ui_MessageBox { Q_OBJECT public: + X2GO_PROPERTY_GETTER(QPushButton*, pbYes) + X2GO_PROPERTY_GETTER(QPushButton*, pbNo) + X2GO_PROPERTY_GETTER(QPushButton*, pbCancel) + X2GO_PROPERTY_GETTER(QPushButton*, pbOk) enum Buttons {YES=1,NO=2,OK=8,CANCEL=16}; private: QEventLoop* loop; @@ -44,11 +48,11 @@ public: static Buttons warning(QString text, int buttons); static Buttons input(QString text, QString inputLabel, QString& input, QLineEdit::EchoMode echoMode = QLineEdit::Normal, QString pixPath=QString::null); -private: MessageBox(); virtual ~MessageBox(); Buttons exec(); - void setupDialog(QString pix, QString text, int buttons, QString inputLabel = QString::null, QLineEdit::EchoMode echoMode = QLineEdit::Normal); + void setupDialog(QString pix, QString text, int buttons, QString inputLabel = QString::null, + QLineEdit::EchoMode echoMode = QLineEdit::Normal); }; #endif // MESSAGEBOX_H diff --git a/profile.cpp b/profile.cpp index 57bb433..8d2c8cd 100644 --- a/profile.cpp +++ b/profile.cpp @@ -243,6 +243,8 @@ void Profile::updateProfileDetails() desktopName=X2GoApplication::instance()->getReadableDesktopName(desktop); else desktopName=X2GoApplication::instance()->getReadableAppName(desktop); + if(desktopName.length()<=0) + desktopName=desktop; QString infoText=desktopName+ " ("+user+"@"+server+"), "+tr("display:")+" "+display+", "+tr("sound:")+" "+snd; QString statusText="not running"; diff --git a/x2goapplication.cpp b/x2goapplication.cpp index 4112ff6..8abe77f 100644 --- a/x2goapplication.cpp +++ b/x2goapplication.cpp @@ -32,6 +32,7 @@ #include "x2goclientconfig.h" #include "helpdialog.h" #include "mainwindow.h" +#include "x2gobroker.h" X2GoApplication::X2GoApplication(int& argc, char** argv, int flags): QApplication(argc, argv, flags) { @@ -57,12 +58,17 @@ X2GoApplication::X2GoApplication(int& argc, char** argv, int flags): QApplicatio X2GoApplication::~X2GoApplication() { delete clientConfig; - delete sessionSettings; + if(sessionSettings) + delete sessionSettings; + if(broker) + delete broker; qDebug()<<"X2Go Application exited"; } void X2GoApplication::slotInitApplication() { + broker=0; + sessionSettings=0; clientConfig=new X2GoClientConfig; clientConfig->loadConfigFiles(); if(!clientConfig->parseCommandLineArguments(arguments())) @@ -87,10 +93,24 @@ void X2GoApplication::slotInitApplication() { sessionSettings=new X2GoSettings("sessions"); initProfiles(); + mainWindow->show(); } - mainWindow->show(); + else + { + mainWindow->show(); + broker=new X2GoBroker(); + connect(broker, SIGNAL(signalSessionsLoaded()), this, SLOT(slotBrokerSessionsConfig())); + broker->getUserSessions(); + } +} + +void X2GoApplication::slotBrokerSessionsConfig() +{ + sessionSettings=new X2GoSettings(broker->get_sessionsConfig(),QSettings::IniFormat); + initProfiles(); } + X2GoApplication* X2GoApplication::instance() { return (X2GoApplication*) QApplication::instance(); diff --git a/x2goapplication.h b/x2goapplication.h index 69227cf..0f0b543 100644 --- a/x2goapplication.h +++ b/x2goapplication.h @@ -40,6 +40,7 @@ class MainWindow; class ProfileDetailConfiguratorForm; class X2GoClientConfig; class X2GoSettings; +class X2GoBroker; struct nameTranslator { @@ -68,6 +69,7 @@ class X2GoApplication: public QApplication X2GO_PROPERTY(ProfileDetailConfiguratorForm*, profileDetailConfiguratorForm) X2GO_RO_PROPERTY(X2GoClientConfig*, clientConfig) X2GO_RO_PROPERTY(X2GoSettings*, sessionSettings) + X2GO_RO_PROPERTY(X2GoBroker*, broker) public: ~X2GoApplication(); X2GoApplication(int& argc, char** argv, int = ApplicationFlags); @@ -114,6 +116,9 @@ public: { return getTranslator(desktopNames, index); } + +private slots: + void slotBrokerSessionsConfig(); signals: void signalUpdateProfiles(); void signalProfilesSelectionChanged(Profile* profile); diff --git a/x2gobroker.cpp b/x2gobroker.cpp new file mode 100644 index 0000000..714ce11 --- /dev/null +++ b/x2gobroker.cpp @@ -0,0 +1,296 @@ +/************************************************************************** +* Copyright (C) 2005-2012 by Oleksandr Shneyder * +* o.shneyder@phoca-gmbh.de * +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of the GNU 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 General Public License for more details. * +* * +* You should have received a copy of the GNU General Public License * +* along with this program; if not, write to the * +* Free Software Foundation, Inc., * +* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * +***************************************************************************/ +#include <QHttp> +#include <QTextStream> +#include <QFile> +#include <QDir> +#include <QDebug> +#include "x2gobroker.h" +#include "x2goapplication.h" +#include "x2goclientconfig.h" +#include "messagebox.h" + +X2GoBroker::X2GoBroker(QObject* parent): QObject(parent) +{ + http=0; + X2GoClientConfig* cfg=X2GoApplication::instance()->get_clientConfig(); + QString urlString=cfg->get_brokerUrl().get_value().toString(); + url = QUrl( urlString); + if(url.userName().length()>0) + user=url.userName(); + if(urlString.indexOf("ssh://")==0) + { + brokerType=SSH; + } + else + { + brokerType=HTTP; + http=new QHttp ( this ); + if ( urlString.indexOf ( "https://" ) ==0 ) + http->setHost ( url.host(),QHttp::ConnectionModeHttps, + url.port ( 443 ) ); + else + http->setHost ( url.host(),QHttp::ConnectionModeHttp, + url.port ( 80 ) ); + connect ( http,SIGNAL ( requestFinished ( int,bool ) ),this, + SLOT ( slotRequestFinished ( int,bool ) ) ); + connect ( http,SIGNAL ( sslErrors ( const QList<QSslError>& ) ),this, + SLOT ( slotSslErrors ( const QList<QSslError>& ) ) ); + } + if(cfg->get_authId().get_value().toString()!=QString::null) + { + QFile file(cfg->get_authId().get_value().toString()); + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) + { + MessageBox::critical(tr("Can't open file")+" - "+cfg->get_authId().get_value().toString(), MessageBox::OK); + X2GoApplication::exit(-1); + } + QTextStream in(&file); + authId = in.readLine(); + } + if(!cfg->get_defaultNoBrockerAuth().get_value().toBool()) + { + getLoginData(); + } +} + +X2GoBroker::~X2GoBroker() +{ + if(http) + delete http; +} + +void X2GoBroker::getLoginData() +{ + if(url.userName().length()<=0) + { + MessageBox::Buttons res=MessageBox::input(tr("Enter user name for authentication on broker"),tr("User:"),user); + if(res!=MessageBox::OK) + X2GoApplication::exit(-1); + } + pass=QString::null; + MessageBox::Buttons res=MessageBox::input(tr("Enter password for authentication on broker"),tr("Password:"),pass, QLineEdit::Password); + if(res!=MessageBox::OK) + X2GoApplication::exit(-1); +} + + +void X2GoBroker::getUserSessions() +{ + if(brokerType==HTTP) + { + QString req; + QTextStream ( &req ) << + "task=listsessions&"<< + "user="<<user<<"&"<< + "password="<<pass<<"&"<< + "authid="<<authId; + httpSessionAnswer.close(); + httpSessionAnswer.setData ( 0,0 ); + sessionsRequest=http->post ( url.path(),req.toUtf8(),&httpSessionAnswer ); + } +} + +void X2GoBroker::slotRequestFinished(int id, bool error) +{ + if ( error ) + { + MessageBox::critical("<b>"+tr("Error")+"</b><br>"+http->errorString(),MessageBox::OK); + X2GoApplication::exit(-1); + return; + } + + QString answer ( httpSessionAnswer.data() ); + qDebug()<<answer; + if (id == sessionsRequest) + { + slotListSessions(true, answer,0); + } +// if (id == selSessRequest) +// { +// slotSelectSession(true,answer,0); +// } +} + +void X2GoBroker::slotListSessions(bool success, QString answer, int) +{ + if(!success) + { + MessageBox::critical("<b>"+tr("Error")+"</b><br>"+answer,MessageBox::OK); + X2GoApplication::exit(-1); + } + if(!checkAccess(answer)) + { + getLoginData(); + getUserSessions(); + return; + } + createIniFile(answer); + emit signalSessionsLoaded(); + +} + +void X2GoBroker::createIniFile(const QString& content) +{ + QString cont; + QStringList lines=content.split("START_USER_SESSIONS<br>"); + if (lines.count()>1) + { + cont=lines[1]; + cont=cont.split("END_USER_SESSIONS")[0]; + cont.replace("\n",""); + cont.replace("<br>","\n"); + } + sessionsConfig=cont; +} + +bool X2GoBroker::checkAccess(QString answer) +{ + if (answer.indexOf("Access granted")==-1) + { + MessageBox::critical ( + "<b>"+tr ( "Error" )+"</b><br>"+ + tr ( "Login failed!<br>" + "Please try again" ),MessageBox::OK ); + return false; + } + return true; +} + + +void X2GoBroker::slotSslErrors(const QList< QSslError >& errors) +{ + QStringList err; + QSslCertificate cert; + for ( int i=0; i<errors.count(); ++i ) + { + err<<errors[i].errorString(); + if ( !errors[i].certificate().isNull() ) + cert=errors[i].certificate(); + } + QString md5=getHexVal ( cert.digest() ); + QString fname=md5; + fname=fname.replace(":","_"); + QString homeDir=QDir::homePath(); + if ( QFile::exists ( homeDir+"/ssl/exceptions/"+ + url.host() +"/"+fname ) ) + { + QFile fl ( homeDir+"/ssl/exceptions/"+ + url.host() +"/"+fname ); + fl.open ( QIODevice::ReadOnly | QIODevice::Text ); + QSslCertificate mcert ( &fl ); + if ( mcert==cert ) + { + http->ignoreSslErrors(); + requestTime.restart(); + return; + } + } + + QString errText=tr ( "<br><b>Server uses an invalid " + "security certificate.</b><br><br>" ); + errText+=err.join ( "<br>" ); + errText+=tr ( "<p style='background:#FFFFDC;'>" + "You should not add an exception " + "if you are using an internet connection " + "that you do not trust completely or if you are " + "not used to seeing a warning for this server.</p>" ); + QString text=QString::null; + QTextStream ( &text ) <<err.join ( "\n" ) <<"\n"<< + "------------\n"<< + tr ( "Issued to:\n" ) << + tr ( "Common Name(CN)\t" ) << + cert.issuerInfo ( QSslCertificate::CommonName ) + <<endl<< + tr ( "Organization(O)\t" ) << + cert.issuerInfo ( QSslCertificate::Organization ) + <<endl<< + tr ( "Organizational Unit(OU)\t" ) << + cert.issuerInfo ( QSslCertificate::OrganizationalUnitName ) + <<endl<< + tr ( "Serial Number\t" ) <<getHexVal ( cert.serialNumber() ) + <<endl<<endl<< + tr ( "Issued by:\n" ) << + tr ( "Common Name(CN)\t" ) << + cert.subjectInfo ( QSslCertificate::CommonName ) + <<endl<< + tr ( "Organization(O)\t" ) << + cert.subjectInfo ( QSslCertificate::Organization ) + <<endl<< + tr ( "Organizational Unit(OU)\t" ) << + cert.subjectInfo ( QSslCertificate::OrganizationalUnitName ) + <<endl<<endl<< + + tr ( "Validity:\n" ) << + tr ( "Issued on\t" ) <<cert.effectiveDate().toString() <<endl<< + tr ( "expires on\t" ) <<cert.expiryDate().toString() <<endl<<endl<< + tr ( "Fingerprints:\n" ) << + tr ( "SHA1\t" ) << + getHexVal ( cert.digest ( QCryptographicHash::Sha1 ) ) <<endl<< + tr ( "MD5\t" ) <<md5; + + MessageBox mb; + mb.setupDialog(":/icons/32x32/critical.png", errText, MessageBox::YES|MessageBox::OK|MessageBox::CANCEL); + mb.get_pbYes()->setText(tr("Show Details...")); + mb.get_pbOk()->setText(tr ( "Add exception")); + mb.get_pbCancel()->setText(tr ( "Exit X2Go Client")); + while(true) + { + switch (mb.exec()) + { + case MessageBox::OK: + { + QDir dr; + dr.mkpath ( homeDir+"/ssl/exceptions/"+url.host() +"/" ); + QFile fl ( homeDir+"/ssl/exceptions/"+ + url.host() +"/"+fname ); + fl.open ( QIODevice::WriteOnly | QIODevice::Text ); + QTextStream ( &fl ) <<cert.toPem(); + fl.close(); + http->ignoreSslErrors(); + requestTime.restart(); + return; + } + case MessageBox::CANCEL: + { + X2GoApplication::exit(-1); + return; + } + default: + { + MessageBox::information(text, MessageBox::OK); + break; + } + } + } +} + +QString X2GoBroker::getHexVal(const QByteArray& ba) +{ + QStringList val; + for ( int i=0; i<ba.size(); ++i ) + { + QString bt; + bt.sprintf ( "%02X", ( unsigned char ) ba[i] ); + val<<bt; + } + return val.join ( ":" ); +} + diff --git a/profiledetailconfiguratorform.h b/x2gobroker.h similarity index 61% copy from profiledetailconfiguratorform.h copy to x2gobroker.h index c8b2a8c..68dee95 100644 --- a/profiledetailconfiguratorform.h +++ b/x2gobroker.h @@ -19,41 +19,49 @@ ***************************************************************************/ -#ifndef PROFILEDETAILCONFIGURATORFORM_H -#define PROFILEDETAILCONFIGURATORFORM_H +#ifndef X2GOBROKER_H +#define X2GOBROKER_H -#include <QWidget> -#include "ui_profiledetailconfiguratorform.h" +#include <QObject> +#include <QUrl> +#include <QBuffer> +#include <QSslError> +#include <QTime> #include "x2goapplication.h" +class QHttp; -class ToolBar; -class ProfileDetailConfigurator; -class Profile; - -class ProfileDetailConfiguratorForm : public QWidget, public Ui_ProfileDetailConfiguratorForm +class X2GoBroker : public QObject { + X2GO_RO_PROPERTY(QString, sessionsConfig) Q_OBJECT public: - enum configuratorType {PROFILE, SERVER, SESSIONTYPE, CONNECTION, DISPLAY, KEYBOARD, SOUND, PRINTING, FOLDERS}; - ProfileDetailConfiguratorForm(QWidget* parent = 0, Qt::WindowFlags f = 0); - ~ProfileDetailConfiguratorForm(); - void setConfigurator(Profile* profile, configuratorType type); - -private slots: - void slotApply(); - void slotDefaults(); - void slotReset(); - void slotBack(); - void slotOk(); - void slotDetailModified(); - + explicit X2GoBroker(QObject* parent = 0); + virtual ~X2GoBroker(); + void getUserSessions(); private: - void setModified(bool value); - + enum {SSH,HTTP} brokerType; + QString user; + QString pass; + QString authId; + QHttp* http; + QUrl url; + QBuffer httpCmdAnswer; + QBuffer httpSessionAnswer; + int sessionsRequest; + int selSessRequest; + QTime requestTime; private: - ToolBar* toolBar; - bool modified; - ProfileDetailConfigurator* profileDetailConfigurator; + void getLoginData(); + QString getHexVal ( const QByteArray& ba ); + bool checkAccess(QString answer); + void createIniFile(const QString& content); + +private slots: + void slotRequestFinished ( int id, bool error ); + void slotSslErrors ( const QList<QSslError> & errors ) ; + void slotListSessions ( bool success, QString answer, int pid); +signals: + void signalSessionsLoaded(); }; -#endif // PROFILEDETAILCONFIGURATORFORM_H +#endif // X2GOBROKER_H diff --git a/x2goclient2.pro b/x2goclient2.pro index 4484450..ea126d0 100755 --- a/x2goclient2.pro +++ b/x2goclient2.pro @@ -55,6 +55,7 @@ SOURCES += main.cpp \ x2goclientconfigdetail.cpp \ x2gosettings.cpp \ helpdialog.cpp \ + x2gobroker.cpp \ profile.cpp HEADERS += mainwindow.h \ @@ -82,6 +83,7 @@ HEADERS += mainwindow.h \ x2goclientconfigdetail.h \ x2gosettings.h \ helpdialog.h \ + x2gobroker.h \ profile.h LIBS += -lssh hooks/post-receive -- x2goclient2.git (X2Go Client 2 (rewrite of x2goclient.git)) This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "x2goclient2.git" (X2Go Client 2 (rewrite of x2goclient.git)).