/* * Copyright (c) 2003 Christian Loose * * 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 #include #include #include #include #include // 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"