|
|
|
/*
|
|
|
|
* Copyright (c) 2003 Christian Loose <christian.loose@hamburg.de>
|
|
|
|
*
|
|
|
|
* This program 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 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
|
|
|
|
* Library General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Library General Public License
|
|
|
|
* along with this program; see the file COPYING. If not, write to
|
|
|
|
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
|
|
* Boston, MA 02110-1301, USA.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "sshagent.h"
|
|
|
|
|
|
|
|
#include <tqregexp.h>
|
|
|
|
#include <kapplication.h>
|
|
|
|
#include <kdebug.h>
|
|
|
|
#include <tdeversion.h>
|
|
|
|
#include <kprocess.h>
|
|
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
|
|
|
|
|
|
// initialize static member variables
|
|
|
|
bool SshAgent::m_isRunning = false;
|
|
|
|
bool SshAgent::m_isOurAgent = false;
|
|
|
|
TQString SshAgent::m_authSock = TQString();
|
|
|
|
TQString SshAgent::m_pid = TQString();
|
|
|
|
|
|
|
|
|
|
|
|
SshAgent::SshAgent(TQObject* parent, const char* name)
|
|
|
|
: TQObject(parent, name)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SshAgent::~SshAgent()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool SshAgent::querySshAgent()
|
|
|
|
{
|
|
|
|
kdDebug(8051) << "SshAgent::querySshAgent(): ENTER" << endl;
|
|
|
|
|
|
|
|
if( m_isRunning )
|
|
|
|
return true;
|
|
|
|
|
|
|
|
// Did the user already start a ssh-agent process?
|
|
|
|
char* pid;
|
|
|
|
if( (pid = ::getenv("SSH_AGENT_PID")) != 0 )
|
|
|
|
{
|
|
|
|
kdDebug(8051) << "SshAgent::querySshAgent(): ssh-agent already exists"
|
|
|
|
<< endl;
|
|
|
|
|
|
|
|
m_pid = TQString::fromLocal8Bit(pid);
|
|
|
|
|
|
|
|
char* sock = ::getenv("SSH_AUTH_SOCK");
|
|
|
|
if( sock )
|
|
|
|
m_authSock = TQString::fromLocal8Bit(sock);
|
|
|
|
|
|
|
|
m_isOurAgent = false;
|
|
|
|
m_isRunning = true;
|
|
|
|
}
|
|
|
|
// We have to start a new ssh-agent process
|
|
|
|
else
|
|
|
|
{
|
|
|
|
kdDebug(8051) << "SshAgent::querySshAgent(): start ssh-agent" << endl;
|
|
|
|
|
|
|
|
m_isOurAgent = true;
|
|
|
|
m_isRunning = startSshAgent();
|
|
|
|
}
|
|
|
|
|
|
|
|
return m_isRunning;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool SshAgent::addSshIdentities()
|
|
|
|
{
|
|
|
|
kdDebug(8051) << "SshAgent::addSshIdentities(): ENTER" << endl;
|
|
|
|
|
|
|
|
if( !m_isRunning || !m_isOurAgent )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
// add identities to ssh-agent
|
|
|
|
KProcess proc;
|
|
|
|
|
|
|
|
proc.setEnvironment("SSH_AGENT_PID", m_pid);
|
|
|
|
proc.setEnvironment("SSH_AUTH_SOCK", m_authSock);
|
|
|
|
proc.setEnvironment("SSH_ASKPASS", "cvsaskpass");
|
|
|
|
|
|
|
|
proc << "ssh-add";
|
|
|
|
|
|
|
|
connect(&proc, TQT_SIGNAL(receivedStdout(KProcess*, char*, int)),
|
|
|
|
TQT_SLOT(slotReceivedStdout(KProcess*, char*, int)));
|
|
|
|
connect(&proc, TQT_SIGNAL(receivedStderr(KProcess*, char*, int)),
|
|
|
|
TQT_SLOT(slotReceivedStderr(KProcess*, char*, int)));
|
|
|
|
|
|
|
|
proc.start(KProcess::DontCare, KProcess::AllOutput);
|
|
|
|
|
|
|
|
// wait for process to finish
|
|
|
|
// TODO CL use timeout?
|
|
|
|
proc.wait();
|
|
|
|
|
|
|
|
kdDebug(8051) << "SshAgent::slotProcessExited(): added identities" << endl;
|
|
|
|
|
|
|
|
return (proc.normalExit() && proc.exitStatus() == 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void SshAgent::killSshAgent()
|
|
|
|
{
|
|
|
|
kdDebug(8051) << "SshAgent::killSshAgent(): ENTER" << endl;
|
|
|
|
|
|
|
|
if( !m_isRunning || !m_isOurAgent )
|
|
|
|
return;
|
|
|
|
|
|
|
|
KProcess proc;
|
|
|
|
|
|
|
|
proc << "kill" << m_pid;
|
|
|
|
|
|
|
|
proc.start(KProcess::DontCare, KProcess::NoCommunication);
|
|
|
|
|
|
|
|
kdDebug(8051) << "SshAgent::killSshAgent(): killed pid = " << m_pid << endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void SshAgent::slotProcessExited(KProcess*)
|
|
|
|
{
|
|
|
|
kdDebug(8051) << "SshAgent::slotProcessExited(): ENTER" << endl;
|
|
|
|
|
|
|
|
TQRegExp cshPidRx("setenv SSH_AGENT_PID (\\d*);");
|
|
|
|
TQRegExp cshSockRx("setenv SSH_AUTH_SOCK (.*);");
|
|
|
|
|
|
|
|
TQRegExp bashPidRx("SSH_AGENT_PID=(\\d*).*");
|
|
|
|
TQRegExp bashSockRx("SSH_AUTH_SOCK=(.*\\.\\d*);.*");
|
|
|
|
|
|
|
|
TQStringList::Iterator it = m_outputLines.begin();
|
|
|
|
TQStringList::Iterator end = m_outputLines.end();
|
|
|
|
for( ; it != end; ++it )
|
|
|
|
{
|
|
|
|
if( m_pid.isEmpty() )
|
|
|
|
{
|
|
|
|
int pos = cshPidRx.search(*it);
|
|
|
|
if( pos > -1 )
|
|
|
|
{
|
|
|
|
m_pid = cshPidRx.cap(1);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
pos = bashPidRx.search(*it);
|
|
|
|
if( pos > -1 )
|
|
|
|
{
|
|
|
|
m_pid = bashPidRx.cap(1);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if( m_authSock.isEmpty() )
|
|
|
|
{
|
|
|
|
int pos = cshSockRx.search(*it);
|
|
|
|
if( pos > -1 )
|
|
|
|
{
|
|
|
|
m_authSock = cshSockRx.cap(1);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
pos = bashSockRx.search(*it);
|
|
|
|
if( pos > -1 )
|
|
|
|
{
|
|
|
|
m_authSock = bashSockRx.cap(1);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
kdDebug(8051) << "SshAgent::slotProcessExited(): pid = " << m_pid
|
|
|
|
<< ", socket = " << m_authSock << endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void SshAgent::slotReceivedStdout(KProcess* proc, char* buffer, int buflen)
|
|
|
|
{
|
|
|
|
Q_UNUSED(proc);
|
|
|
|
|
|
|
|
TQString output = TQString::fromLocal8Bit(buffer, buflen);
|
|
|
|
m_outputLines += TQStringList::split("\n", output);
|
|
|
|
|
|
|
|
kdDebug(8051) << "SshAgent::slotReceivedStdout(): output = " << output << endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void SshAgent::slotReceivedStderr(KProcess* proc, char* buffer, int buflen)
|
|
|
|
{
|
|
|
|
Q_UNUSED(proc);
|
|
|
|
|
|
|
|
TQString output = TQString::fromLocal8Bit(buffer, buflen);
|
|
|
|
m_outputLines += TQStringList::split("\n", output);
|
|
|
|
|
|
|
|
kdDebug(8051) << "SshAgent::slotReceivedStderr(): output = " << output << endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool SshAgent::startSshAgent()
|
|
|
|
{
|
|
|
|
kdDebug(8051) << "SshAgent::startSshAgent(): ENTER" << endl;
|
|
|
|
|
|
|
|
KProcess proc;
|
|
|
|
|
|
|
|
proc << "ssh-agent";
|
|
|
|
|
|
|
|
connect(&proc, TQT_SIGNAL(processExited(KProcess*)),
|
|
|
|
TQT_SLOT(slotProcessExited(KProcess*)));
|
|
|
|
connect(&proc, TQT_SIGNAL(receivedStdout(KProcess*, char*, int)),
|
|
|
|
TQT_SLOT(slotReceivedStdout(KProcess*, char*, int)));
|
|
|
|
connect(&proc, TQT_SIGNAL(receivedStderr(KProcess*, char*, int)),
|
|
|
|
TQT_SLOT(slotReceivedStderr(KProcess*, char*, int)) );
|
|
|
|
|
|
|
|
proc.start(KProcess::NotifyOnExit, KProcess::All);
|
|
|
|
|
|
|
|
// wait for process to finish
|
|
|
|
// TODO CL use timeout?
|
|
|
|
proc.wait();
|
|
|
|
|
|
|
|
return (proc.normalExit() && proc.exitStatus() == 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#include "sshagent.moc"
|