You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
226 lines
4.9 KiB
226 lines
4.9 KiB
/* vi: ts=8 sts=4 sw=4
|
|
*
|
|
* $Id$
|
|
*
|
|
* This file is part of the KDE project, module kdesu.
|
|
* Copyright (C) 1999,2000 Geert Jansen <jansen@kde.org>
|
|
*
|
|
* This is free software; you can use this library under the GNU Library
|
|
* General Public License, version 2. See the file "COPYING.LIB" for the
|
|
* exact licensing terms.
|
|
*
|
|
* kcookie.cpp: KDE authentication cookies.
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
#include <errno.h>
|
|
#include <signal.h>
|
|
|
|
#include <tqstring.h>
|
|
#include <tqstringlist.h>
|
|
#include <tqglobal.h>
|
|
#include <tqfile.h>
|
|
|
|
#include <dcopclient.h>
|
|
|
|
#include <kdebug.h>
|
|
#include <kprocess.h>
|
|
#include "kcookie.h"
|
|
|
|
|
|
KCookie::KCookie()
|
|
{
|
|
#ifdef Q_WS_X11
|
|
getXCookie();
|
|
#endif
|
|
setDcopTransport("local");
|
|
}
|
|
|
|
void KCookie::setDcopTransport(const TQCString &dcopTransport)
|
|
{
|
|
m_dcopTransport = dcopTransport;
|
|
m_bHaveDCOPCookies = false;
|
|
m_bHaveICECookies = false;
|
|
m_DCOPSrv = "";
|
|
m_DCOPAuth = "";
|
|
m_ICEAuth = "";
|
|
}
|
|
|
|
QCStringList KCookie::split(const TQCString &line, char ch)
|
|
{
|
|
QCStringList result;
|
|
|
|
int i=0, pos;
|
|
while ((pos = line.find(ch, i)) != -1)
|
|
{
|
|
result += line.mid(i, pos-i);
|
|
i = pos+1;
|
|
}
|
|
if (i < (int) line.length())
|
|
result += line.mid(i);
|
|
return result;
|
|
}
|
|
|
|
void KCookie::blockSigChild()
|
|
{
|
|
sigset_t sset;
|
|
sigemptyset(&sset);
|
|
sigaddset(&sset, SIGCHLD);
|
|
sigprocmask(SIG_BLOCK, &sset, 0L);
|
|
}
|
|
|
|
void KCookie::unblockSigChild()
|
|
{
|
|
sigset_t sset;
|
|
sigemptyset(&sset);
|
|
sigaddset(&sset, SIGCHLD);
|
|
sigprocmask(SIG_UNBLOCK, &sset, 0L);
|
|
}
|
|
|
|
void KCookie::getXCookie()
|
|
{
|
|
char buf[1024];
|
|
FILE *f;
|
|
|
|
#ifdef Q_WS_X11
|
|
m_Display = getenv("DISPLAY");
|
|
#else
|
|
m_Display = getenv("QWS_DISPLAY");
|
|
#endif
|
|
if (m_Display.isEmpty())
|
|
{
|
|
kdError(900) << k_lineinfo << "$DISPLAY is not set.\n";
|
|
return;
|
|
}
|
|
#ifdef Q_WS_X11 // No need to mess with X Auth stuff
|
|
TQCString disp = m_Display;
|
|
if (!memcmp(disp.data(), "localhost:", 10))
|
|
disp.remove(0, 9);
|
|
|
|
TQString cmd = "xauth list "+KProcess::quote(disp);
|
|
blockSigChild(); // pclose uses waitpid()
|
|
if (!(f = popen(TQFile::encodeName(cmd), "r")))
|
|
{
|
|
kdError(900) << k_lineinfo << "popen(): " << perror << "\n";
|
|
unblockSigChild();
|
|
return;
|
|
}
|
|
TQCString output = fgets(buf, 1024, f);
|
|
if (pclose(f) < 0)
|
|
{
|
|
kdError(900) << k_lineinfo << "Could not run xauth.\n";
|
|
unblockSigChild();
|
|
return;
|
|
}
|
|
unblockSigChild();
|
|
output = output.simplifyWhiteSpace();
|
|
if (output.isEmpty())
|
|
{
|
|
kdWarning(900) << "No X authentication info set for display " <<
|
|
m_Display << endl; return;
|
|
}
|
|
QCStringList lst = split(output, ' ');
|
|
if (lst.count() != 3)
|
|
{
|
|
kdError(900) << k_lineinfo << "parse error.\n";
|
|
return;
|
|
}
|
|
m_DisplayAuth = (lst[1] + ' ' + lst[2]);
|
|
#endif
|
|
}
|
|
|
|
void KCookie::getICECookie()
|
|
{
|
|
FILE *f;
|
|
char buf[1024];
|
|
|
|
TQCString dcopsrv = getenv("DCOPSERVER");
|
|
if (dcopsrv.isEmpty())
|
|
{
|
|
TQCString dcopFile = DCOPClient::dcopServerFile();
|
|
if (!(f = fopen(dcopFile, "r")))
|
|
{
|
|
kdWarning(900) << k_lineinfo << "Cannot open " << dcopFile << ".\n";
|
|
return;
|
|
}
|
|
dcopsrv = fgets(buf, 1024, f);
|
|
dcopsrv = dcopsrv.stripWhiteSpace();
|
|
fclose(f);
|
|
}
|
|
QCStringList dcopServerList = split(dcopsrv, ',');
|
|
if (dcopServerList.isEmpty())
|
|
{
|
|
kdError(900) << k_lineinfo << "No DCOP servers found.\n";
|
|
return;
|
|
}
|
|
|
|
QCStringList::Iterator it;
|
|
for (it=dcopServerList.begin(); it != dcopServerList.end(); ++it)
|
|
{
|
|
if (strncmp((*it).data(), m_dcopTransport.data(), m_dcopTransport.length()) != 0)
|
|
continue;
|
|
m_DCOPSrv = *it;
|
|
TQCString cmd = DCOPClient::iceauthPath()+" list netid="+TQFile::encodeName(KProcess::quote(m_DCOPSrv));
|
|
blockSigChild();
|
|
if (!(f = popen(cmd, "r")))
|
|
{
|
|
kdError(900) << k_lineinfo << "popen(): " << perror << "\n";
|
|
unblockSigChild();
|
|
break;
|
|
}
|
|
QCStringList output;
|
|
while (fgets(buf, 1024, f))
|
|
output += buf;
|
|
if (pclose(f) < 0)
|
|
{
|
|
kdError(900) << k_lineinfo << "Could not run iceauth.\n";
|
|
unblockSigChild();
|
|
break;
|
|
}
|
|
unblockSigChild();
|
|
QCStringList::Iterator it2;
|
|
for (it2=output.begin(); it2!=output.end(); ++it2)
|
|
{
|
|
QCStringList lst = split((*it2).simplifyWhiteSpace(), ' ');
|
|
if (lst.count() != 5)
|
|
{
|
|
kdError(900) << "parse error.\n";
|
|
break;
|
|
}
|
|
if (lst[0] == "DCOP")
|
|
m_DCOPAuth = (lst[3] + ' ' + lst[4]);
|
|
else if (lst[0] == "ICE")
|
|
m_ICEAuth = (lst[3] + ' ' + lst[4]);
|
|
else
|
|
kdError(900) << k_lineinfo << "unknown protocol: " << lst[0] << "\n";
|
|
}
|
|
break;
|
|
}
|
|
m_bHaveDCOPCookies = true;
|
|
m_bHaveICECookies = true;
|
|
}
|
|
|
|
TQCString KCookie::dcopServer()
|
|
{
|
|
if (!m_bHaveDCOPCookies)
|
|
getICECookie();
|
|
return m_DCOPSrv;
|
|
}
|
|
|
|
TQCString KCookie::dcopAuth()
|
|
{
|
|
if (!m_bHaveDCOPCookies)
|
|
getICECookie();
|
|
return m_DCOPAuth;
|
|
}
|
|
|
|
TQCString KCookie::iceAuth()
|
|
{
|
|
if (!m_bHaveICECookies)
|
|
getICECookie();
|
|
return m_ICEAuth;
|
|
}
|