3 * This file is part of the KDE project, module kdesu.
4 * Copyright (C) 2000 Geert Jansen <jansen@kde.org>
6 * This is free software; you can use this library under the GNU Library
7 * General Public License, version 2. See the file "COPYING.LIB" for the
8 * exact licensing terms.
10 * ssh.cpp: Execute a program on a remote machine using ssh.
28 #include <sys/types.h>
31 #include <QtCore/QBool>
35 #include <kstandarddirs.h>
39 using namespace KDESuPrivate
;
41 class SshProcess::SshProcessPrivate
44 SshProcessPrivate(const QByteArray
&host
)
46 , m_Stub( "kdesu_stub" )
55 SshProcess::SshProcess(const QByteArray
&host
, const QByteArray
&user
, const QByteArray
&command
)
56 : d( new SshProcessPrivate(host
) )
64 SshProcess::~SshProcess()
69 void SshProcess::setHost(const QByteArray
&host
)
75 void SshProcess::setStub(const QByteArray
&stub
)
81 int SshProcess::checkInstall(const char *password
)
83 return exec(password
, 1);
87 int SshProcess::checkNeedPassword()
93 int SshProcess::exec(const char *password
, int check
)
98 QList
<QByteArray
> args
;
99 args
+= "-l"; args
+= m_User
;
100 args
+= "-o"; args
+= "StrictHostKeyChecking=no";
101 args
+= d
->m_Host
; args
+= d
->m_Stub
;
103 if (StubProcess::exec("ssh", args
) < 0)
105 return check
? SshNotFound
: -1;
108 int ret
= ConverseSsh(password
, check
);
112 kError(900) << k_lineinfo
<< "Conversation with ssh failed\n";
119 kill(m_Pid
, SIGTERM
);
125 if (m_bErase
&& password
)
126 memset(const_cast<char *>(password
), 0, qstrlen(password
));
128 ret
= ConverseStub(check
);
132 kError(900) << k_lineinfo
<< "Conversation with kdesu_stub failed\n";
137 kill(m_Pid
, SIGTERM
);
139 ret
= SshIncorrectPassword
;
148 setExitString("Waiting for forwarded connections to terminate");
149 ret
= waitForChild();
153 QByteArray
SshProcess::prompt() const
158 QByteArray
SshProcess::error() const
165 * Conversation with ssh.
166 * If check is 0, this waits for either a "Password: " prompt,
167 * or the header of the stub. If a prompt is received, the password is
168 * written back. Used for running a command.
169 * If check is 1, operation is the same as 0 except that if a stub header is
170 * received, the stub is stopped with the "stop" command. This is used for
171 * checking a password.
172 * If check is 2, operation is the same as 1, except that no password is
173 * written. The prompt is saved to m_Prompt. Used for checking the need for
177 int SshProcess::ConverseSsh(const char *password
, int check
)
179 unsigned i
, j
, colon
;
187 const uint len
= line
.length();
193 // Check for "kdesu_stub" header.
194 if (line
== "kdesu_stub")
200 // Match "Password: " with the regex ^[^:]+:[\w]*$.
201 for (i
=0,j
=0,colon
=0; i
<len
; i
++)
208 if (!isspace(line
[i
]))
211 if ((colon
== 1) && (line
[j
] == ':'))
216 return SshNeedsPassword
;
219 write(fd(), password
, strlen(password
));
220 write(fd(), "\n", 1);
225 // Warning/error message.
226 d
->m_Error
+= line
; d
->m_Error
+= '\n';
228 fprintf(stderr
, "ssh: %s\n", line
.constData());
244 // Display redirection is handled by ssh natively.
245 QByteArray
SshProcess::display()
251 QByteArray
SshProcess::displayAuth()
256 void SshProcess::virtual_hook( int id
, void* data
)
257 { StubProcess::virtual_hook( id
, data
); }