[X2Go-Commits] x2goclient.git - master (branch) updated: 4.0.1.1-63-ga77d761

X2Go dev team git-admin at x2go.org
Thu Dec 12 11:14:18 CET 2013


The branch, master has been updated
       via  a77d761dbb16d28206e7c2446654539935746e4e (commit)
      from  1c7a4f1aa2694eec916fe1e35998b931cd089f8f (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 a77d761dbb16d28206e7c2446654539935746e4e
Author: Oleksandr Shneyder <o.shneyder at phoca-gmbh.de>
Date:   Tue Dec 10 13:38:31 2013 +0100

    Support for GSSApi(Kerberos 5) authentication. Using ssh/scp commands on Linux and Mac and plink/pscp on Windows.

-----------------------------------------------------------------------

Summary of changes:
 debian/changelog        |    2 +
 onmainwindow.cpp        |   11 +-
 sessionwidget.cpp       |    2 -
 sharewidget.cpp         |  450 +++++++++++++++++++++++------------------------
 sshmasterconnection.cpp |  163 ++++++++++++++++-
 sshmasterconnection.h   |    1 +
 sshprocess.cpp          |  203 +++++++++++++++++++--
 sshprocess.h            |   12 +-
 8 files changed, 588 insertions(+), 256 deletions(-)

The diff of changes is:
diff --git a/debian/changelog b/debian/changelog
index 5b02cb9..f8d5a5b 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -58,6 +58,8 @@ x2goclient (4.0.1.2-0x2go2) UNRELEASED; urgency=low
     - Support for keys "shadowuser" "shadowdisplay" and "shadowmode" in
       config file. This allows choosing the default display for shadow
       sessions.
+    - Support for GSSApi(Kerberos 5) authentication. Using ssh/scp commands
+      on Linux and Mac and plink/pscp on Windows.   
 
   [ Heinrich Schuchardt ]
   * New upstream version (4.0.1.2):
diff --git a/onmainwindow.cpp b/onmainwindow.cpp
index 3b5b319..7a0a2a8 100644
--- a/onmainwindow.cpp
+++ b/onmainwindow.cpp
@@ -2989,8 +2989,8 @@ void ONMainWindow::slotSshServerAuthError ( int error, QString sshMessage, SshMa
                     "For security reasons, it is recommended to stop the connection.\n"
                     "Do you want to terminate the connection?\n" );
         if ( !QMessageBox::warning( 0, tr( "Host key verification failed" ),
-                errMsg, tr( "Yes" ), tr( "No" ) ) != 0)
-            {
+                                    errMsg, tr( "Yes" ), tr( "No" ) ) != 0)
+        {
             connection->writeKnownHosts(false);
             connection->wait();
             if(sshConnection && sshConnection !=connection)
@@ -3016,8 +3016,8 @@ void ONMainWindow::slotSshServerAuthError ( int error, QString sshMessage, SshMa
                     "For security reasons, it is recommended to stop the connection.\n"
                     "Do you want to terminate the connection?\n");
         if ( !QMessageBox::warning( 0, tr( "Host key verification failed" ),
-                errMsg, tr( "Yes" ), tr( "No" ) ) != 0)
-            {
+                                    errMsg, tr( "Yes" ), tr( "No" ) ) != 0)
+        {
             connection->writeKnownHosts(false);
             connection->wait();
             if(sshConnection && sshConnection !=connection)
@@ -3493,6 +3493,7 @@ bool ONMainWindow::startSession ( const QString& sid )
 void ONMainWindow::slotListSessions ( bool result,QString output,
                                       int  )
 {
+    x2goDebug<<output;
     if ( result==false )
     {
         cardReady=false;
@@ -4406,7 +4407,7 @@ void ONMainWindow::selectSession ( QStringList& sessions )
                     else
                         shadowMode=SHADOW_VIEWONLY;
                     startNewSession();
-		    return;
+                    return;
                 }
             }
         }
diff --git a/sessionwidget.cpp b/sessionwidget.cpp
index 9e54d19..179e6da 100644
--- a/sessionwidget.cpp
+++ b/sessionwidget.cpp
@@ -267,8 +267,6 @@ SessionWidget::SessionWidget ( QString id, ONMainWindow * mw,
     connect (cbProxySameUser, SIGNAL(clicked(bool)), this, SLOT(slot_proxySameLogin()));
 
     readConfig();
-    cbKrbLogin->setChecked(false);
-    cbKrbLogin->setVisible(false);
 }
 
 
diff --git a/sharewidget.cpp b/sharewidget.cpp
index 22b9380..1c24191 100644
--- a/sharewidget.cpp
+++ b/sharewidget.cpp
@@ -38,109 +38,109 @@
 
 ShareWidget::ShareWidget ( QString id, ONMainWindow * mw,
                            QWidget * parent, Qt::WindowFlags f )
-		: ConfigWidget ( id,mw,parent,f )
+    : ConfigWidget ( id,mw,parent,f )
 {
-	QGroupBox *egb=new QGroupBox ( tr ( "&Folders" ),this );
-	expTv=new QTreeView ( egb );
-	expTv->setItemsExpandable ( false );
-	expTv->setRootIsDecorated ( false );
+    QGroupBox *egb=new QGroupBox ( tr ( "&Folders" ),this );
+    expTv=new QTreeView ( egb );
+    expTv->setItemsExpandable ( false );
+    expTv->setRootIsDecorated ( false );
 
-	model=new QStandardItemModel ( 0,2 );
-	ldir=new QLabel ( egb );
+    model=new QStandardItemModel ( 0,2 );
+    ldir=new QLabel ( egb );
 
 
-	model->setHeaderData ( 0,Qt::Horizontal,QVariant (
-	                           ( QString ) tr ( "Path" ) ) );
-	model->setHeaderData ( 1,Qt::Horizontal,QVariant (
-	                           ( QString ) tr ( "Automount" ) ) );
-	expTv->setEditTriggers ( QAbstractItemView::NoEditTriggers );
+    model->setHeaderData ( 0,Qt::Horizontal,QVariant (
+                               ( QString ) tr ( "Path" ) ) );
+    model->setHeaderData ( 1,Qt::Horizontal,QVariant (
+                               ( QString ) tr ( "Automount" ) ) );
+    expTv->setEditTriggers ( QAbstractItemView::NoEditTriggers );
 
 
 
-	QPushButton* openDir=new QPushButton (
-	    QIcon ( mainWindow->iconsPath ( "/16x16/file-open.png" ) ),
-	    QString::null,egb );
+    QPushButton* openDir=new QPushButton (
+        QIcon ( mainWindow->iconsPath ( "/16x16/file-open.png" ) ),
+        QString::null,egb );
 
-	QPushButton* addDir=new QPushButton ( tr ( "Add" ),egb );
-	QPushButton* delDir=new QPushButton ( tr ( "Delete" ),egb );
+    QPushButton* addDir=new QPushButton ( tr ( "Add" ),egb );
+    QPushButton* delDir=new QPushButton ( tr ( "Delete" ),egb );
 #ifdef Q_WS_HILDON
-	QSize sz=addDir->sizeHint();
-	sz.setHeight ( ( int ) ( sz.height() /1.5 ) );
-	addDir->setFixedSize ( sz );
-	sz=delDir->sizeHint();
-	sz.setHeight ( ( int ) ( sz.height() /1.5 ) );
-	delDir->setFixedSize ( sz );
+    QSize sz=addDir->sizeHint();
+    sz.setHeight ( ( int ) ( sz.height() /1.5 ) );
+    addDir->setFixedSize ( sz );
+    sz=delDir->sizeHint();
+    sz.setHeight ( ( int ) ( sz.height() /1.5 ) );
+    delDir->setFixedSize ( sz );
 #endif
 
-	QLabel *dirPrompt=new QLabel ( tr ( "Path:" ),egb );
-	dirPrompt->setFixedSize ( dirPrompt->sizeHint() );
-	openDir->setFixedSize ( openDir->sizeHint() );
-
-	ldir->setFrameStyle ( QFrame::StyledPanel|QFrame::Sunken );
-
-	cbFsConv=new QCheckBox (
-	    tr ( "Filename encoding"
-	       ),egb );
-
-	QHBoxLayout* enclay=new QHBoxLayout;
-	cbFrom=new QComboBox ( egb );
-	cbTo=new QComboBox ( egb );
-	lFrom=new QLabel ( tr ( "local:" ),egb );
-	lTo=new QLabel ( tr ( "remote:" ),egb );
-
-	enclay->addWidget ( cbFsConv );
-	enclay->addWidget ( lFrom );
-	enclay->addWidget ( cbFrom );
-	enclay->addWidget ( lTo );
-	enclay->addWidget ( cbTo );
-	enclay->addStretch();
-	loadEnc ( cbFrom );
-	loadEnc ( cbTo );
-
-	cbFsSshTun=new QCheckBox (
-	    tr ( "Use ssh port forwarding to tunnel file system "
-	         "connections through firewalls" ),egb );
-
-	QVBoxLayout* expLay=new QVBoxLayout ( this );
-	expLay->addWidget ( egb );
-
-	QHBoxLayout *tvLay=new QHBoxLayout ( egb );
-
-	QHBoxLayout *dirLAy=new QHBoxLayout();
-	dirLAy->addWidget ( dirPrompt );
-	dirLAy->addWidget ( ldir );
-	dirLAy->addWidget ( openDir );
-
-	QVBoxLayout* leftLay=new QVBoxLayout();
-	leftLay->addLayout ( dirLAy );
-	leftLay->addSpacing ( 10 );
-	leftLay->addWidget ( expTv );
-	expLay->addLayout ( enclay );
-	expLay->addWidget ( cbFsSshTun );
-
-	QVBoxLayout* rightLay=new QVBoxLayout();
-	rightLay->addWidget ( addDir );
-	rightLay->addStretch();
-	rightLay->addWidget ( delDir );
-	rightLay->addStretch();
-
-
-	tvLay->addLayout ( leftLay );
-	tvLay->addSpacing ( 10 );
-	tvLay->addLayout ( rightLay );
-
-
-
-	expTv->setModel ( ( QAbstractItemModel* ) model );
-	QFontMetrics fm1 ( expTv->font() );
-	expTv->header()->resizeSection ( 1,
-	                                 fm1.width ( tr ( "Automount" ) ) +10 );
-	connect ( openDir,SIGNAL ( clicked() ),this,SLOT ( slot_openDir() ) );
-	connect ( addDir,SIGNAL ( clicked() ),this,SLOT ( slot_addDir() ) );
-	connect ( delDir,SIGNAL ( clicked() ),this,SLOT ( slot_delDir() ) );
-	connect ( cbFsConv,SIGNAL ( clicked() ),this
-	          ,SLOT ( slot_convClicked() ) );
-	readConfig();
+    QLabel *dirPrompt=new QLabel ( tr ( "Path:" ),egb );
+    dirPrompt->setFixedSize ( dirPrompt->sizeHint() );
+    openDir->setFixedSize ( openDir->sizeHint() );
+
+    ldir->setFrameStyle ( QFrame::StyledPanel|QFrame::Sunken );
+
+    cbFsConv=new QCheckBox (
+        tr ( "Filename encoding"
+           ),egb );
+
+    QHBoxLayout* enclay=new QHBoxLayout;
+    cbFrom=new QComboBox ( egb );
+    cbTo=new QComboBox ( egb );
+    lFrom=new QLabel ( tr ( "local:" ),egb );
+    lTo=new QLabel ( tr ( "remote:" ),egb );
+
+    enclay->addWidget ( cbFsConv );
+    enclay->addWidget ( lFrom );
+    enclay->addWidget ( cbFrom );
+    enclay->addWidget ( lTo );
+    enclay->addWidget ( cbTo );
+    enclay->addStretch();
+    loadEnc ( cbFrom );
+    loadEnc ( cbTo );
+
+    cbFsSshTun=new QCheckBox (
+        tr ( "Use ssh port forwarding to tunnel file system "
+             "connections through firewalls" ),egb );
+
+    QVBoxLayout* expLay=new QVBoxLayout ( this );
+    expLay->addWidget ( egb );
+
+    QHBoxLayout *tvLay=new QHBoxLayout ( egb );
+
+    QHBoxLayout *dirLAy=new QHBoxLayout();
+    dirLAy->addWidget ( dirPrompt );
+    dirLAy->addWidget ( ldir );
+    dirLAy->addWidget ( openDir );
+
+    QVBoxLayout* leftLay=new QVBoxLayout();
+    leftLay->addLayout ( dirLAy );
+    leftLay->addSpacing ( 10 );
+    leftLay->addWidget ( expTv );
+    expLay->addLayout ( enclay );
+    expLay->addWidget ( cbFsSshTun );
+
+    QVBoxLayout* rightLay=new QVBoxLayout();
+    rightLay->addWidget ( addDir );
+    rightLay->addStretch();
+    rightLay->addWidget ( delDir );
+    rightLay->addStretch();
+
+
+    tvLay->addLayout ( leftLay );
+    tvLay->addSpacing ( 10 );
+    tvLay->addLayout ( rightLay );
+
+
+
+    expTv->setModel ( ( QAbstractItemModel* ) model );
+    QFontMetrics fm1 ( expTv->font() );
+    expTv->header()->resizeSection ( 1,
+                                     fm1.width ( tr ( "Automount" ) ) +10 );
+    connect ( openDir,SIGNAL ( clicked() ),this,SLOT ( slot_openDir() ) );
+    connect ( addDir,SIGNAL ( clicked() ),this,SLOT ( slot_addDir() ) );
+    connect ( delDir,SIGNAL ( clicked() ),this,SLOT ( slot_delDir() ) );
+    connect ( cbFsConv,SIGNAL ( clicked() ),this
+              ,SLOT ( slot_convClicked() ) );
+    readConfig();
 }
 
 
@@ -150,211 +150,211 @@ ShareWidget::~ShareWidget()
 
 void ShareWidget::slot_openDir()
 {
-	QString startDir=ONMainWindow::getHomeDirectory();
+    QString startDir=ONMainWindow::getHomeDirectory();
 #ifdef Q_OS_WIN
-	if ( ONMainWindow::getPortable() &&
-	        ONMainWindow::U3DevicePath().length() >0 )
-	{
-		startDir=ONMainWindow::U3DevicePath() +"/";
-	}
+    if ( ONMainWindow::getPortable() &&
+            ONMainWindow::U3DevicePath().length() >0 )
+    {
+        startDir=ONMainWindow::U3DevicePath() +"/";
+    }
 #endif
 
-	QString path= QFileDialog::getExistingDirectory (
-	                  this,
-	                  tr ( "Select folder" ),
-	                  startDir );
-	if ( path!=QString::null )
-	{
+    QString path= QFileDialog::getExistingDirectory (
+                      this,
+                      tr ( "Select folder" ),
+                      startDir );
+    if ( path!=QString::null )
+    {
 #ifdef Q_OS_WIN
-		if ( ONMainWindow::getPortable() &&
-		        ONMainWindow::U3DevicePath().length() >0 )
-		{
-			if ( path.indexOf ( ONMainWindow::U3DevicePath() ) !=0 )
-			{
-				QMessageBox::critical (
-				    0l,tr ( "Error" ),
-				    tr ( "x2goclient is running in "
-				         "portable mode. You should "
-				         "use a path on your usb device "
-				         "to be able to access your data "
-				         "whereever you are" ),
-				    QMessageBox::Ok,QMessageBox::NoButton );
-				slot_openDir();
-				return;
-			}
-			path.replace ( ONMainWindow::U3DevicePath(),
-			               "(U3)" );
-		}
+        if ( ONMainWindow::getPortable() &&
+                ONMainWindow::U3DevicePath().length() >0 )
+        {
+            if ( path.indexOf ( ONMainWindow::U3DevicePath() ) !=0 )
+            {
+                QMessageBox::critical (
+                    0l,tr ( "Error" ),
+                    tr ( "x2goclient is running in "
+                         "portable mode. You should "
+                         "use a path on your usb device "
+                         "to be able to access your data "
+                         "whereever you are" ),
+                    QMessageBox::Ok,QMessageBox::NoButton );
+                slot_openDir();
+                return;
+            }
+            path.replace ( ONMainWindow::U3DevicePath(),
+                           "(U3)" );
+        }
 #endif
-		ldir->setText ( path );
-	}
+        ldir->setText ( path );
+    }
 }
 
 
 void ShareWidget::slot_addDir()
 {
-	QString path=ldir->text();
-	if ( path.length() <1 )
-		return;
-	for ( int i=0;i<model->rowCount();++i )
-		if ( model->index ( i,0 ).data().toString() ==path )
-			return;
-	QStandardItem *item;
-	item= new QStandardItem ( path );
-	model->setItem ( model->rowCount(),0,item );
-	item= new QStandardItem();
-	item->setCheckable ( true );
-	model->setItem ( model->rowCount()-1,1,item );
-	ldir->setText ( QString::null );
+    QString path=ldir->text();
+    if ( path.length() <1 )
+        return;
+    for ( int i=0; i<model->rowCount(); ++i )
+        if ( model->index ( i,0 ).data().toString() ==path )
+            return;
+    QStandardItem *item;
+    item= new QStandardItem ( path );
+    model->setItem ( model->rowCount(),0,item );
+    item= new QStandardItem();
+    item->setCheckable ( true );
+    model->setItem ( model->rowCount()-1,1,item );
+    ldir->setText ( QString::null );
 }
 
 
 void ShareWidget::slot_delDir()
 {
-	model->removeRow ( expTv->currentIndex().row() );
+    model->removeRow ( expTv->currentIndex().row() );
 }
 
 
 void ShareWidget::readConfig()
 {
 
-	X2goSettings st ( "sessions" );
+    X2goSettings st ( "sessions" );
 
-	QString exportDir=st.setting()->value ( sessionId+"/export",
-	                                        ( QVariant ) QString::null ).toString();
+    QString exportDir=st.setting()->value ( sessionId+"/export",
+                                            ( QVariant ) QString::null ).toString();
 
-	cbFsSshTun->setChecked ( st.setting()->value ( sessionId+"/fstunnel",
-	                         true ).toBool() );
-	QStringList lst=exportDir.split ( ";",QString::SkipEmptyParts );
+    cbFsSshTun->setChecked ( st.setting()->value ( sessionId+"/fstunnel",
+                             true ).toBool() );
+    QStringList lst=exportDir.split ( ";",QString::SkipEmptyParts );
 
-	QString toCode=st.setting()->value ( sessionId+"/iconvto",
-	                                     ( QVariant ) "UTF-8" ).toString();
+    QString toCode=st.setting()->value ( sessionId+"/iconvto",
+                                         ( QVariant ) "UTF-8" ).toString();
 
 #ifdef Q_OS_WIN
-	QString fromCode=st.setting()->value ( sessionId+"/iconvfrom",
-	                                       ( QVariant ) tr (
-	                                           "WINDOWS-1252" ) ).toString();
+    QString fromCode=st.setting()->value ( sessionId+"/iconvfrom",
+                                           ( QVariant ) tr (
+                                                   "WINDOWS-1252" ) ).toString();
 #endif
 #ifdef Q_OS_DARWIN
-	QString fromCode=st.setting()->value ( sessionId+"/iconvfrom",
-	                                       ( QVariant )
-	                                       "UTF-8" ).toString();
+    QString fromCode=st.setting()->value ( sessionId+"/iconvfrom",
+                                           ( QVariant )
+                                           "UTF-8" ).toString();
 #endif
 #ifdef Q_OS_LINUX
-	QString fromCode=st.setting()->value ( sessionId+"/iconvfrom",
-	                                       ( QVariant ) tr (
-	                                           "ISO8859-1" ) ).toString();
+    QString fromCode=st.setting()->value ( sessionId+"/iconvfrom",
+                                           ( QVariant ) tr (
+                                                   "ISO8859-1" ) ).toString();
 #endif
 
-	cbFsConv->setChecked ( st.setting()->value ( sessionId+"/useiconv",
-	                       ( QVariant ) false ).toBool() );
-	slot_convClicked();
+    cbFsConv->setChecked ( st.setting()->value ( sessionId+"/useiconv",
+                           ( QVariant ) false ).toBool() );
+    slot_convClicked();
 
-	int ind=cbFrom->findText ( fromCode );
-	if ( ind !=-1 )
-		cbFrom->setCurrentIndex ( ind );
+    int ind=cbFrom->findText ( fromCode );
+    if ( ind !=-1 )
+        cbFrom->setCurrentIndex ( ind );
 
-	ind=cbTo->findText ( toCode );
-	if ( ind !=-1 )
-		cbTo->setCurrentIndex ( ind );
+    ind=cbTo->findText ( toCode );
+    if ( ind !=-1 )
+        cbTo->setCurrentIndex ( ind );
 
-	for ( int i=0;i<lst.size();++i )
-	{
+    for ( int i=0; i<lst.size(); ++i )
+    {
 #ifndef Q_OS_WIN
-		QStringList tails=lst[i].split ( ":",QString::SkipEmptyParts );
+        QStringList tails=lst[i].split ( ":",QString::SkipEmptyParts );
 #else
-		QStringList tails=lst[i].split ( "#",QString::SkipEmptyParts );
+        QStringList tails=lst[i].split ( "#",QString::SkipEmptyParts );
 #endif
-		QStandardItem *item;
-		item= new QStandardItem ( tails[0] );
-		model->setItem ( model->rowCount(),0,item );
-		item= new QStandardItem();
-		item->setCheckable ( true );
-		if ( tails[1]=="1" )
-			item->setCheckState ( Qt::Checked );
-		model->setItem ( model->rowCount()-1,1,item );
-	}
+        QStandardItem *item;
+        item= new QStandardItem ( tails[0] );
+        model->setItem ( model->rowCount(),0,item );
+        item= new QStandardItem();
+        item->setCheckable ( true );
+        if ( tails[1]=="1" )
+            item->setCheckState ( Qt::Checked );
+        model->setItem ( model->rowCount()-1,1,item );
+    }
 }
 
 void ShareWidget::setDefaults()
 {
-	cbFsSshTun->setChecked ( true );
+    cbFsSshTun->setChecked ( true );
 
-	QString toCode="UTF-8";
+    QString toCode="UTF-8";
 
 #ifdef Q_OS_WIN
-	QString fromCode=tr ( "WINDOWS-1252" );
+    QString fromCode=tr ( "WINDOWS-1252" );
 #endif
 #ifdef Q_OS_DARWIN
-	QString fromCode="UTF-8";
+    QString fromCode="UTF-8";
 #endif
 #ifdef Q_OS_LINUX
-	QString fromCode=tr ( "ISO8859-1" );
+    QString fromCode=tr ( "ISO8859-1" );
 #endif
 
-	cbFsConv->setChecked ( false );
-	slot_convClicked();
+    cbFsConv->setChecked ( false );
+    slot_convClicked();
 
-	int ind=cbFrom->findText ( fromCode );
-	if ( ind !=-1 )
-		cbFrom->setCurrentIndex ( ind );
-	ind=cbTo->findText ( toCode );
-	if ( ind !=-1 )
-		cbTo->setCurrentIndex ( ind );
+    int ind=cbFrom->findText ( fromCode );
+    if ( ind !=-1 )
+        cbFrom->setCurrentIndex ( ind );
+    ind=cbTo->findText ( toCode );
+    if ( ind !=-1 )
+        cbTo->setCurrentIndex ( ind );
 }
 
 
 void ShareWidget::saveSettings()
 {
 
-	X2goSettings st ( "sessions" );
-	st.setting()->setValue ( sessionId+"/fstunnel",
-	                         ( QVariant ) cbFsSshTun->isChecked() );
+    X2goSettings st ( "sessions" );
+    st.setting()->setValue ( sessionId+"/fstunnel",
+                             ( QVariant ) cbFsSshTun->isChecked() );
 
-	QString exportDirs;
-	for ( int i=0;i<model->rowCount();++i )
-	{
+    QString exportDirs;
+    for ( int i=0; i<model->rowCount(); ++i )
+    {
 #ifndef Q_OS_WIN
-		exportDirs+=model->index ( i,0 ).data().toString() +":";
+        exportDirs+=model->index ( i,0 ).data().toString() +":";
 #else
-		exportDirs+=model->index ( i,0 ).data().toString() +"#";
+        exportDirs+=model->index ( i,0 ).data().toString() +"#";
 #endif
 
-		if ( model->item ( i,1 )->checkState() ==Qt::Checked )
-			exportDirs+="1;";
-		else
-			exportDirs+="0;";
-	}
-	st.setting()->setValue ( sessionId+"/export", ( QVariant ) exportDirs );
+        if ( model->item ( i,1 )->checkState() ==Qt::Checked )
+            exportDirs+="1;";
+        else
+            exportDirs+="0;";
+    }
+    st.setting()->setValue ( sessionId+"/export", ( QVariant ) exportDirs );
 
 
-	st.setting()->setValue ( sessionId+"/iconvto",cbTo->currentText() );
-	st.setting()->setValue ( sessionId+"/iconvfrom",cbFrom->currentText() );
-	st.setting()->setValue ( sessionId+"/useiconv",cbFsConv->isChecked() );
-	st.setting()->sync();
+    st.setting()->setValue ( sessionId+"/iconvto",cbTo->currentText() );
+    st.setting()->setValue ( sessionId+"/iconvfrom",cbFrom->currentText() );
+    st.setting()->setValue ( sessionId+"/useiconv",cbFsConv->isChecked() );
+    st.setting()->sync();
 }
 
 
 void ShareWidget::loadEnc ( QComboBox* cb )
 {
-	QFile file ( ":/txt/encodings" );
-	if ( !file.open ( QIODevice::ReadOnly | QIODevice::Text ) )
-		return;
-
-	QTextStream in ( &file );
-	while ( !in.atEnd() )
-	{
-		QString line = in.readLine();
-		line=line.replace ( "//","" );
-		cb->addItem ( line );
-	}
+    QFile file ( ":/txt/encodings" );
+    if ( !file.open ( QIODevice::ReadOnly | QIODevice::Text ) )
+        return;
+
+    QTextStream in ( &file );
+    while ( !in.atEnd() )
+    {
+        QString line = in.readLine();
+        line=line.replace ( "//","" );
+        cb->addItem ( line );
+    }
 }
 
 void ShareWidget::slot_convClicked()
 {
-	bool val=cbFsConv->isChecked();
-	cbTo->setEnabled ( val );
-	cbFrom->setEnabled ( val );
-	lTo->setEnabled ( val );
-	lFrom->setEnabled ( val );
+    bool val=cbFsConv->isChecked();
+    cbTo->setEnabled ( val );
+    cbFrom->setEnabled ( val );
+    lTo->setEnabled ( val );
+    lFrom->setEnabled ( val );
 }
diff --git a/sshmasterconnection.cpp b/sshmasterconnection.cpp
index 0672eb0..9a81853 100644
--- a/sshmasterconnection.cpp
+++ b/sshmasterconnection.cpp
@@ -47,13 +47,104 @@
 #define PROXYTUNNELPORT 44444
 
 #undef DEBUG
-// #define DEBUG
+#define DEBUG
 
 #undef SSH_DEBUG
 // #define SSH_DEBUG
 
 static bool isLibSshInited=false;
 
+
+#ifdef Q_OS_WIN
+#include <QSettings>
+// parse known_hosts file from libssh and export keys in registry to use with plink.exe
+void SshMasterConnection::parseKnownHosts()
+{
+    QFile fl(mainWnd->getHomeDirectory()+"/ssh/known_hosts");
+    if (!fl.open(QFile::ReadOnly))
+        return;
+    QSettings settings("HKEY_CURRENT_USER\\Software\\SimonTatham\\PuTTY\\SshHostKeys",
+                       QSettings::NativeFormat);
+    while (!fl.atEnd())
+    {
+        QString line=fl.readLine();
+        QStringList parts=line.split(' ',QString::SkipEmptyParts);
+        if (parts.count()!=3)
+            continue;
+
+        //lines in known_hosts have format:
+        //[host]:port <ssh-rsa|ssh-dss> <key>
+        //we proceeding only lines from libssh - no hashed hostnames
+        //or patterns are allowed
+
+        QString type="unknown";
+        QString port="22";
+        if (parts[1]=="ssh-dss")
+            type="dss";
+        if (parts[1]=="ssh-rsa")
+            type="rsa2";
+
+
+        QStringList hostParts=parts[0].split(":",QString::SkipEmptyParts);
+        if (hostParts.count()>1)
+            port=hostParts[1];
+        hostParts[0].replace("[","");
+        hostParts[0].replace("]","");
+
+        QString keyName=type+"@"+port+":"+hostParts[0];
+
+        QByteArray bytes=QByteArray::fromBase64(parts[2].toAscii());
+        QStringList fields;
+
+        //key is a set of data fields:
+        //[size][data][size][data].....[size][data]
+
+        for (int i=0; i<bytes.count();)
+        {
+            int size=0;
+            //first 4 bytes are for size of data fild (big-endian)
+            for (int j=0; j<4; ++j)
+            {
+                size+=((uchar)(bytes[i])) * pow(256,3-j);
+                i++;
+            }
+            QByteArray data;
+            data=bytes.mid(i,size);
+            QString hex;
+
+            for (int j=0; j<data.count(); ++j)
+            {
+                QString byte;
+                byte.sprintf("%02x",(uchar)(data[j]));
+                hex+=byte;
+            }
+            //remove leading '0'
+            for (;;)
+            {
+                if (hex.length()==0)
+                    break;
+                if (hex[0]=='0')
+                    hex.remove(0,1);
+                else
+                    break;
+            }
+            hex="0x"+hex;
+            fields<<hex;
+            i+=size;
+        }
+        //first element is a type of key, we don't need it
+        fields.removeFirst();
+        settings.setValue(keyName,fields.join(","));
+#ifdef DEBUG
+        x2goDebug<<"writing key in registry: HKEY_CURRENT_USER\\Software\\SimonTatham\\PuTTY\\SshHostKeys"<<endl;
+        x2goDebug<<keyName<<"="<<fields.join(",")<<endl;
+#endif
+    }
+    settings.sync();
+}
+#endif
+
+
 SshMasterConnection::SshMasterConnection (QObject* parent, QString host, int port, bool acceptUnknownServers, QString user,
         QString pass, QString key, bool autologin, bool krblogin,
         bool useproxy, ProxyType type, QString proxyserver, quint16 proxyport,
@@ -92,11 +183,14 @@ SshMasterConnection::SshMasterConnection (QObject* parent, QString host, int por
     kerberos=krblogin;
 #ifdef DEBUG
     if (kerberos)
+    {
         x2goDebug<<"starting ssh connection with kerberos authentication"<<endl;
+    }
     else
+    {
         x2goDebug<<"starting ssh connection without kerberos authentication"<<endl;
+    }
 #endif
-    kerberos=false;
 #ifdef DEBUG
     x2goDebug<<"SshMasterConnection, instance "<<this<<" created";
 #endif
@@ -359,6 +453,11 @@ void SshMasterConnection::run()
 
 #ifdef Q_OS_WIN
     ssh_options_set ( my_ssh_session, SSH_OPTIONS_SSH_DIR, (mainWnd->getHomeDirectory()+"/ssh").toAscii());
+    if (kerberos)
+    {
+        parseKnownHosts();
+    }
+
 #endif
     ssh_options_set(my_ssh_session, SSH_OPTIONS_LOG_VERBOSITY, &verbosity);
 
@@ -496,7 +595,13 @@ void SshMasterConnection::run()
         }
         QString err;
         if (!kerberos)
+        {
             err=ssh_get_error ( my_ssh_session );
+        }
+        else
+        {
+            err=sshProcErrString;
+        }
         QString message=tr ( "Authentication failed" );
 #ifdef DEBUG
         x2goDebug<<message<<" - "<<err;
@@ -870,9 +975,63 @@ bool SshMasterConnection::userAuthWithKey()
     return true;
 }
 
+bool SshMasterConnection::userAuthKrb()
+{
+    QProcess ssh;
+    QString sshCmd;
+
+#ifdef Q_OS_WIN
+    sshCmd="plink -batch "+user+"@"+host+" -P "+
+           QString::number(port)+ " whoami";
+#else
+    sshCmd="ssh -o GSSApiAuthentication=yes "+user+"@"+host+" -p "+
+           QString::number(port)+ " -o PasswordAuthentication=no whoami";
+#endif
+
+#ifdef DEBUG
+    x2goDebug<<"starting ssh:" <<sshCmd<<endl;
+#endif
+    ssh.start(sshCmd);
+
+
+    if (!ssh.waitForStarted(5000))
+    {
+        sshProcErrString=ssh.errorString();
+        authErrors<<sshProcErrString;
+#ifdef DEBUG
+        x2goDebug<<"ssh start failed:" <<sshProcErrString<<endl;
+#endif
+        return false;
+    }
+    if (!ssh.waitForFinished(20000))
+    {
+        sshProcErrString=ssh.errorString();
+        authErrors<<sshProcErrString;
+#ifdef DEBUG
+        x2goDebug<<"ssh not finished:" <<sshProcErrString<<endl;
+#endif
+        return false;
+    }
+    QString outp=ssh.readAllStandardOutput();
+    QString err=ssh.readAllStandardError();
+#ifdef DEBUG
+    x2goDebug<<"ssh exited\n";
+    x2goDebug<<"stdout - "<<outp<<endl;
+    x2goDebug<<"stderr - "<<err<<endl;
+    x2goDebug<<"code - "<<ssh.exitCode()<<", status - "<<ssh.exitStatus()<<endl;
+#endif
+    if (ssh.exitCode() == 0 && ssh.exitStatus() == 0)
+        return true;
+    sshProcErrString=err;
+    authErrors<<sshProcErrString;
+    return false;
+}
+
 
 bool SshMasterConnection::userAuth()
 {
+    if (kerberos)
+        return userAuthKrb();
     if ( autologin && key=="" )
         if ( userAuthAuto() )
             return true;
diff --git a/sshmasterconnection.h b/sshmasterconnection.h
index 43ad7f6..dda9772 100644
--- a/sshmasterconnection.h
+++ b/sshmasterconnection.h
@@ -114,6 +114,7 @@ private:
     bool userAuthAuto();
     bool userAuthWithKey();
     bool userAuth();
+    bool userAuthKrb();
     void channelLoop();
     void finalize(int arg1);
     void copy();
diff --git a/sshprocess.cpp b/sshprocess.cpp
index 1813142..69a057e 100644
--- a/sshprocess.cpp
+++ b/sshprocess.cpp
@@ -22,14 +22,20 @@
 #include <QTimer>
 #include <QUuid>
 
+#include <QProcess>
 #ifndef Q_OS_WIN
 #include <arpa/inet.h>
 #include <netinet/tcp.h>
 #endif
 
 #undef DEBUG
-// #define DEBUG
+#define DEBUG
 
+#ifdef Q_OS_DARWIN
+#define KEEPALIVE_OPTION " -o ServerAliveInterval=60 "
+#else
+#define KEEPALIVE_OPTION " -o ProtocolKeepAlives=60 "
+#endif
 
 SshProcess::SshProcess(SshMasterConnection* master, int pid): QObject(0)
 {
@@ -40,6 +46,8 @@ SshProcess::SshProcess(SshMasterConnection* master, int pid): QObject(0)
     tunnel=false;
     normalExited=true;
     this->pid=pid;
+    proc=0l;
+    execProcess=false;
 }
 
 SshProcess::~SshProcess()
@@ -47,6 +55,25 @@ SshProcess::~SshProcess()
 #ifdef DEBUG
     x2goDebug<<"ssh process destructor";
 #endif
+
+    if (proc)
+    {
+        if (tunnel)
+        {
+            disconnect(proc,SIGNAL(finished(int,QProcess::ExitStatus)),this,
+                       SLOT(slotSshProcFinished(int,QProcess::ExitStatus)));
+            disconnect(proc,SIGNAL(readyReadStandardError()),this,SLOT(slotSshProcStdErr()));
+            disconnect(proc,SIGNAL(readyReadStandardOutput()),this,SLOT(slotSshProcStdOut()));
+        }
+        if (proc->state()==QProcess::Running && execProcess)
+        {
+            if(!proc->waitForFinished(3000))
+            {
+                proc->terminate();
+            }
+        }
+        delete proc;
+    }
     if (serverSocket>0)
     {
 #ifdef Q_OS_WIN
@@ -131,41 +158,153 @@ void SshProcess::startNormal(const QString& cmd)
 {
     QUuid uuid = QUuid::createUuid();
     QString uuidStr = uuid.toString().mid(1, 36).toLower();
+    execProcess=true;
 
-    QString shcmd = "sh -c \"echo X2GODATABEGIN:" + uuidStr + "; "+cmd+"; echo X2GODATAEND:" + uuidStr +"\";";
 //#ifdef DEBUG
 // ONLY UNCOMMENT FOR TESTING, MIGHT REVEAL PASSWORD WHEN command=RDP
 //    x2goDebug<<"executing remote command: "<<shcmd<<endl;
 // #endif
-    masterCon->addChannelConnection(this, uuidStr, shcmd);
-    connect(masterCon,SIGNAL(stdOut(SshProcess*,QByteArray)),this,SLOT(slotStdOut(SshProcess*,QByteArray)));
-    connect(masterCon,SIGNAL(channelClosed(SshProcess*,QString)), this,SLOT(slotChannelClosed(SshProcess*,QString)));
+    if(!masterCon->useKerberos())
+    {
+        QString shcmd = "sh -c \"echo X2GODATABEGIN:" + uuidStr + "; "+cmd+"; echo X2GODATAEND:" + uuidStr +"\";";
+        masterCon->addChannelConnection(this, uuidStr, shcmd);
+        connect(masterCon,SIGNAL(stdOut(SshProcess*,QByteArray)),this,SLOT(slotStdOut(SshProcess*,QByteArray)));
+        connect(masterCon,SIGNAL(channelClosed(SshProcess*,QString)), this,SLOT(slotChannelClosed(SshProcess*,QString)));
+    }
+    else
+    {
+        QString shcmd = "echo X2GODATABEGIN:" + uuidStr + "; "+cmd+"; echo X2GODATAEND:" + uuidStr;
+        proc=new QProcess(this);
+#ifdef Q_OS_WIN
+        QString sshString="plink -batch -P "+
+#else
+        QString sshString=QString::null+"ssh"+ KEEPALIVE_OPTION +"-o GSSApiAuthentication=yes -o PasswordAuthentication=no -p "+
+#endif
+                          QString::number(masterCon->getPort())+" "+
+                          masterCon->getUser()+"@"+ masterCon->getHost() +  " \""+shcmd+"\"";
+#ifdef DEBUG
+        x2goDebug<<"running ssh:" <<sshString<<endl;
+#endif
+        procUuid=uuidStr;
+        proc->start(sshString);
+
+        if (!proc->waitForStarted(5000))
+        {
+            stdErrString=proc->errorString();
+#ifdef DEBUG
+            x2goDebug<<"ssh start failed:" <<stdErrString<<endl;
+#endif
+            slotChannelClosed(this, uuidStr);
+            return;
+        }
+        connect(proc,SIGNAL(finished(int,QProcess::ExitStatus)),this,
+                SLOT(slotSshProcFinished(int,QProcess::ExitStatus)));
+        connect(proc,SIGNAL(readyReadStandardError()),this,SLOT(slotSshProcStdErr()));
+        connect(proc,SIGNAL(readyReadStandardOutput()),this,SLOT(slotSshProcStdOut()));
+    }
+
 }
 
 void SshProcess::start_cp(QString src, QString dst)
 {
-    connect(masterCon, SIGNAL(copyErr(SshProcess*,QString,QString)), this,
-            SLOT(slotCopyErr(SshProcess*,QString,QString)));
-    connect(masterCon, SIGNAL(copyOk(SshProcess*)), this,SLOT(slotCopyOk(SshProcess*)));
     scpSource=src;
-    masterCon->addCopyRequest(this,src,dst);
+    if(!masterCon->useKerberos())
+    {
+        connect(masterCon, SIGNAL(copyErr(SshProcess*,QString,QString)), this,
+                SLOT(slotCopyErr(SshProcess*,QString,QString)));
+        connect(masterCon, SIGNAL(copyOk(SshProcess*)), this,SLOT(slotCopyOk(SshProcess*)));
+        masterCon->addCopyRequest(this,src,dst);
+    }
+    else
+    {
+        proc=new QProcess(this);
+#ifdef Q_OS_WIN
+//pscp don't working with paths like "~user"
+//I hope a home directories of your users are in /home/
+        dst.replace("~"+masterCon->getUser(),"/home/"+masterCon->getUser());
+        dst.replace("~","/home/"+masterCon->getUser());
+
+        QString sshString="pscp -batch -P "+
+#else
+        QString sshString="scp -o GSSApiAuthentication=yes -o PasswordAuthentication=no -P "+
+#endif
+                          QString::number(masterCon->getPort())+" "+src+" "+
+                          masterCon->getUser()+"@"+ masterCon->getHost()+":"+dst;
+#ifdef DEBUG
+        x2goDebug<<"running scp:" <<sshString<<endl;
+#endif
+        proc->start(sshString);
+
+        if (!proc->waitForStarted(5000))
+        {
+            stdErrString=proc->errorString();
+#ifdef DEBUG
+            x2goDebug<<"ssh start failed:" <<stdErrString<<endl;
+#endif
+            slotChannelClosed(this,"");
+            return;
+        }
+        connect(proc,SIGNAL(finished(int,QProcess::ExitStatus)),this,
+                SLOT(slotSshProcFinished(int,QProcess::ExitStatus)));
+        connect(proc,SIGNAL(readyReadStandardError()),this,SLOT(slotSshProcStdErr()));
+        connect(proc,SIGNAL(readyReadStandardOutput()),this,SLOT(slotSshProcStdOut()));
+    }
 }
 
 
 void SshProcess::startTunnel(const QString& forwardHost, uint forwardPort, const QString& localHost,
                              uint localPort, bool reverse)
 {
-    this->forwardHost=forwardHost;
-    this->forwardPort=forwardPort;
-    this->localHost=localHost;
-    this->localPort=localPort;
     tunnel=true;
-    if (!reverse)
-        tunnelLoop();
+    if(!masterCon->useKerberos())
+    {
+        this->forwardHost=forwardHost;
+        this->forwardPort=forwardPort;
+        this->localHost=localHost;
+        this->localPort=localPort;
+        if (!reverse)
+            tunnelLoop();
+        else
+        {
+            connect(masterCon, SIGNAL(reverseListenOk(SshProcess*)), this, SLOT(slotReverseTunnelOk(SshProcess*)));
+            tunnelConnection=masterCon->reverseTunnelConnection(this, forwardPort, localHost, localPort);
+        }
+    }
     else
     {
-        connect(masterCon, SIGNAL(reverseListenOk(SshProcess*)), this, SLOT(slotReverseTunnelOk(SshProcess*)));
-        tunnelConnection=masterCon->reverseTunnelConnection(this, forwardPort, localHost, localPort);
+        proc=new QProcess(this);
+#ifdef Q_OS_WIN
+        QString sshString="plink -batch -P "+
+#else
+	        QString sshString=QString::null+"ssh"+ KEEPALIVE_OPTION +"-o GSSApiAuthentication=yes -o PasswordAuthentication=no -p "+
+#endif
+                          QString::number(masterCon->getPort())+" "+
+                          masterCon->getUser()+"@"+
+                          masterCon->getHost() + " -N ";
+        if (!reverse)
+            sshString+=" -L " + QString::number(localPort)+":"+forwardHost+":"+QString::number(forwardPort);
+        else
+            sshString+=" -R "+ QString::number(forwardPort)+":"+forwardHost+":"+QString::number(localPort);
+
+#ifdef DEBUG
+        x2goDebug<<"running ssh:" <<sshString<<endl;
+#endif
+        proc->start(sshString);
+
+        if (!proc->waitForStarted(5000))
+        {
+            stdErrString=proc->errorString();
+#ifdef DEBUG
+            x2goDebug<<"ssh start failed:" <<stdErrString<<endl;
+#endif
+            slotChannelClosed(this,"");
+            return;
+        }
+        connect(proc,SIGNAL(finished(int,QProcess::ExitStatus)),this,
+                SLOT(slotSshProcFinished(int,QProcess::ExitStatus)));
+        connect(proc,SIGNAL(readyReadStandardError()),this,SLOT(slotSshProcStdErr()));
+        connect(proc,SIGNAL(readyReadStandardOutput()),this,SLOT(slotSshProcStdOut()));
+        emit sshTunnelOk(pid);
     }
 }
 
@@ -228,6 +367,10 @@ void SshProcess::slotChannelClosed(SshProcess* creator, QString uuid)
     if (!normalExited)
     {
         output=abortString;
+        if (output.length()<5)
+        {
+            output=stdErrString;
+        }
     }
     else
     {
@@ -239,7 +382,8 @@ void SshProcess::slotChannelClosed(SshProcess* creator, QString uuid)
             x2goDebug<<"have only stderr, something must be wrong"<<endl;
 #endif
         }
-        else {
+        else
+        {
             QString begin_marker = "X2GODATABEGIN:"+uuid+"\n";
             QString end_marker = "X2GODATAEND:"+uuid+"\n";
             int output_begin=stdOutString.indexOf(begin_marker) + begin_marker.length();
@@ -248,7 +392,28 @@ void SshProcess::slotChannelClosed(SshProcess* creator, QString uuid)
         }
     }
 #ifdef DEBUG
-    x2goDebug<<"ssh finished:"<<normalExited<<" - "<<output<<endl;
+    x2goDebug<<"ssh finished:"<<normalExited<<" - "<<output<<uuid<<endl;
 #endif
     emit sshFinished(normalExited, output, pid);
 }
+
+void SshProcess::slotSshProcFinished(int exitCode, QProcess::ExitStatus exitStatus)
+{
+    normalExited=false;
+    if (exitCode==0 && exitStatus==QProcess::NormalExit)
+        normalExited=true;
+#ifdef DEBUG
+    x2goDebug<<"ssh process exit code :"<<exitStatus;
+#endif
+    slotChannelClosed(this,procUuid);
+}
+
+void SshProcess::slotSshProcStdErr()
+{
+    slotStdErr(this, proc->readAllStandardError());
+}
+
+void SshProcess::slotSshProcStdOut()
+{
+    slotStdOut(this, proc->readAllStandardOutput());
+}
diff --git a/sshprocess.h b/sshprocess.h
index caddb3f..d1e05bf 100644
--- a/sshprocess.h
+++ b/sshprocess.h
@@ -20,14 +20,13 @@
 
 #include <libssh/libssh.h>
 #include <QObject>
-
+#include <QProcess>
 #ifndef Q_OS_WIN
 #include <netinet/in.h>
 #endif
 
 #include "sshmasterconnection.h"
 
-
 class SshProcess : public QObject
 {
     Q_OBJECT
@@ -70,7 +69,10 @@ private:
     QString abortString;
     bool tunnel;
     bool normalExited;
-
+//only to use with krb (until no GSSAPI support in libssh)
+    QProcess* proc;
+    QString procUuid;
+    bool execProcess;
 
 private slots:
     void slotCheckNewConnection();
@@ -81,6 +83,10 @@ private slots:
     void slotReverseTunnelOk(SshProcess* creator);
     void slotCopyOk(SshProcess* creator);
     void slotCopyErr(SshProcess* creator,QString message, QString sshSessionErr);
+    //krb stuff
+    void slotSshProcFinished( int exitCode, QProcess::ExitStatus exitStatus);
+    void slotSshProcStdErr();
+    void slotSshProcStdOut();
 signals:
     void sshFinished ( bool result, QString output, int processId);
     void sshTunnelOk(int processId);


hooks/post-receive
-- 
x2goclient.git (X2Go Client)

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 "x2goclient.git" (X2Go Client).




More information about the x2go-commits mailing list