diff options
author | Timothy Pearson <kb9vqf@pearsoncomputing.net> | 2011-11-06 15:56:40 -0600 |
---|---|---|
committer | Timothy Pearson <kb9vqf@pearsoncomputing.net> | 2011-11-06 15:56:40 -0600 |
commit | e16866e072f94410321d70daedbcb855ea878cac (patch) | |
tree | ee3f52eabde7da1a0e6ca845fb9c2813cf1558cf /kdesu | |
parent | a58c20c1a7593631a1b50213c805507ebc16adaf (diff) | |
download | tdelibs-e16866e072f94410321d70daedbcb855ea878cac.tar.gz tdelibs-e16866e072f94410321d70daedbcb855ea878cac.zip |
Actually move the kde files that were renamed in the last commit
Diffstat (limited to 'kdesu')
-rw-r--r-- | kdesu/CMakeLists.txt | 57 | ||||
-rw-r--r-- | kdesu/Mainpage.dox | 21 | ||||
-rw-r--r-- | kdesu/Makefile.am | 30 | ||||
-rw-r--r-- | kdesu/README | 13 | ||||
-rw-r--r-- | kdesu/client.cpp | 435 | ||||
-rw-r--r-- | kdesu/client.h | 207 | ||||
-rw-r--r-- | kdesu/configure.in.in | 93 | ||||
-rw-r--r-- | kdesu/defaults.h | 21 | ||||
-rw-r--r-- | kdesu/kcookie.cpp | 225 | ||||
-rw-r--r-- | kdesu/kcookie.h | 90 | ||||
-rw-r--r-- | kdesu/kdesu_pty.cpp | 302 | ||||
-rw-r--r-- | kdesu/kdesu_pty.h | 71 | ||||
-rw-r--r-- | kdesu/kdesu_stub.c | 432 | ||||
-rw-r--r-- | kdesu/libkdesu.nmcheck | 10 | ||||
-rw-r--r-- | kdesu/libkdesu_weak.nmcheck | 2 | ||||
-rw-r--r-- | kdesu/process.cpp | 626 | ||||
-rw-r--r-- | kdesu/process.h | 188 | ||||
-rw-r--r-- | kdesu/ssh.cpp | 279 | ||||
-rw-r--r-- | kdesu/ssh.h | 90 | ||||
-rw-r--r-- | kdesu/stub.cpp | 184 | ||||
-rw-r--r-- | kdesu/stub.h | 139 | ||||
-rw-r--r-- | kdesu/su.cpp | 342 | ||||
-rw-r--r-- | kdesu/su.h | 63 |
23 files changed, 0 insertions, 3920 deletions
diff --git a/kdesu/CMakeLists.txt b/kdesu/CMakeLists.txt deleted file mode 100644 index 97ede6b97..000000000 --- a/kdesu/CMakeLists.txt +++ /dev/null @@ -1,57 +0,0 @@ -################################################# -# -# (C) 2010 Serghei Amelian -# serghei (DOT) amelian (AT) gmail.com -# -# Improvements and feedback are welcome -# -# This file is released under GPL >= 2 -# -################################################# - -include_directories( - ${TQT_INCLUDE_DIRS} - ${CMAKE_BINARY_DIR} - ${CMAKE_BINARY_DIR}/tdecore - ${CMAKE_SOURCE_DIR}/dcop - ${CMAKE_SOURCE_DIR}/tdecore -) - -link_directories( - ${TQT_LIBRARY_DIRS} -) - - -##### headers ################################### - -install( FILES - defaults.h client.h process.h tdesu_pty.h - kcookie.h su.h ssh.h stub.h - DESTINATION ${INCLUDE_INSTALL_DIR}/tdesu ) - - -##### libtdesu ################################## - -set( target tdesu ) - -set( ${target}_SRCS - client.cpp process.cpp kcookie.cpp - su.cpp ssh.cpp stub.cpp tdesu_pty.cpp -) - -tde_add_library( ${target} SHARED - SOURCES ${${target}_SRCS} - VERSION 4.2.0 - LINK tdecore-shared ${LIB_UTIL} - DESTINATION ${LIB_INSTALL_DIR} -) - -tde_install_symlink( tdesu_pty.h ${INCLUDE_INSTALL_DIR}/tdesu/pty.h ) - - -##### tdesu_stub ################################ - -tde_add_executable( tdesu_stub - SOURCES tdesu_stub.c - DESTINATION ${BIN_INSTALL_DIR} -) diff --git a/kdesu/Mainpage.dox b/kdesu/Mainpage.dox deleted file mode 100644 index c39881397..000000000 --- a/kdesu/Mainpage.dox +++ /dev/null @@ -1,21 +0,0 @@ -/** @mainpage Console-mode authentication - -libtdesu provides functionality for building GUI front ends for -(password asking) console mode programs. For example, tdesu and -kdessh use it to interface with su and ssh respectively. - -@authors -Geert Jansen \<jansen@kde.org\> - -@maintainers -Adriaan de Groot \<groot@kde.org\> - -@licenses -@lgpl - - -*/ - -// DOXYGEN_REFERENCES = tdecore -// DOXYGEN_SET_PROJECT_NAME = Trinitysu -// vim:ts=4:sw=4:expandtab:filetype=doxygen diff --git a/kdesu/Makefile.am b/kdesu/Makefile.am deleted file mode 100644 index 847a21ee1..000000000 --- a/kdesu/Makefile.am +++ /dev/null @@ -1,30 +0,0 @@ -## Makefile.am for libtdesu - -INCLUDES = -I$(top_srcdir)/kio/ $(all_includes) - -lib_LTLIBRARIES = libtdesu.la -libtdesu_la_SOURCES = client.cpp process.cpp kcookie.cpp su.cpp ssh.cpp stub.cpp tdesu_pty.cpp -libtdesu_la_LDFLAGS = -version-info 6:0:2 -no-undefined $(all_libraries) -libtdesu_la_LIBADD = $(LIB_KDECORE) $(LIB_QT) $(top_builddir)/dcop/libDCOP.la -libtdesu_la_NMCHECK = $(srcdir)/libtdesu.nmcheck -libtdesu_la_NMCHECKWEAK = $(srcdir)/libtdesu_weak.nmcheck $(top_srcdir)/tdecore/libtdecore_weak.nmcheck \ - $(top_srcdir)/dcop/libDCOP_weak.nmcheck $(top_srcdir)/tdecore/libqt-mt_weak.nmcheck - -tdesudir = $(includedir)/tdesu -tdesu_HEADERS = defaults.h client.h process.h tdesu_pty.h kcookie.h su.h ssh.h stub.h - -install-data-hook: - $(mkinstalldirs) $(DESTDIR)$(tdesudir) - -rm -f $(DESTDIR)$(tdesudir)/pty.h - ln -s tdesu_pty.h $(DESTDIR)$(tdesudir)/pty.h - -uninstall-local: - -rm -f $(DESTDIR)$(tdesudir)/pty.h - -bin_PROGRAMS = tdesu_stub -tdesu_stub_SOURCES = tdesu_stub.c -tdesu_stub_LDFLAGS = $(all_libraries) -tdesu_stub_LDADD = - -include $(top_srcdir)/admin/Doxyfile.am - diff --git a/kdesu/README b/kdesu/README deleted file mode 100644 index c81f5c23b..000000000 --- a/kdesu/README +++ /dev/null @@ -1,13 +0,0 @@ -Maintainer: Adriaan de Groot <groot@kde.org> -Maintainer: tdesu was maintained by Alan Eldridge until his - death in 2003. - -README for libtdesu. - -Libtdesu provides functionality for building GUI front ends for -(password asking) console mode programs. For example, tdesu and -kdessh use it to interface with su and ssh respectively. - -libtdesu is Copyright (c) 1999,2000 Geert Jansen <jansen@kde.org> - -Distributed under the GNU Library General Public License, version 2. diff --git a/kdesu/client.cpp b/kdesu/client.cpp deleted file mode 100644 index 18accc313..000000000 --- a/kdesu/client.cpp +++ /dev/null @@ -1,435 +0,0 @@ -/* vi: ts=8 sts=4 sw=4 - * - * $Id$ - * - * This file is part of the KDE project, module tdesu. - * 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. - * - * client.cpp: A client for tdesud. - */ - -#include <config.h> -#include <stdio.h> -#include <unistd.h> -#include <stdlib.h> -#include <pwd.h> -#include <errno.h> -#include <string.h> - -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/un.h> -#include <sys/stat.h> - -#include <tqglobal.h> -#include <tqcstring.h> -#include <tqfile.h> -#include <tqregexp.h> - -#include <kdebug.h> -#include <kstandarddirs.h> -#include <kapplication.h> -#include <kde_file.h> - -#include "client.h" - -class KDEsuClient::KDEsuClientPrivate { -public: - TQString daemon; -}; - -#ifndef SUN_LEN -#define SUN_LEN(ptr) ((socklen_t) (((struct sockaddr_un *) 0)->sun_path) \ - + strlen ((ptr)->sun_path)) -#endif - -KDEsuClient::KDEsuClient() -{ - sockfd = -1; -#ifdef Q_WS_X11 - TQCString display(getenv("DISPLAY")); - if (display.isEmpty()) - { - kdWarning(900) << k_lineinfo << "$DISPLAY is not set\n"; - return; - } - - // strip the screen number from the display - display.replace(TQRegExp("\\.[0-9]+$"), ""); -#else - TQCString display("QWS"); -#endif - - sock = TQFile::encodeName(locateLocal("socket", TQString("tdesud_%1").arg(display.data()))); - d = new KDEsuClientPrivate; - connect(); -} - - -KDEsuClient::~KDEsuClient() -{ - delete d; - if (sockfd >= 0) - close(sockfd); -} - -int KDEsuClient::connect() -{ - if (sockfd >= 0) - close(sockfd); - if (access(sock, R_OK|W_OK)) - { - sockfd = -1; - return -1; - } - - sockfd = socket(PF_UNIX, SOCK_STREAM, 0); - if (sockfd < 0) - { - kdWarning(900) << k_lineinfo << "socket(): " << perror << "\n"; - return -1; - } - struct sockaddr_un addr; - addr.sun_family = AF_UNIX; - strcpy(addr.sun_path, sock); - - if (::connect(sockfd, (struct sockaddr *) &addr, SUN_LEN(&addr)) < 0) - { - kdWarning(900) << k_lineinfo << "connect():" << perror << endl; - close(sockfd); sockfd = -1; - return -1; - } - -#if !defined(SO_PEERCRED) || !defined(HAVE_STRUCT_UCRED) -# if defined(HAVE_GETPEEREID) - uid_t euid; - gid_t egid; - // Security: if socket exists, we must own it - if (getpeereid(sockfd, &euid, &egid) == 0) - { - if (euid != getuid()) - { - kdWarning(900) << "socket not owned by me! socket uid = " << euid << endl; - close(sockfd); sockfd = -1; - return -1; - } - } -# else -# ifdef __GNUC__ -# warning "Using sloppy security checks" -# endif - // We check the owner of the socket after we have connected. - // If the socket was somehow not ours an attacker will be able - // to delete it after we connect but shouldn't be able to - // create a socket that is owned by us. - KDE_struct_stat s; - if (KDE_lstat(sock, &s)!=0) - { - kdWarning(900) << "stat failed (" << sock << ")" << endl; - close(sockfd); sockfd = -1; - return -1; - } - if (s.st_uid != getuid()) - { - kdWarning(900) << "socket not owned by me! socket uid = " << s.st_uid << endl; - close(sockfd); sockfd = -1; - return -1; - } - if (!S_ISSOCK(s.st_mode)) - { - kdWarning(900) << "socket is not a socket (" << sock << ")" << endl; - close(sockfd); sockfd = -1; - return -1; - } -# endif -#else - struct ucred cred; - socklen_t siz = sizeof(cred); - - // Security: if socket exists, we must own it - if (getsockopt(sockfd, SOL_SOCKET, SO_PEERCRED, &cred, &siz) == 0) - { - if (cred.uid != getuid()) - { - kdWarning(900) << "socket not owned by me! socket uid = " << cred.uid << endl; - close(sockfd); sockfd = -1; - return -1; - } - } -#endif - - return 0; -} - -TQCString KDEsuClient::escape(const TQCString &str) -{ - TQCString copy = str; - int n = 0; - while ((n = copy.find("\\", n)) != -1) - { - copy.insert(n, '\\'); - n += 2; - } - n = 0; - while ((n = copy.find("\"", n)) != -1) - { - copy.insert(n, '\\'); - n += 2; - } - copy.prepend("\""); - copy.append("\""); - return copy; -} - -int KDEsuClient::command(const TQCString &cmd, TQCString *result) -{ - if (sockfd < 0) - return -1; - - if (send(sockfd, cmd, cmd.length(), 0) != (int) cmd.length()) - return -1; - - char buf[1024]; - int nbytes = recv(sockfd, buf, 1023, 0); - if (nbytes <= 0) - { - kdWarning(900) << k_lineinfo << "no reply from daemon\n"; - return -1; - } - buf[nbytes] = '\000'; - - TQCString reply = buf; - if (reply.left(2) != "OK") - return -1; - - if (result) - *result = reply.mid(3, reply.length()-4); - return 0; -} - -int KDEsuClient::setPass(const char *pass, int timeout) -{ - TQCString cmd = "PASS "; - cmd += escape(pass); - cmd += " "; - cmd += TQCString().setNum(timeout); - cmd += "\n"; - return command(cmd); -} - -int KDEsuClient::exec(const TQCString &prog, const TQCString &user, const TQCString &options, const QCStringList &env) -{ - TQCString cmd; - cmd = "EXEC "; - cmd += escape(prog); - cmd += " "; - cmd += escape(user); - if (!options.isEmpty() || !env.isEmpty()) - { - cmd += " "; - cmd += escape(options); - for(QCStringList::ConstIterator it = env.begin(); - it != env.end(); ++it) - { - cmd += " "; - cmd += escape(*it); - } - } - cmd += "\n"; - return command(cmd); -} - -int KDEsuClient::setHost(const TQCString &host) -{ - TQCString cmd = "HOST "; - cmd += escape(host); - cmd += "\n"; - return command(cmd); -} - -int KDEsuClient::setPriority(int prio) -{ - TQCString cmd; - cmd.sprintf("PRIO %d\n", prio); - return command(cmd); -} - -int KDEsuClient::setScheduler(int sched) -{ - TQCString cmd; - cmd.sprintf("SCHD %d\n", sched); - return command(cmd); -} - -int KDEsuClient::delCommand(const TQCString &key, const TQCString &user) -{ - TQCString cmd = "DEL "; - cmd += escape(key); - cmd += " "; - cmd += escape(user); - cmd += "\n"; - return command(cmd); -} -int KDEsuClient::setVar(const TQCString &key, const TQCString &value, int timeout, - const TQCString &group) -{ - TQCString cmd = "SET "; - cmd += escape(key); - cmd += " "; - cmd += escape(value); - cmd += " "; - cmd += escape(group); - cmd += " "; - cmd += TQCString().setNum(timeout); - cmd += "\n"; - return command(cmd); -} - -TQCString KDEsuClient::getVar(const TQCString &key) -{ - TQCString cmd = "GET "; - cmd += escape(key); - cmd += "\n"; - TQCString reply; - command(cmd, &reply); - return reply; -} - -TQValueList<TQCString> KDEsuClient::getKeys(const TQCString &group) -{ - TQCString cmd = "GETK "; - cmd += escape(group); - cmd += "\n"; - TQCString reply; - command(cmd, &reply); - int index=0, pos; - TQValueList<TQCString> list; - if( !reply.isEmpty() ) - { - // kdDebug(900) << "Found a matching entry: " << reply << endl; - while (1) - { - pos = reply.find( '\007', index ); - if( pos == -1 ) - { - if( index == 0 ) - list.append( reply ); - else - list.append( reply.mid(index) ); - break; - } - else - { - list.append( reply.mid(index, pos-index) ); - } - index = pos+1; - } - } - return list; -} - -bool KDEsuClient::findGroup(const TQCString &group) -{ - TQCString cmd = "CHKG "; - cmd += escape(group); - cmd += "\n"; - if( command(cmd) == -1 ) - return false; - return true; -} - -int KDEsuClient::delVar(const TQCString &key) -{ - TQCString cmd = "DELV "; - cmd += escape(key); - cmd += "\n"; - return command(cmd); -} - -int KDEsuClient::delGroup(const TQCString &group) -{ - TQCString cmd = "DELG "; - cmd += escape(group); - cmd += "\n"; - return command(cmd); -} - -int KDEsuClient::delVars(const TQCString &special_key) -{ - TQCString cmd = "DELS "; - cmd += escape(special_key); - cmd += "\n"; - return command(cmd); -} - -int KDEsuClient::ping() -{ - return command("PING\n"); -} - -int KDEsuClient::exitCode() -{ - TQCString result; - if (command("EXIT\n", &result) != 0) - return -1; - - return result.toLong(); -} - -int KDEsuClient::stopServer() -{ - return command("STOP\n"); -} - -static TQString findDaemon() -{ - TQString daemon = locate("bin", "tdesud"); - if (daemon.isEmpty()) // if not in KDEDIRS, rely on PATH - daemon = KStandardDirs::findExe("tdesud"); - - if (daemon.isEmpty()) - { - kdWarning(900) << k_lineinfo << "daemon not found\n"; - } - return daemon; -} - -bool KDEsuClient::isServerSGID() -{ - if (d->daemon.isEmpty()) - d->daemon = findDaemon(); - if (d->daemon.isEmpty()) - return false; - - KDE_struct_stat sbuf; - if (KDE_stat(TQFile::encodeName(d->daemon), &sbuf) < 0) - { - kdWarning(900) << k_lineinfo << "stat(): " << perror << "\n"; - return false; - } - return (sbuf.st_mode & S_ISGID); -} - -int KDEsuClient::startServer() -{ - if (d->daemon.isEmpty()) - d->daemon = findDaemon(); - if (d->daemon.isEmpty()) - return -1; - - if (!isServerSGID()) { - kdWarning(900) << k_lineinfo << "tdesud not setgid!\n"; - } - - // tdesud only forks to the background after it is accepting - // connections. - // We start it via tdeinit to make sure that it doesn't inherit - // any fd's from the parent process. - int ret = kapp->tdeinitExecWait(d->daemon); - connect(); - return ret; -} diff --git a/kdesu/client.h b/kdesu/client.h deleted file mode 100644 index 420d5dadd..000000000 --- a/kdesu/client.h +++ /dev/null @@ -1,207 +0,0 @@ -/* vi: ts=8 sts=4 sw=4 - * - * $Id$ - * - * This file is part of the KDE project, module tdesu. - * 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. - * - * client.h: client to access tdesud. - */ - -#ifndef __KDE_su_Client_h_Included__ -#define __KDE_su_Client_h_Included__ - -#include <tqglobal.h> -#include <kdelibs_export.h> - -#ifdef Q_OS_UNIX - -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/un.h> - -#include <tqcstring.h> -#include <tqvaluelist.h> - -typedef TQValueList<TQCString> QCStringList; - -/** - * A client class to access tdesud, the KDE su daemon. Kdesud can assist in - * password caching in two ways: - * - * @li For high security passwords, like for su and ssh, it executes the - * password requesting command for you. It feeds the password to the - * command, without ever returning it to you, the user. The daemon should - * be installed setgid nogroup, in order to be able to act as an inaccessible, - * trusted 3rd party. - * See exec, setPass, delCommand. - * - * @li For lower security passwords, like web and ftp passwords, it can act - * as a persistent storage for string variables. These variables are - * returned to the user, and the daemon doesn't need to be setgid nogroup - * for this. - * See setVar, delVar, delGroup. - */ - -class KDESU_EXPORT KDEsuClient { -public: - KDEsuClient(); - ~KDEsuClient(); - - /** - * Lets tdesud execute a command. If the daemon does not have a password - * for this command, this will fail and you need to call setPass(). - * - * @param command The command to execute. - * @param user The user to run the command as. - * @param options Extra options. - * @param env Extra environment variables. - * @return Zero on success, -1 on failure. - */ - int exec(const TQCString &command, const TQCString &user, const TQCString &options=0, const QCStringList &env=QCStringList()); - - /** - * Wait for the last command to exit and return the exit code. - * @return Exit code of last command, -1 on failure. - */ - int exitCode(); - - /** - * Set root's password, lasts one session. - * - * @param pass Root's password. - * @param timeout The time that a password will live. - * @return Zero on success, -1 on failure. - */ - int setPass(const char *pass, int timeout); - - /** - * Set the target host (optional). - */ - int setHost(const TQCString &host); - - /** - * Set the desired priority (optional), see StubProcess. - */ - int setPriority(int priority); - - /** - * Set the desired scheduler (optional), see StubProcess. - */ - int setScheduler(int scheduler); - - /** - * Remove a password for a user/command. - * @param command The command. - * @param user The user. - * @return zero on success, -1 on an error - */ - int delCommand(const TQCString &command, const TQCString &user); - - /** - * Set a persistent variable. - * @param key The name of the variable. - * @param value Its value. - * @param timeout The timeout in seconds for this key. Zero means - * no timeout. - * @param group Make the key part of a group. See delGroup. - * @return zero on success, -1 on failure. - */ - int setVar(const TQCString &key, const TQCString &value, int timeout=0, const TQCString &group=0); - - /** - * Get a persistent variable. - * @param key The name of the variable. - * @return Its value. - */ - TQCString getVar(const TQCString &key); - - /** - * Gets all the keys that are membes of the given group. - * @param group the group name of the variables. - * @return a list of the keys in the group. - */ - TQValueList<TQCString> getKeys(const TQCString &group); - - /** - * Returns true if the specified group exists is - * cached. - * - * @param group the group key - * @return true if the group is found - */ - bool findGroup(const TQCString &group); - - /** - * Delete a persistent variable. - * @param key The name of the variable. - * @return zero on success, -1 on failure. - */ - int delVar(const TQCString &key); - - /** - * Delete all persistent variables with the given key. - * - * A specicalized variant of delVar(TQCString) that removes all - * subsets of the cached varaibles given by @p key. In order for all - * cached variables related to this key to be deleted properly, the - * value given to the @p group argument when the setVar function - * was called, must be a subset of the argument given here and the key - * - * @note Simply supplying the group key here WILL not necessarily - * work. If you only have a group key, then use delGroup instead. - * - * @param special_key the name of the variable. - * @return zero on success, -1 on failure. - */ - int delVars(const TQCString &special_key); - - /** - * Delete all persistent variables in a group. - * - * @param group the group name. See setVar. - * @return - */ - int delGroup(const TQCString &group); - - /** - * Ping tdesud. This can be used for diagnostics. - * @return Zero on success, -1 on failure - */ - int ping(); - - /** - * Stop the daemon. - */ - int stopServer(); - - /** - * Try to start up tdesud - */ - int startServer(); - - /** - * Returns true if the server is safe (installed setgid), false otherwise. - */ - bool isServerSGID(); - -private: - int connect(); - - int sockfd; - TQCString sock; - - int command(const TQCString &cmd, TQCString *result=0L); - TQCString escape(const TQCString &str); - - class KDEsuClientPrivate; - KDEsuClientPrivate *d; -}; - -#endif //Q_OS_UNIX - -#endif //__KDE_su_Client_h_Included__ diff --git a/kdesu/configure.in.in b/kdesu/configure.in.in deleted file mode 100644 index 5f398b720..000000000 --- a/kdesu/configure.in.in +++ /dev/null @@ -1,93 +0,0 @@ -dnl Check for su -AC_PATH_PROG(path_su, "su", "no") -if test "$path_su" = "no"; then - AC_MSG_WARN(su was not found) -else - AC_DEFINE_UNQUOTED(__PATH_SU, "$path_su", [path to su]) -fi - -dnl Check for sudo -AC_PATH_PROG(path_sudo, "sudo", "no") -if test "$path_sudo" = "no"; then - AC_MSG_WARN(sudo was not found) -else - AC_DEFINE_UNQUOTED(__PATH_SUDO, "$path_sudo", [path to sudo]) -fi - -AC_ARG_WITH(sudo-tdesu-backend, - AC_HELP_STRING([--with-sudo-tdesu-backend], - [use sudo as backend for tdesu (default is su)]), -[ - if test x$withval = xyes; then - use_tdesu_backend="sudo" - else - use_tdesu_backend="su" - fi -], - use_tdesu_backend="su" -) - -if test x$use_tdesu_backend = xsudo -a x$path_sudo = xno; then - AC_MSG_ERROR(sudo was chosen as tdesu backend, but was not found in path.) -fi - -AC_DEFINE_UNQUOTED(DEFAULT_SUPER_USER_COMMAND, "$use_tdesu_backend", [Use su or sudo]) - -dnl Check for POSIX.1b scheduling -AC_MSG_CHECKING([POSIX.1b scheduling]) -AC_TRY_LINK([ - #include <sched.h> -], -[ - sched_getscheduler(0); -], -have_rtsched="yes", have_rtsched="no") -if test "$have_rtsched" = "yes"; then - AC_DEFINE(POSIX1B_SCHEDULING, 1, [Define if you have POSIX.1b scheduling]) - AC_MSG_RESULT(yes) -else - AC_MSG_RESULT(no) -fi - -dnl Check for initgroups() -AC_CHECK_FUNCS(initgroups) - -dnl openpty stuff -AC_CHECK_HEADERS(libutil.h util.h pty.h) -AC_CHECK_LIB(util, openpty, [AC_DEFINE_UNQUOTED(HAVE_OPENPTY, 1, [Define if you have openpty in -lutil])]) -AC_CHECK_FUNCS(openpty initgroups setgroups getgroups grantpt setpriority getpt unlockpt ptsname) - -AH_VERBATIM(_OPENPTY, -[ -/* - * Steven Schultz <sms at to.gd-es.com> tells us : - * BSD/OS 4.2 doesn't have a prototype for openpty in its system header files - */ -#ifdef __bsdi__ -__BEGIN_DECLS -int openpty(int *, int *, char *, struct termios *, struct winsize *); -__END_DECLS -#endif -]) - -dnl irix pty stuff -AC_CHECK_FUNCS(_getpty) - -AC_MSG_CHECKING([for struct ucred]) -AC_CACHE_VAL(kde_cv_have_struct_ucred, -[ - AC_TRY_COMPILE( - [ - #include <sys/socket.h> - ], - [ - struct ucred cred; - ], kde_cv_have_struct_ucred=yes, - kde_cv_have_struct_ucred=no) -]) - -AC_MSG_RESULT($kde_cv_have_struct_ucred) -if test "$kde_cv_have_struct_ucred" = yes; then - AC_DEFINE(HAVE_STRUCT_UCRED,1, [Define if struct ucred is present from sys/socket.h]) -fi -AC_CHECK_FUNCS(getpeereid) diff --git a/kdesu/defaults.h b/kdesu/defaults.h deleted file mode 100644 index 4649b2b16..000000000 --- a/kdesu/defaults.h +++ /dev/null @@ -1,21 +0,0 @@ -/* vi: ts=8 sts=4 sw=4 - * - * $Id$ - * - * This file is part of the KDE project, module tdesu. - * 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. - */ - -#ifndef __Defaults_h_included__ -#define __Defaults_h_included__ - -/*const int defTimeout = 120*60;*/ -const int defTimeout = 120*60; -const int defEchoMode = 0; -const int defKeep = true; - -#endif diff --git a/kdesu/kcookie.cpp b/kdesu/kcookie.cpp deleted file mode 100644 index 99b34ec4e..000000000 --- a/kdesu/kcookie.cpp +++ /dev/null @@ -1,225 +0,0 @@ -/* vi: ts=8 sts=4 sw=4 - * - * $Id$ - * - * This file is part of the KDE project, module tdesu. - * 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; -} diff --git a/kdesu/kcookie.h b/kdesu/kcookie.h deleted file mode 100644 index 713922011..000000000 --- a/kdesu/kcookie.h +++ /dev/null @@ -1,90 +0,0 @@ -/* vi: ts=8 sts=4 sw=4 - * - * $Id$ - * - * This file is part of the KDE project, module tdesu - * 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. - */ - -#ifndef __KCookie_h_Included__ -#define __KCookie_h_Included__ - -#include <tqcstring.h> -#include <tqvaluelist.h> - -typedef TQValueList<TQCString> QCStringList; - - -/** - * Utility class to access the authentication tokens needed to run a KDE - * program (X11 and DCOP cookies). - */ - -class KDESU_EXPORT KCookie -{ -public: - KCookie(); - - /** - * Returns the X11 display. - */ - TQCString display() { return m_Display; } - -#ifdef Q_WS_X11 - /** - * Returns the X11 magic cookie, if available. - */ - TQCString displayAuth() { return m_DisplayAuth; } -#endif - - /** - * Select the DCOP transport to look for. Default: "local" - */ - void setDcopTransport(const TQCString &dcopTransport); - - /** - * Returns the netid where the dcopserver is running - */ - TQCString dcopServer(); - - /** - * Returns a list of magic cookies for DCOP protocol authentication. - * The order is the same as in dcopServer(). - */ - TQCString dcopAuth(); - - /** - * Returns a list of magic cookies for the ICE protocol. - */ - TQCString iceAuth(); - -private: - void getXCookie(); - void getICECookie(); - QCStringList split(const TQCString &line, char ch); - - void blockSigChild(); - void unblockSigChild(); - - bool m_bHaveDCOPCookies; - bool m_bHaveICECookies; - - TQCString m_Display; -#ifdef Q_WS_X11 - TQCString m_DisplayAuth; -#endif - TQCString m_DCOPSrv; - TQCString m_DCOPAuth; - TQCString m_ICEAuth; - TQCString m_dcopTransport; - - class KCookiePrivate; - KCookiePrivate *d; -}; - - -#endif // __KCookie_h_Included__ diff --git a/kdesu/kdesu_pty.cpp b/kdesu/kdesu_pty.cpp deleted file mode 100644 index d3392ec5e..000000000 --- a/kdesu/kdesu_pty.cpp +++ /dev/null @@ -1,302 +0,0 @@ -/* vi: ts=8 sts=4 sw=4 - * - * $Id$ - * - * This file is part of the KDE project, module tdesu. - * Copyright (C) 1999,2000 Geert Jansen <jansen@kde.org> - * - * This file contains code from TEShell.C of the KDE konsole. - * Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> - * - * 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. - * - * pty.cpp: Access to PTY's on different systems a la UNIX98. - */ - - -#ifndef _GNU_SOURCE -#define _GNU_SOURCE /* Needed for getpt, ptsname in glibc 2.1.x systems */ -#endif - -#include <config.h> - -#include <stdio.h> -#include <fcntl.h> -#include <unistd.h> -#include <string.h> -#include <stdlib.h> -#include <errno.h> - -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/wait.h> -#include <sys/ioctl.h> -#if defined(__osf__) || defined(__CYGWIN__) -#include <pty.h> -#endif - -#include <tqglobal.h> -#include <tqcstring.h> - -#include <kdebug.h> -#include <kstandarddirs.h> -#include "tdesu_pty.h" - -// stdlib.h is meant to declare the prototypes but doesn't :( -#ifndef __THROW -#define __THROW -#endif - -#ifdef HAVE_GRANTPT -extern "C" int grantpt(int fd) __THROW; -#endif - -#ifdef HAVE_PTSNAME -extern "C" char * ptsname(int fd) __THROW; -#endif - -#ifdef HAVE_UNLOCKPT -extern "C" int unlockpt(int fd) __THROW; -#endif - -#ifdef HAVE__GETPTY -extern "C" char *_getpty(int *, int, mode_t, int); -#endif - -#ifdef HAVE_PTY_H - #include <pty.h> -#endif - -#include <termios.h> - -#ifdef HAVE_LIBUTIL_H - #include <libutil.h> -#elif defined(HAVE_UTIL_H) - #include <util.h> -#endif - -PTY::PTY() -{ - ptyfd = -1; -} - -PTY::~PTY() -{ - if (ptyfd >= 0) - close(ptyfd); -} - - -// Opens a pty master and returns its filedescriptor. - -int PTY::getpt() -{ - -#if defined(HAVE_GETPT) && defined(HAVE_PTSNAME) - - // 1: UNIX98: preferred way - ptyfd = ::getpt(); - ttyname = ::ptsname(ptyfd); - return ptyfd; - -#elif defined(HAVE_OPENPTY) - // 2: BSD interface - // More preferred than the linux hacks - char name[30]; - int master_fd, slave_fd; - if (openpty(&master_fd, &slave_fd, name, 0L, 0L) != -1) { - ttyname = name; - name[5]='p'; - ptyname = name; - close(slave_fd); // We don't need this yet // Yes, we do. - ptyfd = master_fd; - return ptyfd; - } - ptyfd = -1; - kdDebug(900) << k_lineinfo << "Opening pty failed.\n"; - return -1; - -#elif defined(HAVE__GETPTY) - // 3: Irix interface - int master_fd; - ttyname = _getpty(&master_fd,O_RDWR,0600,0); - if (ttyname) - ptyfd = master_fd; - else{ - ptyfd = -1; - kdDebug(900) << k_lineinfo << "Opening pty failed.error" << errno << '\n'; - } - return ptyfd; - -#else - - // 4: Open terminal device directly - // 4.1: Try /dev/ptmx first. (Linux w/ Unix98 PTYs, Solaris) - - ptyfd = open("/dev/ptmx", O_RDWR); - if (ptyfd >= 0) { - ptyname = "/dev/ptmx"; -#ifdef HAVE_PTSNAME - ttyname = ::ptsname(ptyfd); - return ptyfd; -#elif defined (TIOCGPTN) - int ptyno; - if (ioctl(ptyfd, TIOCGPTN, &ptyno) == 0) { - ttyname.sprintf("/dev/pts/%d", ptyno); - return ptyfd; - } -#endif - close(ptyfd); - } - - // 4.2: Try /dev/pty[p-e][0-f] (Linux w/o UNIX98 PTY's) - - for (const char *c1 = "pqrstuvwxyzabcde"; *c1 != '\0'; c1++) - { - for (const char *c2 = "0123456789abcdef"; *c2 != '\0'; c2++) - { - ptyname.sprintf("/dev/pty%c%c", *c1, *c2); - ttyname.sprintf("/dev/tty%c%c", *c1, *c2); - if (access(ptyname, F_OK) < 0) - goto linux_out; - ptyfd = open(ptyname, O_RDWR); - if (ptyfd >= 0) - return ptyfd; - } - } -linux_out: - - // 4.3: Try /dev/pty%d (SCO, Unixware) - - for (int i=0; i<256; i++) - { - ptyname.sprintf("/dev/ptyp%d", i); - ttyname.sprintf("/dev/ttyp%d", i); - if (access(ptyname, F_OK) < 0) - break; - ptyfd = open(ptyname, O_RDWR); - if (ptyfd >= 0) - return ptyfd; - } - - - // Other systems ?? - ptyfd = -1; - kdDebug(900) << k_lineinfo << "Unknown system or all methods failed.\n"; - return -1; - -#endif // HAVE_GETPT && HAVE_PTSNAME - -} - - -int PTY::grantpt() -{ - if (ptyfd < 0) - return -1; - -#ifdef HAVE_GRANTPT - - return ::grantpt(ptyfd); - -#elif defined(HAVE_OPENPTY) - - // the BSD openpty() interface chowns the devices properly for us, - // no need to do this at all - return 0; - -#else - - // konsole_grantpty only does /dev/pty?? - if (ptyname.left(8) != "/dev/pty") - return 0; - - // Use konsole_grantpty: - if (KStandardDirs::findExe("konsole_grantpty").isEmpty()) - { - kdError(900) << k_lineinfo << "konsole_grantpty not found.\n"; - return -1; - } - - // As defined in konsole_grantpty.c - const int pty_fileno = 3; - - pid_t pid; - if ((pid = fork()) == -1) - { - kdError(900) << k_lineinfo << "fork(): " << perror << "\n"; - return -1; - } - - if (pid) - { - // Parent: wait for child - int ret; - waitpid(pid, &ret, 0); - if (WIFEXITED(ret) && !WEXITSTATUS(ret)) - return 0; - kdError(900) << k_lineinfo << "konsole_grantpty returned with error: " - << WEXITSTATUS(ret) << "\n"; - return -1; - } else - { - // Child: exec konsole_grantpty - if (ptyfd != pty_fileno && dup2(ptyfd, pty_fileno) < 0) - _exit(1); - execlp("konsole_grantpty", "konsole_grantpty", "--grant", (void *)0); - kdError(900) << k_lineinfo << "exec(): " << perror << "\n"; - _exit(1); - } - - // shut up, gcc - return 0; - -#endif // HAVE_GRANTPT -} - - -/** - * Unlock the pty. This allows connections on the slave side. - */ - -int PTY::unlockpt() -{ - if (ptyfd < 0) - return -1; - -#ifdef HAVE_UNLOCKPT - - // (Linux w/ glibc 2.1, Solaris, ...) - - return ::unlockpt(ptyfd); - -#elif defined(TIOCSPTLCK) - - // Unlock pty (Linux w/ UNIX98 PTY's & glibc 2.0) - int flag = 0; - return ioctl(ptyfd, TIOCSPTLCK, &flag); - -#else - - // Other systems (Linux w/o UNIX98 PTY's, ...) - return 0; - -#endif - -} - - -/** - * Return the slave side name. - */ - -TQCString PTY::ptsname() -{ - if (ptyfd < 0) - return 0; - - return ttyname; -} - diff --git a/kdesu/kdesu_pty.h b/kdesu/kdesu_pty.h deleted file mode 100644 index 1dab49dcb..000000000 --- a/kdesu/kdesu_pty.h +++ /dev/null @@ -1,71 +0,0 @@ -/* vi: ts=8 sts=4 sw=4 - * - * $Id$ - * - * This file is part of the KDE project, module tdesu. - * 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. - */ - - -/** - * PTY compatibility routines. This class tries to emulate a UNIX98 PTY API - * on various platforms. - */ -#ifndef __PTY_h_Included__ -#define __PTY_h_Included__ - -#include <tqcstring.h> - -#include <kdelibs_export.h> - -class KDESU_EXPORT PTY { - -public: - /** - * Construct a PTY object. - */ - PTY(); - - /** - * Destructs the object. The PTY is closed if it is still open. - */ - ~PTY(); - - /** - * Allocate a pty. - * @return A filedescriptor to the master side. - */ - int getpt(); - - /** - * Grant access to the slave side. - * @return Zero if succesfull, < 0 otherwise. - */ - int grantpt(); - - /** - * Unlock the slave side. - * @return Zero if successful, < 0 otherwise. - */ - int unlockpt(); - - /** - * Get the slave name. - * @return The slave name. - */ - TQCString ptsname(); - -private: - - int ptyfd; - TQCString ptyname, ttyname; - - class PTYPrivate; - PTYPrivate *d; -}; - -#endif // __PTY_h_Included__ diff --git a/kdesu/kdesu_stub.c b/kdesu/kdesu_stub.c deleted file mode 100644 index 5e1f09c24..000000000 --- a/kdesu/kdesu_stub.c +++ /dev/null @@ -1,432 +0,0 @@ -/* vi: ts=8 sts=4 sw=4 - * - * $Id$ - * - * This file is part of the KDE project, module tdesu. - * Copyright (C) 1999,2000 Geert Jansen <jansen@kde.org> - * - * tdesu_stub.c: KDE su executes this stub through su or ssh. This stub in turn - * executes the target program. Before that, startup parameters - * are sent through stdin. - * - * - * Available parameters: - * - * Parameter Description Format (csl = comma separated list) - * - * - tdesu_stub Header "ok" | "stop" - * - display X11 display string - * - display_auth X11 authentication "type cookie" pair - * - dcopserver KDE dcopserver csl of netids - * - dcop_auth DCOP authentication csl of "type cookie" pairs for DCOP - * - ice_auth ICE authentication csl of "type cookie" pairs for ICE - * - command Command to run string - * - path PATH env. var string - * - build_sycoca Rebuild sycoca? "yes" | "no" - * - user Target user string - * - priority Process priority 0 <= int <= 100 - * - scheduler Process scheduler "fifo" | "normal" - * - app_startup_id DESKTOP_STARTUP_ID string - * - environment Additional envvars strings, last one is empty - */ - -#include <config.h> - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <errno.h> -#include <pwd.h> -#include <termios.h> -#include <signal.h> - -#ifdef HAVE_INITGROUPS -#include <grp.h> -#endif - -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/wait.h> -#include <sys/time.h> -#include <sys/resource.h> - -#ifdef POSIX1B_SCHEDULING -#include <sched.h> -#endif - -/** - * Params sent by the peer. - */ - -struct param_struct -{ - const char *name; - char *value; -}; - -struct param_struct params[] = -{ - { "tdesu_stub", 0L }, - { "display", 0L }, - { "display_auth", 0L }, - { "dcopserver", 0L }, - { "dcop_auth", 0L }, - { "ice_auth", 0L }, - { "command", 0L }, - { "path", 0L }, - { "xwindows_only", 0L }, - { "user", 0L }, - { "priority", 0L }, - { "scheduler", 0L }, -/* obsoleted by app_startup_id { "app_start_pid", 0L } */ - { "app_startup_id", 0L } -}; - -#define P_HEADER 0 -#define P_DISPLAY 1 -#define P_DISPLAY_AUTH 2 -#define P_DCOPSERVER 3 -#define P_DCOP_AUTH 4 -#define P_ICE_AUTH 5 -#define P_COMMAND 6 -#define P_PATH 7 -#define P_XWIN_ONLY 8 -#define P_USER 9 -#define P_PRIORITY 10 -#define P_SCHEDULER 11 -#define P_APP_STARTUP_ID 12 -#define P_LAST 13 - -/* Prototypes */ -char *xmalloc(size_t); -char *xrealloc(char *ptr, int size); -int xsetenv(const char *name, const char *value); -char *xstrdup(char *src); -char **xstrsep(char *str); - -/** - * Safe malloc functions. - */ -char *xmalloc(size_t size) -{ - char *ptr = malloc(size); - if (ptr) return ptr; - perror("malloc()"); - exit(1); -} - - -char *xrealloc(char *ptr, int size) -{ - ptr = realloc(ptr, size); - if (ptr) return ptr; - perror("realloc()"); - exit(1); -} - - -/** - * Solaris does not have a setenv()... - */ -int xsetenv(const char *name, const char *value) -{ - char *s = malloc(strlen(name)+strlen(value)+2); - if (!s) return -1; - strcpy(s, name); - strcat(s, "="); - strcat(s, value); - return putenv(s); /* yes: no free()! */ -} - -/** - * Safe strdup and strip newline - */ -char *xstrdup(char *src) -{ - int len = strlen(src); - char *dst = xmalloc(len+1); - strcpy(dst, src); - if (dst[len-1] == '\n') - dst[len-1] = '\000'; - return dst; -} - -/** - * Split comma separated list. - */ -char **xstrsep(char *str) -{ - int i = 0, size = 10; - char **list = (char **) xmalloc(size * sizeof(char *)); - char *ptr = str, *nptr; - while ((nptr = strchr(ptr, ',')) != 0L) - { - if (i > size-2) - list = realloc(list, (size *= 2) * sizeof(char *)); - *nptr = '\000'; - list[i++] = ptr; - ptr = nptr+1; - } - if (*ptr != '\000') - list[i++] = ptr; - list[i] = 0L; - return list; -} - -#define BUFSIZE 8192 - -/** - * The main program - */ - -int main() -{ - char buf[BUFSIZE+1]; -#ifndef QWS - char xauthority[200]; -#endif - char iceauthority[200]; - char **host, **auth; - int i/*, res, sycoca*/, prio; - pid_t pid; - FILE *fout; - struct passwd *pw; - const char* tdesu_lc_all; - - /* Get startup parameters. */ - - for (i=0; i<P_LAST; i++) - { - printf("%s\n", params[i].name); - fflush(stdout); - if (fgets(buf, BUFSIZE, stdin) == 0L) - { - printf("end\n"); fflush(stdout); - perror("tdesu_stub: fgets()"); - exit(1); - } - params[i].value = xstrdup(buf); - /* Installation check? */ - if ((i == 0) && !strcmp(params[i].value, "stop")) - { - printf("end\n"); - exit(0); - } - } - printf("environment\n"); - fflush(stdout); - for(;;) - { - char* tmp; - if (fgets(buf, BUFSIZE, stdin) == 0L) - { - printf("end\n"); fflush(stdout); - perror("tdesu_stub: fgets()"); - exit(1); - } - tmp = xstrdup( buf ); - if( tmp[ 0 ] == '\0' ) /* terminator */ - break; - putenv( xstrdup( buf )); - } - - printf("end\n"); - fflush(stdout); - - xsetenv("PATH", params[P_PATH].value); - xsetenv("DESKTOP_STARTUP_ID", params[P_APP_STARTUP_ID].value); - - tdesu_lc_all = getenv( "KDESU_LC_ALL" ); - if( tdesu_lc_all != NULL ) - xsetenv("LC_ALL",tdesu_lc_all); - else - unsetenv("LC_ALL"); - - /* Do we need to change uid? */ - - pw = getpwnam(params[P_USER].value); - if (pw == 0L) - { - printf("tdesu_stub: user %s does not exist!\n", params[P_USER].value); - exit(1); - } - xsetenv("HOME", pw->pw_dir); - - /* Set scheduling/priority */ - - prio = atoi(params[P_PRIORITY].value); - if (!strcmp(params[P_SCHEDULER].value, "realtime")) - { -#ifdef POSIX1B_SCHEDULING - struct sched_param sched; - int min = sched_get_priority_min(SCHED_FIFO); - int max = sched_get_priority_max(SCHED_FIFO); - sched.sched_priority = min + (int) (((double) prio) * (max - min) / 100 + 0.5); - sched_setscheduler(0, SCHED_FIFO, &sched); -#else - printf("tdesu_stub: realtime scheduling not supported\n"); -#endif - } else - { -#ifdef HAVE_SETPRIORITY - int val = 20 - (int) (((double) prio) * 40 / 100 + 0.5); - setpriority(PRIO_PROCESS, getpid(), val); -#endif - } - - /* Drop privileges (this is permanent) */ - - if (getuid() != pw->pw_uid) - { - if (setgid(pw->pw_gid) == -1) - { - perror("tdesu_stub: setgid()"); - exit(1); - } -#ifdef HAVE_INITGROUPS - if (initgroups(pw->pw_name, pw->pw_gid) == -1) - { - perror("tdesu_stub: initgroups()"); - exit(1); - } -#endif - if (setuid(pw->pw_uid) == -1) - { - perror("tdesu_stub: setuid()"); - exit(1); - } - xsetenv("HOME", pw->pw_dir); - } - - /* Handle display */ - - if (strcmp(params[P_DISPLAY].value, "no")) - { -#ifndef QWS - xsetenv("DISPLAY", params[P_DISPLAY].value); - if (params[P_DISPLAY_AUTH].value[0]) - { - int fd2; - /* - ** save umask and set to 077, so we create those files only - ** readable for root. (if someone else could read them, we - ** are in deep shit). - */ - int oldumask = umask(077); - const char *disp = params[P_DISPLAY].value; - if (strncmp(disp, "localhost:", 10) == 0) - disp += 9; - - strcpy(xauthority, "/tmp/xauth.XXXXXXXXXX"); - fd2 = mkstemp(xauthority); - umask(oldumask); - - if (fd2 == -1) { - perror("tdesu_stub: mkstemp()"); - exit(1); - } else - close(fd2); - xsetenv("XAUTHORITY", xauthority); - - fout = popen("xauth >/dev/null 2>&1","w"); - if (fout == NULL) - { - perror("tdesu_stub: popen(xauth)"); - exit(1); - } - fprintf(fout, "add %s %s\n", disp, - params[P_DISPLAY_AUTH].value); - pclose(fout); - } -#else - xsetenv("DISPLAY", params[P_DISPLAY].value); -#endif - } - - - /* Handle DCOP */ - - if (strcmp(params[P_DCOPSERVER].value, "no")) - { - xsetenv("DCOPSERVER", params[P_DCOPSERVER].value); - host = xstrsep(params[P_DCOPSERVER].value); - auth = xstrsep(params[P_ICE_AUTH].value); - if (host[0]) - { - int fd; - int oldumask = umask(077); - - strcpy(iceauthority, "/tmp/iceauth.XXXXXXXXXX"); - fd = mkstemp(iceauthority); - umask(oldumask); - if (fd == -1) { - perror("tdesu_stub: mkstemp()"); - exit(1); - } else - close(fd); - xsetenv("ICEAUTHORITY", iceauthority); - - fout = popen("iceauth >/dev/null 2>&1", "w"); - if (!fout) { - perror("tdesu_stub: popen iceauth"); - exit(1); - } - for (i=0; host[i]; i++) - fprintf(fout, "add ICE \"\" %s %s\n", host[i], auth[i]); - auth = xstrsep(params[P_DCOP_AUTH].value); - for (i=0; host[i]; i++) - fprintf(fout, "add DCOP \"\" %s %s\n", host[i], auth[i]); - pclose(fout); - } - } - - /* Rebuild the sycoca and start tdeinit? */ - - if (strcmp(params[P_XWIN_ONLY].value, "no")) - { - system("tdeinit --suicide"); - } - - /* Execute the command */ - - pid = fork(); - if (pid == -1) - { - perror("tdesu_stub: fork()"); - exit(1); - } - if (pid) - { - /* Parent: wait for child, delete tempfiles and return. */ - int ret, state, xit = 1; - while (1) - { - ret = waitpid(pid, &state, 0); - if (ret == -1) - { - if (errno == EINTR) - continue; - if (errno != ECHILD) - perror("tdesu_stub: waitpid()"); - break; - } - if (WIFEXITED(state)) - xit = WEXITSTATUS(state); - } - -#ifndef QWS - unlink(xauthority); -#endif - unlink(iceauthority); - exit(xit); - } else - { - setsid(); - /* Child: exec command. */ - sprintf(buf, "%s", params[P_COMMAND].value); - execl("/bin/sh", "sh", "-c", buf, (void *)0); - perror("tdesu_stub: exec()"); - _exit(1); - } -} diff --git a/kdesu/libkdesu.nmcheck b/kdesu/libkdesu.nmcheck deleted file mode 100644 index 8e4827481..000000000 --- a/kdesu/libkdesu.nmcheck +++ /dev/null @@ -1,10 +0,0 @@ -# KDE namespace check file - -# tdesu classes -SshProcess:* -PTY::* -SuProcess::* -StubProcess::* -PtyProcess::* -KCookie::* -KDEsuClient::* diff --git a/kdesu/libkdesu_weak.nmcheck b/kdesu/libkdesu_weak.nmcheck deleted file mode 100644 index 6fa8e9176..000000000 --- a/kdesu/libkdesu_weak.nmcheck +++ /dev/null @@ -1,2 +0,0 @@ -# KDE namespace check file - diff --git a/kdesu/process.cpp b/kdesu/process.cpp deleted file mode 100644 index d52308f63..000000000 --- a/kdesu/process.cpp +++ /dev/null @@ -1,626 +0,0 @@ -/* vi: ts=8 sts=4 sw=4 - * - * $Id$ - * - * This file is part of the KDE project, module tdesu. - * Copyright (C) 1999,2000 Geert Jansen <jansen@kde.org> - * - * This file contains code from TEShell.C of the KDE konsole. - * Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> - * - * 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. - * - * process.cpp: Functionality to build a front end to password asking - * terminal programs. - */ - -#include <config.h> - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <fcntl.h> -#include <signal.h> -#include <errno.h> -#include <string.h> -#include <termios.h> -#include <signal.h> - -#include <sys/types.h> -#include <sys/wait.h> -#include <sys/stat.h> -#include <sys/time.h> -#include <sys/resource.h> -#include <sys/ioctl.h> - -#if defined(__SVR4) && defined(sun) -#include <stropts.h> -#include <sys/stream.h> -#endif - -#ifdef HAVE_SYS_SELECT_H -#include <sys/select.h> // Needed on some systems. -#endif - -#include <tqglobal.h> -#include <tqcstring.h> -#include <tqfile.h> - -#include <kconfig.h> -#include <kdebug.h> -#include <kstandarddirs.h> - -#include "process.h" -#include "tdesu_pty.h" -#include "kcookie.h" - -int PtyProcess::waitMS(int fd,int ms) -{ - struct timeval tv; - tv.tv_sec = 0; - tv.tv_usec = 1000*ms; - - fd_set fds; - FD_ZERO(&fds); - FD_SET(fd,&fds); - return select(fd+1, &fds, 0L, 0L, &tv); -} - -/* -** Basic check for the existence of @p pid. -** Returns true iff @p pid is an extant process. -*/ -bool PtyProcess::checkPid(pid_t pid) -{ - KConfig* config = KGlobal::config(); - config->setGroup("super-user-command"); - TQString superUserCommand = config->readEntry("super-user-command", DEFAULT_SUPER_USER_COMMAND); - //sudo does not accept signals from user so we except it - if (superUserCommand == "sudo") { - return true; - } else { - return kill(pid,0) == 0; - } -} - -/* -** Check process exit status for process @p pid. -** On error (no child, no exit), return Error (-1). -** If child @p pid has exited, return its exit status, -** (which may be zero). -** If child @p has not exited, return NotExited (-2). -*/ - -int PtyProcess::checkPidExited(pid_t pid) -{ - int state, ret; - ret = waitpid(pid, &state, WNOHANG); - - if (ret < 0) - { - kdError(900) << k_lineinfo << "waitpid(): " << perror << "\n"; - return Error; - } - if (ret == pid) - { - if (WIFEXITED(state)) - return WEXITSTATUS(state); - return Killed; - } - - return NotExited; -} - - -class PtyProcess::PtyProcessPrivate -{ -public: - QCStringList env; -}; - - -PtyProcess::PtyProcess() -{ - m_bTerminal = false; - m_bErase = false; - m_pPTY = 0L; - d = new PtyProcessPrivate; -} - - -int PtyProcess::init() -{ - delete m_pPTY; - m_pPTY = new PTY(); - m_Fd = m_pPTY->getpt(); - if (m_Fd < 0) - return -1; - if ((m_pPTY->grantpt() < 0) || (m_pPTY->unlockpt() < 0)) - { - kdError(900) << k_lineinfo << "Master setup failed.\n"; - m_Fd = -1; - return -1; - } - m_TTY = m_pPTY->ptsname(); - m_Inbuf.resize(0); - return 0; -} - - -PtyProcess::~PtyProcess() -{ - delete m_pPTY; - delete d; -} - -/** Set additinal environment variables. */ -void PtyProcess::setEnvironment( const QCStringList &env ) -{ - d->env = env; -} - -const QCStringList& PtyProcess::environment() const -{ - return d->env; -} - -/* - * Read one line of input. The terminal is in canonical mode, so you always - * read a line at at time, but it's possible to receive multiple lines in - * one time. - */ - -TQCString PtyProcess::readLine(bool block) -{ - int pos; - TQCString ret; - - if (!m_Inbuf.isEmpty()) - { - pos = m_Inbuf.find('\n'); - if (pos == -1) - { - ret = m_Inbuf; - m_Inbuf.resize(0); - } else - { - ret = m_Inbuf.left(pos); - m_Inbuf = m_Inbuf.mid(pos+1); - } - return ret; - } - - int flags = fcntl(m_Fd, F_GETFL); - if (flags < 0) - { - kdError(900) << k_lineinfo << "fcntl(F_GETFL): " << perror << "\n"; - return ret; - } - int oflags = flags; - if (block) - flags &= ~O_NONBLOCK; - else - flags |= O_NONBLOCK; - - if ((flags != oflags) && (fcntl(m_Fd, F_SETFL, flags) < 0)) - { - // We get an error here when the child process has closed - // the file descriptor already. - return ret; - } - - int nbytes; - char buf[256]; - while (1) - { - nbytes = read(m_Fd, buf, 255); - if (nbytes == -1) - { - if (errno == EINTR) - continue; - else break; - } - if (nbytes == 0) - break; // eof - - buf[nbytes] = '\000'; - m_Inbuf += buf; - - pos = m_Inbuf.find('\n'); - if (pos == -1) - { - ret = m_Inbuf; - m_Inbuf.resize(0); - } else - { - ret = m_Inbuf.left(pos); - m_Inbuf = m_Inbuf.mid(pos+1); - } - break; - } - - return ret; -} - -TQCString PtyProcess::readAll(bool block) -{ - TQCString ret; - - if (!m_Inbuf.isEmpty()) - { - // if there is still something in the buffer, we need not block. - // we should still try to read any further output, from the fd, though. - block = false; - ret = m_Inbuf; - m_Inbuf.resize(0); - } - - int flags = fcntl(m_Fd, F_GETFL); - if (flags < 0) - { - kdError(900) << k_lineinfo << "fcntl(F_GETFL): " << perror << "\n"; - return ret; - } - int oflags = flags; - if (block) - flags &= ~O_NONBLOCK; - else - flags |= O_NONBLOCK; - - if ((flags != oflags) && (fcntl(m_Fd, F_SETFL, flags) < 0)) - { - // We get an error here when the child process has closed - // the file descriptor already. - return ret; - } - - int nbytes; - char buf[256]; - while (1) - { - nbytes = read(m_Fd, buf, 255); - if (nbytes == -1) - { - if (errno == EINTR) - continue; - else break; - } - if (nbytes == 0) - break; // eof - - buf[nbytes] = '\000'; - ret += buf; - break; - } - - return ret; -} - - -void PtyProcess::writeLine(const TQCString &line, bool addnl) -{ - if (!line.isEmpty()) - write(m_Fd, line, line.length()); - if (addnl) - write(m_Fd, "\n", 1); -} - - -void PtyProcess::unreadLine(const TQCString &line, bool addnl) -{ - TQCString tmp = line; - if (addnl) - tmp += '\n'; - if (!tmp.isEmpty()) - m_Inbuf.prepend(tmp); -} - -/* - * Fork and execute the command. This returns in the parent. - */ - -int PtyProcess::exec(const TQCString &command, const QCStringList &args) -{ - kdDebug(900) << k_lineinfo << "Running `" << command << "'\n"; - - if (init() < 0) - return -1; - - // Open the pty slave before forking. See SetupTTY() - int slave = open(m_TTY, O_RDWR); - if (slave < 0) - { - kdError(900) << k_lineinfo << "Could not open slave pty.\n"; - return -1; - } - - if ((m_Pid = fork()) == -1) - { - kdError(900) << k_lineinfo << "fork(): " << perror << "\n"; - return -1; - } - - // Parent - if (m_Pid) - { - close(slave); - return 0; - } - - // Child - if (SetupTTY(slave) < 0) - _exit(1); - - for(QCStringList::ConstIterator it = d->env.begin(); - it != d->env.end(); it++) - { - putenv(const_cast<TQCString&>(*it).data()); - } - unsetenv("TDE_FULL_SESSION"); - - // set temporarily LC_ALL to C, for su (to be able to parse "Password:") - const char* old_lc_all = getenv( "LC_ALL" ); - if( old_lc_all != NULL ) - setenv( "KDESU_LC_ALL", old_lc_all, 1 ); - else - unsetenv( "KDESU_LC_ALL" ); - setenv("LC_ALL", "C", 1); - - // From now on, terminal output goes through the tty. - - TQCString path; - if (command.contains('/')) - path = command; - else - { - TQString file = KStandardDirs::findExe(command); - if (file.isEmpty()) - { - kdError(900) << k_lineinfo << command << " not found\n"; - _exit(1); - } - path = TQFile::encodeName(file); - } - - const char **argp = (const char **)malloc((args.count()+2)*sizeof(char *)); - int i = 0; - argp[i++] = path; - for (QCStringList::ConstIterator it=args.begin(); it!=args.end(); ++it) - argp[i++] = *it; - - argp[i] = 0L; - - execv(path, (char * const *)argp); - kdError(900) << k_lineinfo << "execv(\"" << path << "\"): " << perror << "\n"; - _exit(1); - return -1; // Shut up compiler. Never reached. -} - - -/* - * Wait until the terminal is set into no echo mode. At least one su - * (RH6 w/ Linux-PAM patches) sets noecho mode AFTER writing the Password: - * prompt, using TCSAFLUSH. This flushes the terminal I/O queues, possibly - * taking the password with it. So we wait until no echo mode is set - * before writing the password. - * Note that this is done on the slave fd. While Linux allows tcgetattr() on - * the master side, Solaris doesn't. - */ - -int PtyProcess::WaitSlave() -{ - int slave = open(m_TTY, O_RDWR); - if (slave < 0) - { - kdError(900) << k_lineinfo << "Could not open slave tty.\n"; - return -1; - } - - kdDebug(900) << k_lineinfo << "Child pid " << m_Pid << endl; - - struct termios tio; - while (1) - { - if (!checkPid(m_Pid)) - { - close(slave); - return -1; - } - if (tcgetattr(slave, &tio) < 0) - { - kdError(900) << k_lineinfo << "tcgetattr(): " << perror << "\n"; - close(slave); - return -1; - } - if (tio.c_lflag & ECHO) - { - kdDebug(900) << k_lineinfo << "Echo mode still on.\n"; - waitMS(slave,100); - continue; - } - break; - } - close(slave); - return 0; -} - - -int PtyProcess::enableLocalEcho(bool enable) -{ - int slave = open(m_TTY, O_RDWR); - if (slave < 0) - { - kdError(900) << k_lineinfo << "Could not open slave tty.\n"; - return -1; - } - struct termios tio; - if (tcgetattr(slave, &tio) < 0) - { - kdError(900) << k_lineinfo << "tcgetattr(): " << perror << "\n"; - close(slave); return -1; - } - if (enable) - tio.c_lflag |= ECHO; - else - tio.c_lflag &= ~ECHO; - if (tcsetattr(slave, TCSANOW, &tio) < 0) - { - kdError(900) << k_lineinfo << "tcsetattr(): " << perror << "\n"; - close(slave); return -1; - } - close(slave); - return 0; -} - - -/* - * Copy output to stdout until the child process exists, or a line of output - * matches `m_Exit'. - * We have to use waitpid() to test for exit. Merely waiting for EOF on the - * pty does not work, because the target process may have children still - * attached to the terminal. - */ - -int PtyProcess::waitForChild() -{ - int retval = 1; - - fd_set fds; - FD_ZERO(&fds); - - while (1) - { - FD_SET(m_Fd, &fds); - int ret = select(m_Fd+1, &fds, 0L, 0L, 0L); - if (ret == -1) - { - if (errno != EINTR) - { - kdError(900) << k_lineinfo << "select(): " << perror << "\n"; - return -1; - } - ret = 0; - } - - if (ret) - { - TQCString output = readAll(false); - bool lineStart = true; - while (!output.isNull()) - { - if (!m_Exit.isEmpty()) - { - // match exit string only at line starts - int pos = output.find(m_Exit.data()); - if ((pos >= 0) && ((pos == 0 && lineStart) || (output.at (pos - 1) == '\n'))) - { - kill(m_Pid, SIGTERM); - } - } - if (m_bTerminal) - { - fputs(output, stdout); - fflush(stdout); - } - lineStart = output.tqat( output.length() - 1 ) == '\n'; - output = readAll(false); - } - } - - ret = checkPidExited(m_Pid); - if (ret == Error) - { - if (errno == ECHILD) retval = 0; - else retval = 1; - break; - } - else if (ret == Killed) - { - retval = 0; - break; - } - else if (ret == NotExited) - { - // keep checking - } - else - { - retval = ret; - break; - } - } - return retval; -} - -/* - * SetupTTY: Creates a new session. The filedescriptor "fd" should be - * connected to the tty. It is closed after the tty is reopened to make it - * our controlling terminal. This way the tty is always opened at least once - * so we'll never get EIO when reading from it. - */ - -int PtyProcess::SetupTTY(int fd) -{ - // Reset signal handlers - for (int sig = 1; sig < NSIG; sig++) - signal(sig, SIG_DFL); - signal(SIGHUP, SIG_IGN); - - // Close all file handles - struct rlimit rlp; - getrlimit(RLIMIT_NOFILE, &rlp); - for (int i = 0; i < (int)rlp.rlim_cur; i++) - if (i != fd) close(i); - - // Create a new session. - setsid(); - - // Open slave. This will make it our controlling terminal - int slave = open(m_TTY, O_RDWR); - if (slave < 0) - { - kdError(900) << k_lineinfo << "Could not open slave side: " << perror << "\n"; - return -1; - } - close(fd); - -#if defined(__SVR4) && defined(sun) - - // Solaris STREAMS environment. - // Push these modules to make the stream look like a terminal. - ioctl(slave, I_PUSH, "ptem"); - ioctl(slave, I_PUSH, "ldterm"); - -#endif - -#ifdef TIOCSCTTY - ioctl(slave, TIOCSCTTY, NULL); -#endif - - // Connect stdin, stdout and stderr - dup2(slave, 0); dup2(slave, 1); dup2(slave, 2); - if (slave > 2) - close(slave); - - // Disable OPOST processing. Otherwise, '\n' are (on Linux at least) - // translated to '\r\n'. - struct termios tio; - if (tcgetattr(0, &tio) < 0) - { - kdError(900) << k_lineinfo << "tcgetattr(): " << perror << "\n"; - return -1; - } - tio.c_oflag &= ~OPOST; - if (tcsetattr(0, TCSANOW, &tio) < 0) - { - kdError(900) << k_lineinfo << "tcsetattr(): " << perror << "\n"; - return -1; - } - - return 0; -} - -void PtyProcess::virtual_hook( int, void* ) -{ /*BASE::virtual_hook( id, data );*/ } diff --git a/kdesu/process.h b/kdesu/process.h deleted file mode 100644 index ec3af9a62..000000000 --- a/kdesu/process.h +++ /dev/null @@ -1,188 +0,0 @@ -/* vi: ts=8 sts=4 sw=4 - * - * $Id$ - * - * This file is part of the KDE project, module tdesu. - * 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. - */ - -#ifndef __Process_h_Included__ -#define __Process_h_Included__ - -#include <sys/types.h> - -#include <tqcstring.h> -#include <tqstring.h> -#include <tqstringlist.h> -#include <tqvaluelist.h> - -#include <kdelibs_export.h> - -class PTY; -typedef TQValueList<TQCString> QCStringList; - -/** - * Synchronous communication with tty programs. - * - * PtyProcess provides synchronous communication with tty based programs. - * The communications channel used is a pseudo tty (as opposed to a pipe) - * This means that programs which require a terminal will work. - */ - -class KDESU_EXPORT PtyProcess -{ -public: - PtyProcess(); - virtual ~PtyProcess(); - - /** - * Forks off and execute a command. The command's standard in and output - * are connected to the pseudo tty. They are accessible with readLine - * and writeLine. - * @param command The command to execute. - * @param args The arguments to the command. - */ - int exec(const TQCString &command, const QCStringList &args); - - /** - * Reads a line from the program's standard out. Depending on the @em block - * parameter, this call blocks until a single, full line is read. - * @param block Block until a full line is read? - * @return The output string. - */ - TQCString readLine(bool block=true); - /** - * Read all available output from the program's standard out. - * @param block If no output is in the buffer, should the function block - * @return The output. - */ - TQCString readAll(bool block=true); - - /** - * Writes a line of text to the program's standard in. - * @param line The text to write. - * @param addNewline Adds a '\n' to the line. - */ - void writeLine(const TQCString &line, bool addNewline=true); - - /** - * Puts back a line of input. - * @param line The line to put back. - * @param addNewline Adds a '\n' to the line. - */ - void unreadLine(const TQCString &line, bool addNewline=true); - - /** - * Sets the exit string. If a line of program output matches this, - * waitForChild() will terminate the program and return. - */ - void setExitString(const TQCString &exit) { m_Exit = exit; } - - /** - * Waits for the child to exit. See also setExitString. - */ - int waitForChild(); - - /** - * Waits until the pty has cleared the ECHO flag. This is useful - * when programs write a password prompt before they disable ECHO. - * Disabling it might flush any input that was written. - */ - int WaitSlave(); - - /** - * Enables/disables local echo on the pseudo tty. - */ - int enableLocalEcho(bool enable=true); - - /** - * Enables/disables terminal output. Relevant only to some subclasses. - */ - void setTerminal(bool terminal) { m_bTerminal = terminal; } - - /** - * Overwrites the password as soon as it is used. Relevant only to - * some subclasses. - */ - void setErase(bool erase) { m_bErase = erase; } - - /** - * Set additinal environment variables. - */ - void setEnvironment( const QCStringList &env ); - - /** - * Returns the filedescriptor of the process. - */ - int fd() {return m_Fd;} - - /** - * Returns the pid of the process. - */ - int pid() {return m_Pid;} - -public: /* static */ - /* - ** This is a collection of static functions that can be - ** used for process control inside tdesu. I'd suggest - ** against using this publicly. There are probably - ** nicer Qt based ways to do what you want. - */ - - /** - ** Wait @p ms miliseconds (ie. 1/10th of a second is 100ms), - ** using @p fd as a filedescriptor to wait on. Returns - ** select(2)'s result, which is -1 on error, 0 on timeout, - ** or positive if there is data on one of the selected fd's. - ** - ** @p ms must be in the range 0..999 (ie. the maximum wait - ** duration is 999ms, almost one second). - */ - static int waitMS(int fd,int ms); - - - /** - ** Basic check for the existence of @p pid. - ** Returns true iff @p pid is an extant process, - ** (one you could kill - see man kill(2) for signal 0). - */ - static bool checkPid(pid_t pid); - - /** - ** Check process exit status for process @p pid. - ** On error (no child, no exit), return -1. - ** If child @p pid has exited, return its exit status, - ** (which may be zero). - ** If child @p has not exited, return -2. - */ - enum checkPidStatus { Error=-1, NotExited=-2, Killed=-3 } ; - static int checkPidExited(pid_t pid); - - -protected: - const QCStringList& environment() const; - - bool m_bErase, m_bTerminal; - int m_Pid, m_Fd; - TQCString m_Command, m_Exit; - -private: - int init(); - int SetupTTY(int fd); - - PTY *m_pPTY; - TQCString m_Inbuf, m_TTY; - -protected: - virtual void virtual_hook( int id, void* data ); -private: - class PtyProcessPrivate; - PtyProcessPrivate *d; -}; - - -#endif diff --git a/kdesu/ssh.cpp b/kdesu/ssh.cpp deleted file mode 100644 index f45b38e7e..000000000 --- a/kdesu/ssh.cpp +++ /dev/null @@ -1,279 +0,0 @@ -/* vi: ts=8 sts=4 sw=4 -* -* $Id$ -* -* This file is part of the KDE project, module tdesu. -* Copyright (C) 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. -* -* ssh.cpp: Execute a program on a remote machine using ssh. -*/ - -#include <config.h> - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <fcntl.h> -#include <signal.h> -#include <errno.h> -#include <string.h> -#include <ctype.h> -#include <signal.h> -#include <time.h> - -#include <sys/types.h> -#include <sys/stat.h> - -#include <tqglobal.h> -#include <tqcstring.h> - -#include <kdebug.h> -#include <klocale.h> -#include <kstandarddirs.h> - -#include "ssh.h" -#include "kcookie.h" - - -SshProcess::SshProcess(const TQCString &host, const TQCString &user, const TQCString &command) -{ - m_Host = host; - m_User = user; - m_Command = command; - m_Stub = "tdesu_stub"; - srand(time(0L)); -} - - -SshProcess::~SshProcess() -{ -} - - -void SshProcess::setStub(const TQCString &stub) -{ - m_Stub = stub; -} - - -int SshProcess::checkInstall(const char *password) -{ - return exec(password, 1); -} - - -int SshProcess::checkNeedPassword() -{ - return exec(0L, 2); -} - - -int SshProcess::exec(const char *password, int check) -{ - if (check) - setTerminal(true); - - QCStringList args; - args += "-l"; args += m_User; - args += "-o"; args += "StrictHostKeyChecking=no"; - args += m_Host; args += m_Stub; - - if (StubProcess::exec("ssh", args) < 0) - { - return check ? SshNotFound : -1; - } - - int ret = ConverseSsh(password, check); - if (ret < 0) - { - if (!check) - kdError(900) << k_lineinfo << "Conversation with ssh failed\n"; - return ret; - } - if (check == 2) - { - if (ret == 1) - { - kill(m_Pid, SIGTERM); - waitForChild(); - } - return ret; - } - - if (m_bErase && password) - { - char *ptr = const_cast<char *>(password); - const uint plen = strlen(password); - for (unsigned i=0; i < plen; i++) - ptr[i] = '\000'; - } - - ret = ConverseStub(check); - if (ret < 0) - { - if (!check) - kdError(900) << k_lineinfo << "Converstation with tdesu_stub failed\n"; - return ret; - } - else if (ret == 1) - { - kill(m_Pid, SIGTERM); - waitForChild(); - ret = SshIncorrectPassword; - } - - if (check == 1) - { - waitForChild(); - return 0; - } - - setExitString("Waiting for forwarded connections to terminate"); - ret = waitForChild(); - return ret; -} - -/* -* Create a port forwarding for DCOP. For the remote port, we take a pseudo -* random number between 10k and 50k. This is not ok, of course, but I see -* no other way. There is, afaik, no security issue involved here. If the port -* happens to be occupied, ssh will refuse to start. -* -* 14/SEP/2000: DCOP forwarding is not used anymore. -*/ - -TQCString SshProcess::dcopForward() -{ - TQCString result; - - setDcopTransport("tcp"); - - TQCString srv = StubProcess::dcopServer(); - if (srv.isEmpty()) - return result; - - int i = srv.find('/'); - if (i == -1) - return result; - if (srv.left(i) != "tcp") - return result; - int j = srv.find(':', ++i); - if (j == -1) - return result; - TQCString host = srv.mid(i, j-i); - bool ok; - int port = srv.mid(++j).toInt(&ok); - if (!ok) - return result; - - m_dcopPort = 10000 + (int) ((40000.0 * rand()) / (1.0 + RAND_MAX)); - result.sprintf("%d:%s:%d", m_dcopPort, host.data(), port); - return result; -} - - -/* -* Conversation with ssh. -* If check is 0, this waits for either a "Password: " prompt, -* or the header of the stub. If a prompt is received, the password is -* written back. Used for running a command. -* If check is 1, operation is the same as 0 except that if a stub header is -* received, the stub is stopped with the "stop" command. This is used for -* checking a password. -* If check is 2, operation is the same as 1, except that no password is -* written. The prompt is saved to m_Prompt. Used for checking the need for -* a password. -*/ - -int SshProcess::ConverseSsh(const char *password, int check) -{ - unsigned i, j, colon; - - TQCString line; - int state = 0; - - while (state < 2) - { - line = readLine(); - const uint len = line.length(); - if (line.isNull()) - return -1; - - switch (state) { - case 0: - // Check for "tdesu_stub" header. - if (line == "tdesu_stub") - { - unreadLine(line); - return 0; - } - - // Match "Password: " with the regex ^[^:]+:[\w]*$. - for (i=0,j=0,colon=0; i<len; i++) - { - if (line[i] == ':') - { - j = i; colon++; - continue; - } - if (!isspace(line[i])) - j++; - } - if ((colon == 1) && (line[j] == ':')) - { - if (check == 2) - { - m_Prompt = line; - return SshNeedsPassword; - } - WaitSlave(); - write(m_Fd, password, strlen(password)); - write(m_Fd, "\n", 1); - state++; - break; - } - - // Warning/error message. - m_Error += line; m_Error += "\n"; - if (m_bTerminal) - fprintf(stderr, "ssh: %s\n", line.data()); - break; - - case 1: - if (line.isEmpty()) - { - state++; - break; - } - return -1; - } - } - return 0; -} - - -// Display redirection is handled by ssh natively. -TQCString SshProcess::display() -{ - return "no"; -} - - -TQCString SshProcess::displayAuth() -{ - return "no"; -} - - -// Return the remote end of the forwarded connection. -TQCString SshProcess::dcopServer() -{ - return TQCString().sprintf("tcp/localhost:%d", m_dcopPort); -} - -void SshProcess::virtual_hook( int id, void* data ) -{ StubProcess::virtual_hook( id, data ); } diff --git a/kdesu/ssh.h b/kdesu/ssh.h deleted file mode 100644 index c84c56d02..000000000 --- a/kdesu/ssh.h +++ /dev/null @@ -1,90 +0,0 @@ -/* vi: ts=8 sts=4 sw=4 - * - * $Id$ - * - * This file is part of the KDE project, module tdesu. - * Copyright (C) 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. - */ - -#ifndef __SSH_h_Included__ -#define __SSH_h_Included__ - -#include <tqcstring.h> - -#include "stub.h" - -#include <kdelibs_export.h> - -/** - * Executes a remote command, using ssh. - */ - -class KDESU_EXPORT SshProcess: public StubProcess -{ -public: - SshProcess(const TQCString &host=0, const TQCString &user=0, const TQCString &command=0); - ~SshProcess(); - - enum Errors { SshNotFound=1, SshNeedsPassword, SshIncorrectPassword }; - - /** - * Sets the target host. - */ - void setHost(const TQCString &host) { m_Host = host; } - - /** - * Sets the localtion of the remote stub. - */ - void setStub(const TQCString &stub); - - /** - * Checks if the current user\@host needs a password. - * @return The prompt for the password if a password is required. A null - * string otherwise. - * - * @todo The return doc is so obviously wrong that the C code needs to be checked. - */ - int checkNeedPassword(); - - /** - * Checks if the stub is installed and if the password is correct. - * @return Zero if everything is correct, nonzero otherwise. - */ - int checkInstall(const char *password); - - /** - * Executes the command. - */ - int exec(const char *password, int check=0); - - TQCString prompt() { return m_Prompt; } - TQCString error() { return m_Error; } - -protected: - virtual TQCString display(); - virtual TQCString displayAuth(); - virtual TQCString dcopServer(); - -private: - TQCString dcopForward(); - int ConverseSsh(const char *password, int check); - - int m_dcopPort; - int m_dcopSrv; - TQCString m_Prompt; - TQCString m_Host; - TQCString m_Error; - TQCString m_Stub; - -protected: - virtual void virtual_hook( int id, void* data ); -private: - class SshProcessPrivate; - SshProcessPrivate *d; -}; - -#endif diff --git a/kdesu/stub.cpp b/kdesu/stub.cpp deleted file mode 100644 index 7f083d71b..000000000 --- a/kdesu/stub.cpp +++ /dev/null @@ -1,184 +0,0 @@ -/* vi: ts=8 sts=4 sw=4 - * - * $Id$ - * - * This file is part of the KDE project, module tdesu. - * 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. - * - * stub.cpp: Conversation with tdesu_stub. - */ - -#include <config.h> -#include <stdlib.h> -#include <unistd.h> - -#include <tqglobal.h> -#include <tqcstring.h> -#include <kdatastream.h> - -#include <kapplication.h> -#include <kdebug.h> -#include <dcopclient.h> - -#include "stub.h" -#include "kcookie.h" - - -StubProcess::StubProcess() -{ - m_User = "root"; - m_Scheduler = SchedNormal; - m_Priority = 50; - m_pCookie = new KCookie; - m_bXOnly = true; - m_bDCOPForwarding = false; -} - - -StubProcess::~StubProcess() -{ - delete m_pCookie; -} - - -void StubProcess::setPriority(int prio) -{ - if (prio > 100) - m_Priority = 100; - else if (prio < 0) - m_Priority = 0; - else - m_Priority = prio; -} - - -TQCString StubProcess::commaSeparatedList(QCStringList lst) -{ - if (lst.count() == 0) - return TQCString(""); - - QCStringList::Iterator it = lst.begin(); - TQCString str = *it; - for (it++; it!=lst.end(); it++) - { - str += ','; - str += *it; - } - return str; -} - -/* - * Conversation with tdesu_stub. This is how we pass the authentication - * tokens (X11, DCOP) and other stuff to tdesu_stub. - * return values: -1 = error, 0 = ok, 1 = kill me - */ - -int StubProcess::ConverseStub(int check) -{ - TQCString line, tmp; - while (1) - { - line = readLine(); - if (line.isNull()) - return -1; - - if (line == "tdesu_stub") - { - // This makes parsing a lot easier. - enableLocalEcho(false); - if (check) writeLine("stop"); - else writeLine("ok"); - } else if (line == "display") { - writeLine(display()); - } else if (line == "display_auth") { -#ifdef Q_WS_X11 - writeLine(displayAuth()); -#else - writeLine(""); -#endif - } else if (line == "dcopserver") { - if (m_bDCOPForwarding) - writeLine(dcopServer()); - else - writeLine("no"); - } else if (line == "dcop_auth") { - if (m_bDCOPForwarding) - writeLine(dcopAuth()); - else - writeLine("no"); - } else if (line == "ice_auth") { - if (m_bDCOPForwarding) - writeLine(iceAuth()); - else - writeLine("no"); - } else if (line == "command") { - writeLine(m_Command); - } else if (line == "path") { - TQCString path = getenv("PATH"); - if (!path.isEmpty() && path[0] == ':') - path = path.mid(1); - if (m_User == "root") - if (!path.isEmpty()) - path = "/sbin:/bin:/usr/sbin:/usr/bin:" + path; - else - path = "/sbin:/bin:/usr/sbin:/usr/bin"; - writeLine(path); - } else if (line == "user") { - writeLine(m_User); - } else if (line == "priority") { - tmp.setNum(m_Priority); - writeLine(tmp); - } else if (line == "scheduler") { - if (m_Scheduler == SchedRealtime) writeLine("realtime"); - else writeLine("normal"); - } else if (line == "xwindows_only") { - if (m_bXOnly) writeLine("no"); - else writeLine("yes"); - } else if (line == "app_startup_id") { - QCStringList env = environment(); - TQCString tmp; - for( QCStringList::ConstIterator it = env.begin(); - it != env.end(); - ++it ) - { - if( (*it).find( "DESKTOP_STARTUP_ID=" ) == 0 ) - tmp = (*it).mid( strlen( "DESKTOP_STARTUP_ID=" )); - } - if( tmp.isEmpty()) - tmp = "0"; - writeLine(tmp); - } else if (line == "app_start_pid") { // obsolete - tmp.setNum(getpid()); - writeLine(tmp); - } else if (line == "environment") { // additional env vars - QCStringList env = environment(); - for( QCStringList::ConstIterator it = env.begin(); - it != env.end(); - ++it ) - writeLine( *it ); - writeLine( "" ); - } else if (line == "end") { - return 0; - } else - { - kdWarning(900) << k_lineinfo << "Unknown request: -->" << line - << "<--\n"; - return 1; - } - } - - return 0; -} - - -void StubProcess::notifyTaskbar(const TQString &) -{ - kdWarning(900) << "Obsolete StubProcess::notifyTaskbar() called!" << endl; -} - -void StubProcess::virtual_hook( int id, void* data ) -{ PtyProcess::virtual_hook( id, data ); } diff --git a/kdesu/stub.h b/kdesu/stub.h deleted file mode 100644 index 8bfc70a7f..000000000 --- a/kdesu/stub.h +++ /dev/null @@ -1,139 +0,0 @@ -/* vi: ts=8 sts=4 sw=4 - * - * $Id$ - * - * This file is part of the KDE project, module tdesu. - * 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. - */ - -#ifndef __Stub_h_Included__ -#define __Stub_h_Included__ - -#include <tqcstring.h> -#include <tqvaluelist.h> - -#include "process.h" -#include "kcookie.h" - -#include <kdelibs_export.h> - -typedef TQValueList<TQCString> QCStringList; - -/** - * Chat with tdesu_stub. - * - * StubProcess extends PtyProcess with functionality to chat with tdesu_stub. - */ - -class KDESU_EXPORT StubProcess: public PtyProcess -{ -public: - StubProcess(); - ~StubProcess(); - - /** - * Specify dcop transport - */ - void setDcopTransport(const TQCString &dcopTransport) - { m_pCookie->setDcopTransport(dcopTransport); } - - /** - * Set the command. - */ - void setCommand(const TQCString &command) { m_Command = command; } - - /** - * Set the target user. - */ - void setUser(const TQCString &user) { m_User = user; } - - /** - * Set to "X only mode": Sycoca is not built and tdeinit is not launched. - */ - void setXOnly(bool xonly) { m_bXOnly = xonly; } - - /** - * Enable DCOP forwarding. - */ - void setDCOPForwarding(bool dcopForwarding) { m_bDCOPForwarding = dcopForwarding; } - - /** - * Set the priority of the process. The priority value must be between 0 - * and 100, 0 being the lowest priority. This value is mapped to the - * scheduler and system dependant priority range of the OS. - */ - void setPriority(int prio); - - /** - * Different schedulers. SchedNormal is the normal Unix timesharing - * scheduler, while SchedRealtime is a POSIX.1b realtime scheduler. - */ - enum Scheduler { SchedNormal, SchedRealtime }; - - /** - * Set the scheduler type. - */ - void setScheduler(int sched) { m_Scheduler = sched; } - -protected: - - /** - * Exchange all parameters with tdesu_stub. - */ - int ConverseStub(int check); - - /** - * Notify the taskbar that a new application has been started. - * @obsolete - */ - // KDE4 remove - void notifyTaskbar(const TQString &suffix); - - /** - * This virtual function can be overloaded when special behavior is - * desired. By default, it returns the value returned by KCookie. - */ - virtual TQCString display() { return m_pCookie->display(); } -#ifdef Q_WS_X11 - /** - * See display. - */ - virtual TQCString displayAuth() { return m_pCookie->displayAuth(); } -#endif - /** - * See display. - */ - virtual TQCString dcopServer() { return m_pCookie->dcopServer(); } - /** - * See display. - */ - virtual TQCString dcopAuth() { return m_pCookie->dcopAuth(); } - /** - * See display. - */ - virtual TQCString iceAuth() { return m_pCookie->iceAuth(); } - - bool m_bXOnly; - bool m_bDCOPForwarding; - int m_Priority; - int m_Scheduler; - TQCString m_dcopTransport; - TQCString m_Command; - TQCString m_User; - KCookie *m_pCookie; - -private: - TQCString commaSeparatedList(QCStringList); - -protected: - virtual void virtual_hook( int id, void* data ); -private: - class StubProcessPrivate; - StubProcessPrivate *d; -}; - -#endif // __Stub_h_Included__ diff --git a/kdesu/su.cpp b/kdesu/su.cpp deleted file mode 100644 index 0739c29c3..000000000 --- a/kdesu/su.cpp +++ /dev/null @@ -1,342 +0,0 @@ -/* vi: ts=8 sts=4 sw=4 -* -* $Id$ -* -* This file is part of the KDE project, module tdesu. -* Copyright (C) 1999,2000 Geert Jansen <jansen@kde.org> -* -* Sudo support added by Jonathan Riddell <jriddell@ ubuntu.com> -* Copyright (C) 2005 Canonical Ltd -* -* 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. -* -* su.cpp: Execute a program as another user with "class SuProcess". -*/ - -#include <config.h> - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <fcntl.h> -#include <errno.h> -#include <string.h> -#include <ctype.h> -#include <signal.h> - -#include <sys/types.h> -#include <sys/stat.h> - -#include <tqglobal.h> -#include <tqcstring.h> -#include <tqfile.h> - -#include <kconfig.h> -#include <kdebug.h> -#include <klocale.h> -#include <kstandarddirs.h> - -#include "su.h" -#include "kcookie.h" - - -#ifndef __PATH_SU -#define __PATH_SU "false" -#endif - -#ifndef __PATH_SUDO -#define __PATH_SUDO "false" -#endif - -SuProcess::SuProcess(const TQCString &user, const TQCString &command) -{ - m_User = user; - m_Command = command; - - KConfig* config = KGlobal::config(); - config->setGroup("super-user-command"); - superUserCommand = config->readEntry("super-user-command", DEFAULT_SUPER_USER_COMMAND); - if ( superUserCommand != "sudo" && superUserCommand != "su" ) { - kdWarning() << "unknown super user command" << endl; - superUserCommand = "su"; - } -} - - -SuProcess::~SuProcess() -{ -} - -int SuProcess::checkInstall(const char *password) -{ - return exec(password, Install); -} - -int SuProcess::checkNeedPassword() -{ - return exec(0L, NeedPassword); -} - -/* -* Execute a command with su(1). -*/ - -int SuProcess::exec(const char *password, int check) -{ - if (check) - setTerminal(true); - - // since user may change after constructor (due to setUser()) - // we need to override sudo with su for non-root here - if (m_User != "root") { - superUserCommand = "su"; - } - - QCStringList args; - if (superUserCommand == "sudo") { - args += "-u"; - } - -#ifdef Q_OS_DARWIN - args += "-c"; - args += "staff"; -#endif - - if ((m_Scheduler != SchedNormal) || (m_Priority > 50)) - args += "root"; - else - args += m_User; - - if (superUserCommand == "su") { - args += "-c"; - } - args += TQCString(__KDE_BINDIR) + "/tdesu_stub"; -#ifndef Q_OS_DARWIN - args += "-"; -#endif - - /// TQCString command = __PATH_SU; - /// if (::access(__PATH_SU, X_OK) != 0) - TQCString command; - if (superUserCommand == "sudo") { - command = __PATH_SUDO; - } else { - command = __PATH_SU; - } - - if (::access(command, X_OK) != 0) - { - /// command = TQFile::encodeName(KGlobal::dirs()->findExe("su")); - command = TQFile::encodeName( KGlobal::dirs()->findExe(superUserCommand.ascii()) ); - if (command.isEmpty()) - return check ? SuNotFound : -1; - } - - // kdDebug(900) << k_lineinfo << "Call StubProcess::exec()" << endl; - if (StubProcess::exec(command, args) < 0) - { - return check ? SuNotFound : -1; - } - // kdDebug(900) << k_lineinfo << "Done StubProcess::exec()" << endl; - - SuErrors ret = (SuErrors) ConverseSU(password); - // kdDebug(900) << k_lineinfo << "Conversation returned " << ret << endl; - - if (ret == error) - { - if (!check) - kdError(900) << k_lineinfo << "Conversation with " << superUserCommand << " failed\n"; - return ret; - } - if (check == NeedPassword) - { - if (ret == killme) - { - /// if (kill(m_Pid, SIGKILL) < 0) - /// { - /// ret=error; - /// } - if ( superUserCommand == "sudo" ) { - // sudo can not be killed, just return - return ret; - } - if (kill(m_Pid, SIGKILL) < 0) { - kdDebug() << k_funcinfo << "kill < 0" << endl; - //FIXME SIGKILL doesn't work for sudo, - //why is this different from su? - ret=error; - } - else - { - int iret = waitForChild(); - if (iret < 0) ret=error; - else /* nothing */ {} ; - } - } - return ret; - } - - if (m_bErase && password) - { - char *ptr = const_cast<char *>(password); - const uint plen = strlen(password); - for (unsigned i=0; i < plen; i++) - ptr[i] = '\000'; - } - - if (ret == notauthorized) - { - kill(m_Pid, SIGKILL); - if (superUserCommand != "sudo") { - waitForChild(); - } - return SuIncorrectPassword; - } - - int iret = ConverseStub(check); - if (iret < 0) - { - if (!check) - kdError(900) << k_lineinfo << "Converstation with tdesu_stub failed\n"; - return iret; - } - else if (iret == 1) - { - kill(m_Pid, SIGKILL); - waitForChild(); - return SuIncorrectPassword; - } - - if (check == Install) - { - waitForChild(); - return 0; - } - - iret = waitForChild(); - return iret; -} - -/* -* Conversation with su: feed the password. -* Return values: -1 = error, 0 = ok, 1 = kill me, 2 not authorized -*/ - -int SuProcess::ConverseSU(const char *password) -{ - enum { WaitForPrompt, CheckStar, HandleStub } state = WaitForPrompt; - int colon; - unsigned i, j; - // kdDebug(900) << k_lineinfo << "ConverseSU starting." << endl; - - TQCString line; - while (true) - { - line = readLine(); - if (line.isNull()) - return ( state == HandleStub ? notauthorized : error); - kdDebug(900) << k_lineinfo << "Read line <" << line << ">" << endl; - - switch (state) - { - ////////////////////////////////////////////////////////////////////////// - case WaitForPrompt: - { - // In case no password is needed. - if (line == "tdesu_stub") - { - unreadLine(line); - return ok; - } - - while(waitMS(m_Fd,100)>0) - { - // There is more output available, so the previous line - // couldn't have been a password prompt (the definition - // of prompt being that there's a line of output followed - // by a colon, and then the process waits). - TQCString more = readLine(); - if (more.isEmpty()) - break; - - line = more; - kdDebug(900) << k_lineinfo << "Read line <" << more << ">" << endl; - } - - // Match "Password: " with the regex ^[^:]+:[\w]*$. - const uint len = line.length(); - for (i=0,j=0,colon=0; i<len; i++) - { - if (line[i] == ':') - { - j = i; colon++; - continue; - } - if (!isspace(line[i])) - j++; - } - if ((colon == 1) && (line[j] == ':')) - { - if (password == 0L) - return killme; - if (!checkPid(m_Pid)) - { - kdError(900) << superUserCommand << " has exited while waiting for pwd." << endl; - return error; - } - if ((WaitSlave() == 0) && checkPid(m_Pid)) - { - write(m_Fd, password, strlen(password)); - write(m_Fd, "\n", 1); - state=CheckStar; - } - else - { - return error; - } - } - break; - } - ////////////////////////////////////////////////////////////////////////// - case CheckStar: - { - TQCString s = line.stripWhiteSpace(); - if (s.isEmpty()) - { - state=HandleStub; - break; - } - const uint len = line.length(); - for (i=0; i< len; i++) - { - if (s[i] != '*') - return error; - } - state=HandleStub; - break; - } - ////////////////////////////////////////////////////////////////////////// - case HandleStub: - // Read till we get "tdesu_stub" - if (line == "tdesu_stub") - { - unreadLine(line); - return ok; - } else if (superUserCommand == "sudo") { - // sudo gives a "sorry" line so reaches here - // with the wrong password - return notauthorized; - } - break; - ////////////////////////////////////////////////////////////////////////// - } // end switch - } // end while (true) - return ok; -} - -void SuProcess::virtual_hook( int id, void* data ) -{ StubProcess::virtual_hook( id, data ); } - - diff --git a/kdesu/su.h b/kdesu/su.h deleted file mode 100644 index dcb67a14c..000000000 --- a/kdesu/su.h +++ /dev/null @@ -1,63 +0,0 @@ -/* vi: ts=8 sts=4 sw=4 - * - * $Id$ - * - * This file is part of the KDE project, module tdesu. - * 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. - */ - -#ifndef __SU_h_Included__ -#define __SU_h_Included__ - -#include <tqcstring.h> - -#include <kdelibs_export.h> - -#include "stub.h" - -/** - * Executes a command under elevated privileges, using su. - */ - -class KDESU_EXPORT SuProcess: public StubProcess -{ -public: - SuProcess(const TQCString &user=0, const TQCString &command=0); - ~SuProcess(); - - enum Errors { SuNotFound=1, SuNotAllowed, SuIncorrectPassword }; - - /** - * Executes the command. This will wait for the command to finish. - */ - enum checkMode { NoCheck=0, Install=1, NeedPassword=2 } ; - int exec(const char *password, int check=NoCheck); - - /** - * Checks if the stub is installed and the password is correct. - * @return Zero if everything is correct, nonzero otherwise. - */ - int checkInstall(const char *password); - - /** - * Checks if a password is needed. - */ - int checkNeedPassword(); - -private: - enum SuErrors { error=-1, ok=0, killme=1, notauthorized=2 } ; - int ConverseSU(const char *password); - -protected: - virtual void virtual_hook( int id, void* data ); -private: - class SuProcessPrivate; - SuProcessPrivate *d; - TQString superUserCommand; -}; - -#endif |