kcookie.cpp
00001 /* vi: ts=8 sts=4 sw=4 00002 * 00003 * $Id$ 00004 * 00005 * This file is part of the KDE project, module kdesu. 00006 * Copyright (C) 1999,2000 Geert Jansen <jansen@kde.org> 00007 * 00008 * This is free software; you can use this library under the GNU Library 00009 * General Public License, version 2. See the file "COPYING.LIB" for the 00010 * exact licensing terms. 00011 * 00012 * kcookie.cpp: KDE authentication cookies. 00013 */ 00014 00015 #include <stdio.h> 00016 #include <stdlib.h> 00017 #include <string.h> 00018 #include <unistd.h> 00019 #include <errno.h> 00020 #include <signal.h> 00021 00022 #include <tqstring.h> 00023 #include <tqstringlist.h> 00024 #include <tqglobal.h> 00025 #include <tqfile.h> 00026 00027 #include <dcopclient.h> 00028 00029 #include <kdebug.h> 00030 #include <kprocess.h> 00031 #include "kcookie.h" 00032 00033 00034 KCookie::KCookie() 00035 { 00036 #ifdef Q_WS_X11 00037 getXCookie(); 00038 #endif 00039 setDcopTransport("local"); 00040 } 00041 00042 void KCookie::setDcopTransport(const TQCString &dcopTransport) 00043 { 00044 m_dcopTransport = dcopTransport; 00045 m_bHaveDCOPCookies = false; 00046 m_bHaveICECookies = false; 00047 m_DCOPSrv = ""; 00048 m_DCOPAuth = ""; 00049 m_ICEAuth = ""; 00050 } 00051 00052 QCStringList KCookie::split(const TQCString &line, char ch) 00053 { 00054 QCStringList result; 00055 00056 int i=0, pos; 00057 while ((pos = line.find(ch, i)) != -1) 00058 { 00059 result += line.mid(i, pos-i); 00060 i = pos+1; 00061 } 00062 if (i < (int) line.length()) 00063 result += line.mid(i); 00064 return result; 00065 } 00066 00067 void KCookie::blockSigChild() 00068 { 00069 sigset_t sset; 00070 sigemptyset(&sset); 00071 sigaddset(&sset, SIGCHLD); 00072 sigprocmask(SIG_BLOCK, &sset, 0L); 00073 } 00074 00075 void KCookie::unblockSigChild() 00076 { 00077 sigset_t sset; 00078 sigemptyset(&sset); 00079 sigaddset(&sset, SIGCHLD); 00080 sigprocmask(SIG_UNBLOCK, &sset, 0L); 00081 } 00082 00083 void KCookie::getXCookie() 00084 { 00085 char buf[1024]; 00086 FILE *f; 00087 00088 #ifdef Q_WS_X11 00089 m_Display = getenv("DISPLAY"); 00090 #else 00091 m_Display = getenv("QWS_DISPLAY"); 00092 #endif 00093 if (m_Display.isEmpty()) 00094 { 00095 kdError(900) << k_lineinfo << "$DISPLAY is not set.\n"; 00096 return; 00097 } 00098 #ifdef Q_WS_X11 // No need to mess with X Auth stuff 00099 TQCString disp = m_Display; 00100 if (!memcmp(disp.data(), "localhost:", 10)) 00101 disp.remove(0, 9); 00102 00103 TQString cmd = "xauth list "+KProcess::quote(disp); 00104 blockSigChild(); // pclose uses waitpid() 00105 if (!(f = popen(TQFile::encodeName(cmd), "r"))) 00106 { 00107 kdError(900) << k_lineinfo << "popen(): " << perror << "\n"; 00108 unblockSigChild(); 00109 return; 00110 } 00111 TQCString output = fgets(buf, 1024, f); 00112 if (pclose(f) < 0) 00113 { 00114 kdError(900) << k_lineinfo << "Could not run xauth.\n"; 00115 unblockSigChild(); 00116 return; 00117 } 00118 unblockSigChild(); 00119 output = output.simplifyWhiteSpace(); 00120 if (output.isEmpty()) 00121 { 00122 kdWarning(900) << "No X authentication info set for display " << 00123 m_Display << endl; return; 00124 } 00125 QCStringList lst = split(output, ' '); 00126 if (lst.count() != 3) 00127 { 00128 kdError(900) << k_lineinfo << "parse error.\n"; 00129 return; 00130 } 00131 m_DisplayAuth = (lst[1] + ' ' + lst[2]); 00132 #endif 00133 } 00134 00135 void KCookie::getICECookie() 00136 { 00137 FILE *f; 00138 char buf[1024]; 00139 00140 TQCString dcopsrv = getenv("DCOPSERVER"); 00141 if (dcopsrv.isEmpty()) 00142 { 00143 TQCString dcopFile = DCOPClient::dcopServerFile(); 00144 if (!(f = fopen(dcopFile, "r"))) 00145 { 00146 kdWarning(900) << k_lineinfo << "Cannot open " << dcopFile << ".\n"; 00147 return; 00148 } 00149 dcopsrv = fgets(buf, 1024, f); 00150 dcopsrv = dcopsrv.stripWhiteSpace(); 00151 fclose(f); 00152 } 00153 QCStringList dcopServerList = split(dcopsrv, ','); 00154 if (dcopServerList.isEmpty()) 00155 { 00156 kdError(900) << k_lineinfo << "No DCOP servers found.\n"; 00157 return; 00158 } 00159 00160 QCStringList::Iterator it; 00161 for (it=dcopServerList.begin(); it != dcopServerList.end(); ++it) 00162 { 00163 if (strncmp((*it).data(), m_dcopTransport.data(), m_dcopTransport.length()) != 0) 00164 continue; 00165 m_DCOPSrv = *it; 00166 TQCString cmd = DCOPClient::iceauthPath()+" list netid="+TQFile::encodeName(KProcess::quote(m_DCOPSrv)); 00167 blockSigChild(); 00168 if (!(f = popen(cmd, "r"))) 00169 { 00170 kdError(900) << k_lineinfo << "popen(): " << perror << "\n"; 00171 unblockSigChild(); 00172 break; 00173 } 00174 QCStringList output; 00175 while (fgets(buf, 1024, f)) 00176 output += buf; 00177 if (pclose(f) < 0) 00178 { 00179 kdError(900) << k_lineinfo << "Could not run iceauth.\n"; 00180 unblockSigChild(); 00181 break; 00182 } 00183 unblockSigChild(); 00184 QCStringList::Iterator it2; 00185 for (it2=output.begin(); it2!=output.end(); ++it2) 00186 { 00187 QCStringList lst = split((*it2).simplifyWhiteSpace(), ' '); 00188 if (lst.count() != 5) 00189 { 00190 kdError(900) << "parse error.\n"; 00191 break; 00192 } 00193 if (lst[0] == "DCOP") 00194 m_DCOPAuth = (lst[3] + ' ' + lst[4]); 00195 else if (lst[0] == "ICE") 00196 m_ICEAuth = (lst[3] + ' ' + lst[4]); 00197 else 00198 kdError(900) << k_lineinfo << "unknown protocol: " << lst[0] << "\n"; 00199 } 00200 break; 00201 } 00202 m_bHaveDCOPCookies = true; 00203 m_bHaveICECookies = true; 00204 } 00205 00206 TQCString KCookie::dcopServer() 00207 { 00208 if (!m_bHaveDCOPCookies) 00209 getICECookie(); 00210 return m_DCOPSrv; 00211 } 00212 00213 TQCString KCookie::dcopAuth() 00214 { 00215 if (!m_bHaveDCOPCookies) 00216 getICECookie(); 00217 return m_DCOPAuth; 00218 } 00219 00220 TQCString KCookie::iceAuth() 00221 { 00222 if (!m_bHaveICECookies) 00223 getICECookie(); 00224 return m_ICEAuth; 00225 }