diff options
Diffstat (limited to 'kdecore/ksocks.cpp')
-rw-r--r-- | kdecore/ksocks.cpp | 600 |
1 files changed, 0 insertions, 600 deletions
diff --git a/kdecore/ksocks.cpp b/kdecore/ksocks.cpp deleted file mode 100644 index e596c50d9..000000000 --- a/kdecore/ksocks.cpp +++ /dev/null @@ -1,600 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 2001-2003 George Staikos <staikos@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 as published by the Free Software Foundation. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include <config.h> - -#ifdef HAVE_SYS_TIME_H -#include <sys/time.h> -#endif - -#include <tqfile.h> -#include <tqstring.h> -#include <tqmap.h> - -#include <klocale.h> -#include <kdebug.h> -#include "klibloader.h" -#include <kconfig.h> -#include <kapplication.h> - -#include <sys/types.h> -#include <sys/socket.h> - -#include <unistd.h> - -#include "ksocks.h" - -// DO NOT RE-ORDER THESE. -enum SymbolKeys { - S_SOCKSinit = 0, - S_connect = 1, - S_read = 2, - S_write = 3, - S_recvfrom = 4, - S_sendto = 5, - S_recv = 6, - S_send = 7, - S_getsockname = 8, - S_getpeername = 9, - S_accept = 10, - S_select = 11, - S_listen = 12, - S_bind = 13 - }; - - -extern "C" { -// Function pointer table -static int (*F_SOCKSinit) (char *) = 0L; -static int (*F_connect) (int, const struct sockaddr *, ksocklen_t) = 0L; -static signed long int (*F_read) (int, void *, unsigned long int) = 0L; -static signed long int (*F_write) (int, const void *, unsigned long int) = 0L; -static int (*F_recvfrom) (int, void *, unsigned long int, int, struct sockaddr *, - ksocklen_t *) = 0L; -static int (*F_sendto) (int, const void *, unsigned long int, int, - const struct sockaddr *, ksocklen_t) = 0L; -static int (*F_recv) (int, void *, unsigned long int, int) = 0L; -static int (*F_send) (int, const void *, unsigned long int, int) = 0L; -static int (*F_getsockname) (int, struct sockaddr *, ksocklen_t *) = 0L; -static int (*F_getpeername) (int, struct sockaddr *, ksocklen_t *) = 0L; -static int (*F_accept) (int, struct sockaddr *, ksocklen_t *) = 0L; -static int (*F_select) (int, fd_set *, fd_set *, fd_set *, - struct timeval *) = 0L; -static int (*F_listen) (int, int) = 0L; -static int (*F_bind) (int, const struct sockaddr *, ksocklen_t) = 0L; -} - - -class KSocksTable { - public: - KSocksTable(); - virtual ~KSocksTable(); - - // The name of each symbol and it's SOCKS replacement - TQMap<SymbolKeys,TQString> symbols; - // The name of this library - TQString myname; - bool hasWorkingAsyncConnect; -}; - - -KSocksTable::KSocksTable() : myname("Unknown"), hasWorkingAsyncConnect(true) { -} - -KSocksTable::~KSocksTable() { -} - - -/* - * How to add support for a new SOCKS package. - * - * 1) Subclass KSocksTable as is done below and write out all the symbols - * 1.b) Give the class a "myname" - * 2) Make sure that all possible library names are written into the - * _libNames string list. Don't forget that different OSes name shared - * libraries differently. Expect .so, .sl, .a (!) (AIX does this). - * 3) Find a unique symbol in the library that we can use to identify that - * library and write out the test case in the constructor - * 4) Make necessary changes to the KControl module in kdebase/kcontrol/.... - * 5) TEST! - * - */ - -////////////////////////////////////////////////////////////////// -/////// Define each library symbol table here /////// -////////////////////////////////////////////////////////////////// - - -// -// Support for NEC SOCKS client -// - -class KNECSocksTable : public KSocksTable { - public: - KNECSocksTable(); - virtual ~KNECSocksTable(); -}; - - -KNECSocksTable::KNECSocksTable() : KSocksTable() { - myname = i18n("NEC SOCKS client"); - symbols.insert(S_SOCKSinit, "SOCKSinit"); - symbols.insert(S_connect, "connect"); - symbols.insert(S_read, "read"); - symbols.insert(S_write, "write"); - symbols.insert(S_recvfrom, "recvfrom"); - symbols.insert(S_sendto, "sendto"); - symbols.insert(S_recv, "recv"); - symbols.insert(S_send, "send"); - symbols.insert(S_getsockname, "getsockname"); - symbols.insert(S_getpeername, "getpeername"); - symbols.insert(S_accept, "accept"); - symbols.insert(S_select, "select"); - symbols.insert(S_listen, "listen"); - symbols.insert(S_bind, "bind"); -} - -KNECSocksTable::~KNECSocksTable() { -} - - - - -// -// Support for Dante SOCKS client -// - -class KDanteSocksTable : public KSocksTable { - public: - KDanteSocksTable(); - virtual ~KDanteSocksTable(); -}; - -KDanteSocksTable::KDanteSocksTable() : KSocksTable() { - hasWorkingAsyncConnect = false; - myname = i18n("Dante SOCKS client"); - symbols.insert(S_SOCKSinit, "SOCKSinit"); - symbols.insert(S_connect, "Rconnect"); - symbols.insert(S_read, "Rread"); - symbols.insert(S_write, "Rwrite"); - symbols.insert(S_recvfrom, "Rrecvfrom"); - symbols.insert(S_sendto, "Rsendto"); - symbols.insert(S_recv, "Rrecv"); - symbols.insert(S_send, "Rsend"); - symbols.insert(S_getsockname, "Rgetsockname"); - symbols.insert(S_getpeername, "Rgetpeername"); - symbols.insert(S_accept, "Raccept"); - symbols.insert(S_select, "Rselect"); - symbols.insert(S_listen, "Rlisten"); - symbols.insert(S_bind, "Rbind"); -} - - -KDanteSocksTable::~KDanteSocksTable() { -} - - - -////////////////////////////////////////////////////////////////// -/////// End of all symbol table definitions /////// -////////////////////////////////////////////////////////////////// - - -KSocks *KSocks::_me = 0; -#ifdef __CYGWIN__ -bool KSocks::_disabled = true; -#else -bool KSocks::_disabled = false; -#endif -static KStaticDeleter<KSocks> med; - -void KSocks::disable() -{ - if (!_me) - _disabled = true; -} - -KSocks *KSocks::self() { - // Note that we don't use a static deleter here. It makes no sense and tends to cause crashes. - if (!_me) { - if (kapp) { - KConfigGroup cfg(kapp->config(), "Socks"); - _me = new KSocks(&cfg); - } else { - _disabled = true; - _me = new KSocks(0); - } - } - return _me; -} - -void KSocks::setConfig(KConfigBase *config) -{ - // We can change the config from disabled to enabled - // but not the other way around. - if (_me && _disabled) { - delete _me; - _me = 0; - _disabled = false; - } - if (!_me) - _me = new KSocks(config); -} - -bool KSocks::activated() { return (_me != 0L); } - - -KSocks::KSocks(KConfigBase *config) : _socksLib(0L), _st(0L) { - _hasSocks = false; - _useSocks = false; - - if (!config) - return; - - if (!(config->readBoolEntry("SOCKS_enable", false))) { - _disabled = true; - } - - if (_disabled) - return; - - _libPaths << "" - << "/usr/lib" KDELIBSUFF "/" - << "/usr/lib/" - << "/usr/local/lib" KDELIBSUFF "/" - << "/usr/local/lib/" - << "/usr/local/socks5/lib" KDELIBSUFF "/" - << "/usr/local/socks5/lib/" - << "/opt/socks5/lib" KDELIBSUFF "/" - << "/opt/socks5/lib/"; - _libNames << "libsocks.so" // Dante - << "libdsocksd.so.0" // Dante 1.1.14-2 on - // Debian unstable 17-12-2003 - << "libsocks5.so" // ? - << "libsocks5_sh.so"; // NEC - - // Add the custom library paths here - TQStringList newlibs = config->readListEntry("SOCKS_lib_path"); - - for (TQStringList::Iterator it = newlibs.begin(); - it != newlibs.end(); - ++it) { - TQString thisone = *it; - if (thisone[thisone.length()-1] != '/') thisone += "/"; - _libPaths << thisone; - kdDebug(171) << "KSocks added a new library path: " << thisone << endl; - } - - // Load the proper libsocks and KSocksTable - KLibLoader *ll = KLibLoader::self(); - - - int _meth = config->readNumEntry("SOCKS_method", 1); - /**** Current methods - * 1) Autodetect (read: any) 2) NEC - * 3) Dante 4) Custom - */ - - if (_meth == 4) { // try to load^H^H^H^Hguess at a custom library - _socksLib = ll->library(config->readPathEntry("SOCKS_lib").latin1()); - if (_socksLib && _socksLib->symbol("Rconnect")) { // Dante compatible? - _st = new KDanteSocksTable; - _useSocks = true; - _hasSocks = true; - } else if (_socksLib && _socksLib->symbol("connect")) { // NEC compatible? - _st = new KNECSocksTable; - _useSocks = true; - _hasSocks = true; - } else if (_socksLib) { - _socksLib->unload(); - _socksLib = 0L; - } - } else // leave this here "else for {}" - for (TQStringList::Iterator pit = _libPaths.begin(); - !_hasSocks && pit != _libPaths.end(); - ++pit) - for (TQStringList::Iterator it = _libNames.begin(); - it != _libNames.end(); - ++it) { - _socksLib = ll->library((*pit + *it).latin1()); - if (_socksLib) { - if ((_meth == 1 || _meth == 2) && - _socksLib->symbol("S5LogShowThreadIDS") != 0L) { // NEC SOCKS - kdDebug(171) << "Found NEC SOCKS" << endl; - _st = new KNECSocksTable; - _useSocks = true; - _hasSocks = true; - break; - } else if ((_meth == 1 || _meth == 3) && - _socksLib->symbol("sockaddr2ruleaddress") != 0L) { //Dante - kdDebug(171) << "Found Dante SOCKS" << endl; - _st = new KDanteSocksTable; - _useSocks = true; - _hasSocks = true; - break; - } else { - _socksLib->unload(); - _socksLib = 0L; - } - } - } - - // Load in all the symbols - if (_st) { - for (TQMap<SymbolKeys,TQString>::Iterator it = _st->symbols.begin(); - it != _st->symbols.end(); - ++it) { - switch(it.key()) { - case S_SOCKSinit: - F_SOCKSinit = (int (*)(char *)) - _socksLib->symbol(it.data().latin1()); - break; - case S_connect: - F_connect = (int (*)(int, const struct sockaddr *, ksocklen_t)) - _socksLib->symbol(it.data().latin1()); - break; - case S_read: - F_read = (signed long int (*)(int, void *, unsigned long int)) - _socksLib->symbol(it.data().latin1()); - break; - case S_write: - F_write = (signed long int (*)(int, const void *, unsigned long int)) - _socksLib->symbol(it.data().latin1()); - break; - case S_recvfrom: - F_recvfrom = (int (*)(int, void *, unsigned long int, int, - struct sockaddr *, ksocklen_t *)) - _socksLib->symbol(it.data().latin1()); - break; - case S_sendto: - F_sendto = (int (*)(int, const void *, unsigned long int, int, - const struct sockaddr *, ksocklen_t)) - _socksLib->symbol(it.data().latin1()); - break; - case S_recv: - F_recv = (int (*)(int, void *, unsigned long int, int)) - _socksLib->symbol(it.data().latin1()); - break; - case S_send: - F_send = (int (*)(int, const void *, unsigned long int, int)) - _socksLib->symbol(it.data().latin1()); - break; - case S_getsockname: - F_getsockname = (int (*)(int, struct sockaddr *, ksocklen_t *)) - _socksLib->symbol(it.data().latin1()); - break; - case S_getpeername: - F_getpeername = (int (*)(int, struct sockaddr *, ksocklen_t *)) - _socksLib->symbol(it.data().latin1()); - break; - case S_accept: - F_accept = (int (*)(int, struct sockaddr *, ksocklen_t *)) - _socksLib->symbol(it.data().latin1()); - break; - case S_select: - F_select = (int (*)(int, fd_set *, fd_set *, fd_set *, struct timeval *)) - _socksLib->symbol(it.data().latin1()); - break; - case S_listen: - F_listen = (int (*)(int, int)) - _socksLib->symbol(it.data().latin1()); - break; - case S_bind: - F_bind = (int (*)(int, const struct sockaddr *, ksocklen_t)) - _socksLib->symbol(it.data().latin1()); - break; - default: - kdDebug(171) << "KSocks got a symbol it doesn't know about!" << endl; - break; - } - } - - // Now we check for the critical stuff. - if (F_SOCKSinit) { - int rc = (*F_SOCKSinit)((char *)"KDE"); - if (rc != 0) - stopSocks(); - else kdDebug(171) << "SOCKS has been activated!" << endl; - } else { - stopSocks(); - } - } -} - - -KSocks::~KSocks() { - stopSocks(); - _me = 0; -} - -void KSocks::die() { - if (_me == this) { - _me = 0; - delete this; - } -} - -void KSocks::stopSocks() { - if (_hasSocks) { - // This library doesn't even provide the basics. - // It's probably broken. Let's abort. - _useSocks = false; - _hasSocks = false; - if (_socksLib) { - _socksLib->unload(); - _socksLib = 0L; - } - delete _st; - _st = 0L; - } -} - - -bool KSocks::usingSocks() { - return _useSocks; -} - - -bool KSocks::hasSocks() { - return _hasSocks; -} - - -void KSocks::disableSocks() { - _useSocks = false; -} - - -void KSocks::enableSocks() { - if (_hasSocks) - _useSocks = true; -} - -bool KSocks::hasWorkingAsyncConnect() -{ - return (_useSocks && _st) ? _st->hasWorkingAsyncConnect : true; -} - - -/* - * REIMPLEMENTED FUNCTIONS FROM LIBC - * - */ - -int KSocks::connect (int sockfd, const sockaddr *serv_addr, - ksocklen_t addrlen) { - if (_useSocks && F_connect) - return (*F_connect)(sockfd, serv_addr, addrlen); - else return ::connect(sockfd, (sockaddr*) serv_addr, (socklen_t)addrlen); -} - - -signed long int KSocks::read (int fd, void *buf, unsigned long int count) { - if (_useSocks && F_read) - return (*F_read)(fd, buf, count); - else return ::read(fd, buf, count); -} - - -signed long int KSocks::write (int fd, const void *buf, unsigned long int count) { - if (_useSocks && F_write) - return (*F_write)(fd, buf, count); - else return ::write(fd, buf, count); -} - - -int KSocks::recvfrom (int s, void *buf, unsigned long int len, int flags, - sockaddr *from, ksocklen_t *fromlen) { - if (_useSocks && F_recvfrom) { - return (*F_recvfrom)(s, buf, len, flags, from, fromlen); - } else { - socklen_t casted_len = (socklen_t) *fromlen; - int rc = ::recvfrom(s, (char*) buf, len, flags, from, &casted_len); - *fromlen = casted_len; - return rc; - } -} - - -int KSocks::sendto (int s, const void *msg, unsigned long int len, int flags, - const sockaddr *to, ksocklen_t tolen) { - if (_useSocks && F_sendto) - return (*F_sendto)(s, msg, len, flags, to, tolen); - else return ::sendto(s, (char*) msg, len, flags, to, (socklen_t)tolen); -} - - -int KSocks::recv (int s, void *buf, unsigned long int len, int flags) { - if (_useSocks && F_recv) - return (*F_recv)(s, buf, len, flags); - else return ::recv(s, (char*) buf, len, flags); -} - - -int KSocks::send (int s, const void *msg, unsigned long int len, int flags) { - if (_useSocks && F_send) - return (*F_send)(s, msg, len, flags); - else return ::send(s, (char*) msg, len, flags); -} - - -int KSocks::getsockname (int s, sockaddr *name, ksocklen_t *namelen) { - if (_useSocks && F_getsockname) { - return (*F_getsockname)(s, name, namelen); - } else { - socklen_t casted_len = *namelen; - int rc = ::getsockname(s, name, &casted_len); - *namelen = casted_len; - return rc; - } -} - - -int KSocks::getpeername (int s, sockaddr *name, ksocklen_t *namelen) { - if (_useSocks && F_getpeername) { - return (*F_getpeername)(s, name, namelen); - } else { - socklen_t casted_len = *namelen; - int rc = ::getpeername(s, name, &casted_len); - *namelen = casted_len; - return rc; - } -} - - -int KSocks::accept (int s, sockaddr *addr, ksocklen_t *addrlen) { - if (_useSocks && F_accept) { - return (*F_accept)(s, addr, addrlen); - } else { - socklen_t casted_len = *addrlen; - int rc = ::accept(s, addr, &casted_len); - *addrlen = casted_len; - return rc; - } -} - - -int KSocks::select (int n, fd_set *readfds, fd_set *writefds, - fd_set *exceptfds, struct timeval *timeout) { - if (_useSocks && F_select) - return (*F_select)(n, readfds, writefds, exceptfds, timeout); - else return ::select(n, readfds, writefds, exceptfds, timeout); -} - - -int KSocks::listen (int s, int backlog) { - if (_useSocks && F_listen) - return (*F_listen)(s, backlog); - else return ::listen(s, backlog); -} - - -int KSocks::bind (int sockfd, const sockaddr *my_addr, ksocklen_t addrlen) { - if (_useSocks && F_bind) - return (*F_bind)(sockfd, my_addr, addrlen); - else return ::bind(sockfd, my_addr, (socklen_t)addrlen); -} - -int KSocks::bind (int sockfd, sockaddr *my_addr, ksocklen_t addrlen) { - if (_useSocks && F_bind) - return (*F_bind)(sockfd, my_addr, addrlen); - else return ::bind(sockfd, my_addr, (socklen_t)addrlen); -} - - - |