10#include <ksud_debug.h>
19#include <sys/socket.h>
21#include <sshprocess.h>
35ConnectionHandler::ConnectionHandler(
int fd)
38 , m_hasExitCode(false)
39 , m_needExitCode(false)
44 m_Scheduler = SuProcess::SchedNormal;
47ConnectionHandler::~ConnectionHandler()
64 nbytes = recv(m_Fd, m_Buf.
data() + m_Buf.
size(), BUF_SIZE - 1 - m_Buf.
size(), 0);
72 }
else if (nbytes == 0) {
78 if (m_Buf.
size() == BUF_SIZE - 1) {
79 qCWarning(KSUD_LOG) <<
"line too long";
85 while ((n = m_Buf.
indexOf(
'\n')) != -1) {
88 int nsize = m_Buf.
size() - n;
89 ::memmove(m_Buf.
data(), m_Buf.
data() + n, nsize);
90 ::memset(m_Buf.
data() + nsize,
'x', n);
92 ret = doCommand(newbuf);
93 if (newbuf.isDetached()) {
109 res += s1 +
'*' + s2 +
'*' + s3;
113void ConnectionHandler::sendExitCode()
115 if (!m_needExitCode) {
126void ConnectionHandler::respond(
int ok,
const QByteArray &s)
155int ConnectionHandler::doCommand(
QByteArray buf)
157 if ((uid_t)
peerUid() != getuid()) {
158 qCWarning(KSUD_LOG) <<
"Peer uid not equal to me\n";
159 qCWarning(KSUD_LOG) <<
"Peer: " <<
peerUid() <<
" Me: " << getuid();
175 case Lexer::Tok_pass:
177 if (tok != Lexer::Tok_str) {
183 if (tok != Lexer::Tok_num) {
187 if (l->
lex() !=
'\n') {
193 qCDebug(KSUD_LOG) <<
"Password set!\n";
197 case Lexer::Tok_host:
199 if (tok != Lexer::Tok_str) {
203 if (l->
lex() !=
'\n') {
206 qCDebug(KSUD_LOG) <<
"Host set to " << m_Host;
210 case Lexer::Tok_prio:
212 if (tok != Lexer::Tok_num) {
216 if (l->
lex() !=
'\n') {
219 qCDebug(KSUD_LOG) <<
"priority set to " << m_Priority;
223 case Lexer::Tok_sched:
225 if (tok != Lexer::Tok_num) {
229 if (l->
lex() !=
'\n') {
232 qCDebug(KSUD_LOG) <<
"Scheduler set to " << m_Scheduler;
236 case Lexer::Tok_exec:
241 if (tok != Lexer::Tok_str) {
246 if (tok != Lexer::Tok_str) {
252 if (tok != Lexer::Tok_str) {
257 while (tok !=
'\n') {
258 if (tok != Lexer::Tok_str) {
263 if (strncmp(env_str.
constData(),
"DESKTOP_STARTUP_ID=", strlen(
"DESKTOP_STARTUP_ID=")) != 0) {
264 env_check +=
'*' + env_str;
271 if ((m_Scheduler != SuProcess::SchedNormal) || (m_Priority > 50)) {
276 key = makeKey(2, m_Host, auth_user, command);
278 if (repo->
find(key) == env_check) {
279 key = makeKey(0, m_Host, auth_user, command);
280 pass = repo->
find(key);
288 data.value = env_check;
289 data.timeout = m_Timeout;
290 key = makeKey(2, m_Host, auth_user, command);
291 repo->
add(key, data);
293 data.timeout = m_Timeout;
294 key = makeKey(0, m_Host, auth_user, command);
295 repo->
add(key, data);
300 qCDebug(KSUD_LOG) <<
"Executing command: " << command;
303 qCDebug(KSUD_LOG) <<
"fork(): " << strerror(errno);
306 }
else if (pid > 0) {
313 signal(SIGCHLD, SIG_DFL);
326 ret = proc.exec(pass.
data());
335 qCDebug(KSUD_LOG) <<
"Command completed: " << command;
339 case Lexer::Tok_delCmd:
341 if (tok != Lexer::Tok_str) {
346 if (tok != Lexer::Tok_str) {
350 if (l->
lex() !=
'\n') {
353 key = makeKey(0, m_Host, user, command);
354 if (repo->
remove(key) < 0) {
355 qCDebug(KSUD_LOG) <<
"Unknown command: " << command;
358 qCDebug(KSUD_LOG) <<
"Deleted command: " << command <<
", user = " << user;
363 case Lexer::Tok_delVar:
366 if (tok != Lexer::Tok_str) {
374 key = makeKey(1, name);
375 if (repo->
remove(key) < 0) {
376 qCDebug(KSUD_LOG) <<
"Unknown name: " <<
name;
379 qCDebug(KSUD_LOG) <<
"Deleted name: " <<
name;
385 case Lexer::Tok_delGroup:
387 if (tok != Lexer::Tok_str) {
392 qCDebug(KSUD_LOG) <<
"No keys found under group: " <<
name;
395 qCDebug(KSUD_LOG) <<
"Removed all keys under group: " <<
name;
400 case Lexer::Tok_delSpecialKey:
402 if (tok != Lexer::Tok_str) {
415 if (tok != Lexer::Tok_str) {
420 if (tok != Lexer::Tok_str) {
423 data.value = l->
lval();
425 if (tok != Lexer::Tok_str) {
428 data.group = l->
lval();
430 if (tok != Lexer::Tok_num) {
434 if (l->
lex() !=
'\n') {
437 key = makeKey(1, name);
438 repo->
add(key, data);
439 qCDebug(KSUD_LOG) <<
"Stored key: " << key;
445 if (tok != Lexer::Tok_str) {
449 if (l->
lex() !=
'\n') {
452 key = makeKey(1, name);
453 qCDebug(KSUD_LOG) <<
"Request for key: " << key;
454 value = repo->
find(key);
456 respond(Res_OK, value);
462 case Lexer::Tok_getKeys:
464 if (tok != Lexer::Tok_str) {
468 if (l->
lex() !=
'\n') {
471 qCDebug(KSUD_LOG) <<
"Request for group key: " <<
name;
474 respond(Res_OK, value);
480 case Lexer::Tok_chkGroup:
482 if (tok != Lexer::Tok_str) {
486 if (l->
lex() !=
'\n') {
489 qCDebug(KSUD_LOG) <<
"Checking for group key: " <<
name;
497 case Lexer::Tok_ping:
505 case Lexer::Tok_exit:
510 m_needExitCode =
true;
516 case Lexer::Tok_stop:
521 qCDebug(KSUD_LOG) <<
"Stopping by command";
527 qCWarning(KSUD_LOG) <<
"Unknown command: " << l->
lval();
536 qCWarning(KSUD_LOG) <<
"Parse error";
int handle()
Handle incoming data.
void setEnvironment(const QList< QByteArray > &env)
Set additinal environment variables.
Executes a remote command, using ssh.
void setHost(const QByteArray &host)
Sets the target host.
int exec(const char *password, int check=0)
Executes the command.
void setPriority(int prio)
Set the priority of the process.
void setXOnly(bool xonly)
Set to "X only mode": Sycoca is not built and kdeinit is not launched.
void setScheduler(int sched)
Set the scheduler type.
void setCommand(const QByteArray &command)
Set the command.
void setUser(const QByteArray &user)
Set the target user.
Executes a command under elevated privileges, using su.
This is a lexer for the kdesud protocol.
QByteArray & lval()
Return the token's value.
int lex()
Read next token.
void add(const QByteArray &key, Data_entry &data)
Add a data element.
int remove(const QByteArray &key)
Delete a data element.
QByteArray findKeys(const QByteArray &group, const char *sep="-") const
Returns the key values for the given group.
QByteArray find(const QByteArray &key) const
Return a data value.
int removeGroup(const QByteArray &group)
Delete all data entries having the given group.
int removeSpecialKey(const QByteArray &key)
Delete all data entries based on key.
int hasGroup(const QByteArray &group) const
Checks for the existence of the specified group.
The Socket_security class authenticates the peer for you.
int peerUid() const
Returns the peer's user-id.
QString name(StandardAction id)
QByteArray & append(QByteArrayView data)
const char * constData() const const
bool contains(QByteArrayView bv) const const
QByteArray & fill(char ch, qsizetype size)
qsizetype indexOf(QByteArrayView bv, qsizetype from) const const
bool isEmpty() const const
bool isNull() const const
qsizetype length() const const
QByteArray & prepend(QByteArrayView ba)
void reserve(qsizetype size)
void resize(qsizetype newSize, char c)
QByteArray & setNum(double n, char format, int precision)
qsizetype size() const const
int toInt(bool *ok, int base) const const
void append(QList< T > &&value)