00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <config.h>
00020 #define I_KNOW_KSOCKS_ISNT_PUBLIC
00021 #include "k3socks.h"
00022 #undef I_KNOW_KSOCKS_ISNT_PUBLIC
00023
00024 #ifdef HAVE_SYS_TIME_H
00025 #include <sys/time.h>
00026 #endif
00027
00028 #include <QtCore/QFile>
00029 #include <QtCore/QCharRef>
00030 #include <QtCore/QMap>
00031
00032 #include <klocale.h>
00033 #include <kdebug.h>
00034 #include "klibloader.h"
00035 #include <kconfig.h>
00036
00037 #include <sys/types.h>
00038 #include <sys/socket.h>
00039
00040 #include <unistd.h>
00041
00042 #include <kconfiggroup.h>
00043
00044
00045 enum SymbolKeys {
00046 S_SOCKSinit = 0,
00047 S_connect = 1,
00048 S_read = 2,
00049 S_write = 3,
00050 S_recvfrom = 4,
00051 S_sendto = 5,
00052 S_recv = 6,
00053 S_send = 7,
00054 S_getsockname = 8,
00055 S_getpeername = 9,
00056 S_accept = 10,
00057 S_select = 11,
00058 S_listen = 12,
00059 S_bind = 13
00060 };
00061
00062
00063 extern "C" {
00064
00065 static int (*F_SOCKSinit) (char *) = 0L;
00066 static int (*F_connect) (int, const struct sockaddr *, kde_socklen_t) = 0L;
00067 static signed long int (*F_read) (int, void *, unsigned long int) = 0L;
00068 static signed long int (*F_write) (int, const void *, unsigned long int) = 0L;
00069 static int (*F_recvfrom) (int, void *, unsigned long int, int, struct sockaddr *,
00070 kde_socklen_t *) = 0L;
00071 static int (*F_sendto) (int, const void *, unsigned long int, int,
00072 const struct sockaddr *, kde_socklen_t) = 0L;
00073 static int (*F_recv) (int, void *, unsigned long int, int) = 0L;
00074 static int (*F_send) (int, const void *, unsigned long int, int) = 0L;
00075 static int (*F_getsockname) (int, struct sockaddr *, kde_socklen_t *) = 0L;
00076 static int (*F_getpeername) (int, struct sockaddr *, kde_socklen_t *) = 0L;
00077 static int (*F_accept) (int, struct sockaddr *, kde_socklen_t *) = 0L;
00078 static int (*F_select) (int, fd_set *, fd_set *, fd_set *,
00079 struct timeval *) = 0L;
00080 static int (*F_listen) (int, int) = 0L;
00081 static int (*F_bind) (int, const struct sockaddr *, kde_socklen_t) = 0L;
00082 }
00083
00084
00085 class KSocksTable {
00086 public:
00087 KSocksTable();
00088 virtual ~KSocksTable();
00089
00090
00091 QMap<SymbolKeys,QString> symbols;
00092
00093 QString myname;
00094 bool hasWorkingAsyncConnect;
00095 };
00096
00097
00098 KSocksTable::KSocksTable() : myname("Unknown"), hasWorkingAsyncConnect(true) {
00099 }
00100
00101 KSocksTable::~KSocksTable() {
00102 }
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00123
00124
00125
00126
00127
00128
00129 class KNECSocksTable : public KSocksTable {
00130 public:
00131 KNECSocksTable();
00132 virtual ~KNECSocksTable();
00133 };
00134
00135
00136 KNECSocksTable::KNECSocksTable() : KSocksTable() {
00137 myname = i18n("NEC SOCKS client");
00138 symbols.insert(S_SOCKSinit, "SOCKSinit");
00139 symbols.insert(S_connect, "connect");
00140 symbols.insert(S_read, "read");
00141 symbols.insert(S_write, "write");
00142 symbols.insert(S_recvfrom, "recvfrom");
00143 symbols.insert(S_sendto, "sendto");
00144 symbols.insert(S_recv, "recv");
00145 symbols.insert(S_send, "send");
00146 symbols.insert(S_getsockname, "getsockname");
00147 symbols.insert(S_getpeername, "getpeername");
00148 symbols.insert(S_accept, "accept");
00149 symbols.insert(S_select, "select");
00150 symbols.insert(S_listen, "listen");
00151 symbols.insert(S_bind, "bind");
00152 }
00153
00154 KNECSocksTable::~KNECSocksTable() {
00155 }
00156
00157
00158
00159
00160
00161
00162
00163
00164 class KDanteSocksTable : public KSocksTable {
00165 public:
00166 KDanteSocksTable();
00167 virtual ~KDanteSocksTable();
00168 };
00169
00170 KDanteSocksTable::KDanteSocksTable() : KSocksTable() {
00171 hasWorkingAsyncConnect = false;
00172 myname = i18n("Dante SOCKS client");
00173 symbols.insert(S_SOCKSinit, "SOCKSinit");
00174 symbols.insert(S_connect, "Rconnect");
00175 symbols.insert(S_read, "Rread");
00176 symbols.insert(S_write, "Rwrite");
00177 symbols.insert(S_recvfrom, "Rrecvfrom");
00178 symbols.insert(S_sendto, "Rsendto");
00179 symbols.insert(S_recv, "Rrecv");
00180 symbols.insert(S_send, "Rsend");
00181 symbols.insert(S_getsockname, "Rgetsockname");
00182 symbols.insert(S_getpeername, "Rgetpeername");
00183 symbols.insert(S_accept, "Raccept");
00184 symbols.insert(S_select, "Rselect");
00185 symbols.insert(S_listen, "Rlisten");
00186 symbols.insert(S_bind, "Rbind");
00187 }
00188
00189
00190 KDanteSocksTable::~KDanteSocksTable() {
00191 }
00192
00193
00194
00198
00199 class KSocks::KSocksPrivate
00200 {
00201 public:
00202 KSocksPrivate() :
00203 _useSocks(false),
00204 _hasSocks(false),
00205 _socksLib(0L),
00206 _st(0L)
00207 {}
00208 QStringList _libNames;
00209 QStringList _libPaths;
00210 bool _useSocks;
00211 bool _hasSocks;
00212 KLibrary* _socksLib;
00213 KSocksTable *_st;
00214 };
00215
00216 KSocks *KSocks::_me = 0;
00217 #ifdef __CYGWIN__
00218 bool KSocks::_disabled = true;
00219 #else
00220 bool KSocks::_disabled = false;
00221 #endif
00222
00223 void KSocks::disable()
00224 {
00225 if (!_me)
00226 _disabled = true;
00227 }
00228
00229 KSocks *KSocks::self() {
00230
00231 if (!_me) {
00232 if (KGlobal::hasMainComponent()) {
00233 KConfigGroup cfg(KGlobal::config(), "Socks");
00234 _me = new KSocks(&cfg);
00235 } else {
00236 _disabled = true;
00237 _me = new KSocks(0);
00238 }
00239 }
00240 return _me;
00241 }
00242
00243 void KSocks::setConfig(const KConfigGroup *config)
00244 {
00245
00246
00247 if (_me && _disabled) {
00248 delete _me;
00249 _me = 0;
00250 _disabled = false;
00251 }
00252 if (!_me)
00253 _me = new KSocks(config);
00254 }
00255
00256 bool KSocks::activated() { return (_me != 0L); }
00257
00258
00259 KDECORE_EXPORT bool kdeHasSocks() { return KSocks::self()->hasSocks(); }
00260
00261 KSocks::KSocks(const KConfigGroup *config)
00262 : d(new KSocksPrivate())
00263 {
00264 if (!config)
00265 return;
00266
00267 if (!config->readEntry("SOCKS_enable", false)) {
00268 _disabled = true;
00269 }
00270
00271 if (_disabled)
00272 return;
00273
00274 d->_libPaths << ""
00275 << "/usr/lib" KDELIBSUFF "/"
00276 << "/usr/lib/"
00277 << "/usr/local/lib" KDELIBSUFF "/"
00278 << "/usr/local/lib/"
00279 << "/usr/local/socks5/lib" KDELIBSUFF "/"
00280 << "/usr/local/socks5/lib/"
00281 << "/opt/socks5/lib" KDELIBSUFF "/"
00282 << "/opt/socks5/lib/";
00283 d->_libNames << "libsocks.so"
00284 << "libdsocksd.so.0"
00285
00286 << "libsocks5.so"
00287 << "libsocks5_sh.so";
00288
00289
00290 QStringList newlibs = config->readEntry("SOCKS_lib_path", QStringList());
00291
00292 for (QStringList::Iterator it = newlibs.begin();
00293 it != newlibs.end();
00294 ++it) {
00295 QString thisone = *it;
00296 if (thisone[thisone.length()-1] != '/') thisone += '/';
00297 d->_libPaths << thisone;
00298 kDebug(171) << "KSocks added a new library path: " << thisone;
00299 }
00300
00301
00302 KLibLoader *ll = KLibLoader::self();
00303
00304
00305 int _meth = config->readEntry("SOCKS_method", 1);
00306
00307
00308
00309
00310
00311 if (_meth == 4) {
00312 d->_socksLib = ll->library(config->readPathEntry("SOCKS_lib", QString()));
00313 if (d->_socksLib && d->_socksLib->resolveFunction("Rconnect")) {
00314 d->_st = new KDanteSocksTable;
00315 d->_useSocks = true;
00316 d->_hasSocks = true;
00317 } else if (d->_socksLib && d->_socksLib->resolveFunction("connect")) {
00318 d->_st = new KNECSocksTable;
00319 d->_useSocks = true;
00320 d->_hasSocks = true;
00321 } else if (d->_socksLib) {
00322 d->_socksLib->unload();
00323 d->_socksLib = 0L;
00324 }
00325 } else
00326 for (QStringList::Iterator pit = d->_libPaths.begin();
00327 !d->_hasSocks && pit != d->_libPaths.end();
00328 ++pit)
00329 for (QStringList::Iterator it = d->_libNames.begin();
00330 it != d->_libNames.end();
00331 ++it) {
00332 d->_socksLib = ll->library(*pit + *it);
00333 if (d->_socksLib) {
00334 if ((_meth == 1 || _meth == 2) &&
00335 d-> _socksLib->resolveFunction("S5LogShowThreadIDS") != 0L) {
00336 kDebug(171) << "Found NEC SOCKS";
00337 d->_st = new KNECSocksTable;
00338 d->_useSocks = true;
00339 d->_hasSocks = true;
00340 break;
00341 } else if ((_meth == 1 || _meth == 3) &&
00342 d->_socksLib->resolveFunction("sockaddr2ruleaddress") != 0L) {
00343 kDebug(171) << "Found Dante SOCKS";
00344 d->_st = new KDanteSocksTable;
00345 d->_useSocks = true;
00346 d->_hasSocks = true;
00347 break;
00348 } else {
00349 d->_socksLib->unload();
00350 d->_socksLib = 0L;
00351 }
00352 }
00353 }
00354
00355
00356 if (d->_st) {
00357 for (QMap<SymbolKeys,QString>::Iterator it = d->_st->symbols.begin();
00358 it != d->_st->symbols.end();
00359 ++it) {
00360 switch(it.key()) {
00361 case S_SOCKSinit:
00362 F_SOCKSinit = (int (*)(char *))
00363 d->_socksLib->resolveFunction(it.value().toLatin1());
00364 break;
00365 case S_connect:
00366 F_connect = (int (*)(int, const struct sockaddr *, kde_socklen_t))
00367 d->_socksLib->resolveFunction(it.value().toLatin1());
00368 break;
00369 case S_read:
00370 F_read = (signed long int (*)(int, void *, unsigned long int))
00371 d->_socksLib->resolveFunction(it.value().toLatin1());
00372 break;
00373 case S_write:
00374 F_write = (signed long int (*)(int, const void *, unsigned long int))
00375 d->_socksLib->resolveFunction(it.value().toLatin1());
00376 break;
00377 case S_recvfrom:
00378 F_recvfrom = (int (*)(int, void *, unsigned long int, int,
00379 struct sockaddr *, kde_socklen_t *))
00380 d->_socksLib->resolveFunction(it.value().toLatin1());
00381 break;
00382 case S_sendto:
00383 F_sendto = (int (*)(int, const void *, unsigned long int, int,
00384 const struct sockaddr *, kde_socklen_t))
00385 d->_socksLib->resolveFunction(it.value().toLatin1());
00386 break;
00387 case S_recv:
00388 F_recv = (int (*)(int, void *, unsigned long int, int))
00389 d->_socksLib->resolveFunction(it.value().toLatin1());
00390 break;
00391 case S_send:
00392 F_send = (int (*)(int, const void *, unsigned long int, int))
00393 d->_socksLib->resolveFunction(it.value().toLatin1());
00394 break;
00395 case S_getsockname:
00396 F_getsockname = (int (*)(int, struct sockaddr *, kde_socklen_t *))
00397 d->_socksLib->resolveFunction(it.value().toLatin1());
00398 break;
00399 case S_getpeername:
00400 F_getpeername = (int (*)(int, struct sockaddr *, kde_socklen_t *))
00401 d->_socksLib->resolveFunction(it.value().toLatin1());
00402 break;
00403 case S_accept:
00404 F_accept = (int (*)(int, struct sockaddr *, kde_socklen_t *))
00405 d->_socksLib->resolveFunction(it.value().toLatin1());
00406 break;
00407 case S_select:
00408 F_select = (int (*)(int, fd_set *, fd_set *, fd_set *, struct timeval *))
00409 d->_socksLib->resolveFunction(it.value().toLatin1());
00410 break;
00411 case S_listen:
00412 F_listen = (int (*)(int, int))
00413 d->_socksLib->resolveFunction(it.value().toLatin1());
00414 break;
00415 case S_bind:
00416 F_bind = (int (*)(int, const struct sockaddr *, kde_socklen_t))
00417 d->_socksLib->resolveFunction(it.value().toLatin1());
00418 break;
00419 default:
00420 kDebug(171) << "KSocks got a symbol it doesn't know about!";
00421 break;
00422 }
00423 }
00424
00425
00426 if (F_SOCKSinit) {
00427 int rc = (*F_SOCKSinit)((char *)"KDE");
00428 if (rc != 0)
00429 stopSocks();
00430 else kDebug(171) << "SOCKS has been activated!";
00431 } else {
00432 stopSocks();
00433 }
00434 }
00435 }
00436
00437
00438 KSocks::~KSocks() {
00439 stopSocks();
00440 _me = 0;
00441 delete d;
00442 }
00443
00444 void KSocks::die() {
00445 if (_me == this) {
00446 _me = 0;
00447 delete this;
00448 }
00449 }
00450
00451 void KSocks::stopSocks() {
00452 if (d->_hasSocks) {
00453
00454
00455 d->_useSocks = false;
00456 d->_hasSocks = false;
00457 if (d->_socksLib) {
00458 d->_socksLib->unload();
00459 d->_socksLib = 0L;
00460 }
00461 delete d->_st;
00462 d->_st = 0L;
00463 }
00464 }
00465
00466
00467 bool KSocks::usingSocks() {
00468 return d->_useSocks;
00469 }
00470
00471
00472 bool KSocks::hasSocks() {
00473 return d->_hasSocks;
00474 }
00475
00476
00477 void KSocks::disableSocks() {
00478 d->_useSocks = false;
00479 }
00480
00481
00482 void KSocks::enableSocks() {
00483 if (d->_hasSocks)
00484 d->_useSocks = true;
00485 }
00486
00487 bool KSocks::hasWorkingAsyncConnect()
00488 {
00489 return (d->_useSocks && d->_st) ? d->_st->hasWorkingAsyncConnect : true;
00490 }
00491
00492
00493
00494
00495
00496
00497
00498 int KSocks::connect (int sockfd, const sockaddr *serv_addr,
00499 kde_socklen_t addrlen) {
00500 if (d->_useSocks && F_connect)
00501 return (*F_connect)(sockfd, serv_addr, addrlen);
00502 else return ::connect(sockfd, (sockaddr*) serv_addr, (socklen_t)addrlen);
00503 }
00504
00505
00506 signed long int KSocks::read (int fd, void *buf, unsigned long int count) {
00507 if (d->_useSocks && F_read)
00508 return (*F_read)(fd, buf, count);
00509 else return ::read(fd, buf, count);
00510 }
00511
00512
00513 signed long int KSocks::write (int fd, const void *buf, unsigned long int count) {
00514 if (d->_useSocks && F_write)
00515 return (*F_write)(fd, buf, count);
00516 else return ::write(fd, buf, count);
00517 }
00518
00519
00520 int KSocks::recvfrom (int s, void *buf, unsigned long int len, int flags,
00521 sockaddr *from, kde_socklen_t *fromlen) {
00522 if (d->_useSocks && F_recvfrom) {
00523 return (*F_recvfrom)(s, buf, len, flags, from, fromlen);
00524 } else {
00525 socklen_t casted_len = (socklen_t) *fromlen;
00526 int rc = ::recvfrom(s, (char*) buf, len, flags, from, &casted_len);
00527 *fromlen = casted_len;
00528 return rc;
00529 }
00530 }
00531
00532
00533 int KSocks::sendto (int s, const void *msg, unsigned long int len, int flags,
00534 const sockaddr *to, kde_socklen_t tolen) {
00535 if (d->_useSocks && F_sendto)
00536 return (*F_sendto)(s, msg, len, flags, to, tolen);
00537 else return ::sendto(s, (char*) msg, len, flags, to, (socklen_t)tolen);
00538 }
00539
00540
00541 int KSocks::recv (int s, void *buf, unsigned long int len, int flags) {
00542 if (d->_useSocks && F_recv)
00543 return (*F_recv)(s, buf, len, flags);
00544 else return ::recv(s, (char*) buf, len, flags);
00545 }
00546
00547
00548 int KSocks::send (int s, const void *msg, unsigned long int len, int flags) {
00549 if (d->_useSocks && F_send)
00550 return (*F_send)(s, msg, len, flags);
00551 else return ::send(s, (char*) msg, len, flags);
00552 }
00553
00554
00555 int KSocks::getsockname (int s, sockaddr *name, kde_socklen_t *namelen) {
00556 if (d->_useSocks && F_getsockname) {
00557 return (*F_getsockname)(s, name, namelen);
00558 } else {
00559 socklen_t casted_len = *namelen;
00560 int rc = ::getsockname(s, name, &casted_len);
00561 *namelen = casted_len;
00562 return rc;
00563 }
00564 }
00565
00566
00567 int KSocks::getpeername (int s, sockaddr *name, kde_socklen_t *namelen) {
00568 if (d->_useSocks && F_getpeername) {
00569 return (*F_getpeername)(s, name, namelen);
00570 } else {
00571 socklen_t casted_len = *namelen;
00572 int rc = ::getpeername(s, name, &casted_len);
00573 *namelen = casted_len;
00574 return rc;
00575 }
00576 }
00577
00578
00579 int KSocks::accept (int s, sockaddr *addr, kde_socklen_t *addrlen) {
00580 if (d->_useSocks && F_accept) {
00581 return (*F_accept)(s, addr, addrlen);
00582 } else {
00583 socklen_t casted_len = *addrlen;
00584 int rc = ::accept(s, addr, &casted_len);
00585 *addrlen = casted_len;
00586 return rc;
00587 }
00588 }
00589
00590
00591 int KSocks::select (int n, fd_set *readfds, fd_set *writefds,
00592 fd_set *exceptfds, struct timeval *timeout) {
00593 if (d->_useSocks && F_select)
00594 return (*F_select)(n, readfds, writefds, exceptfds, timeout);
00595 else return ::select(n, readfds, writefds, exceptfds, timeout);
00596 }
00597
00598
00599 int KSocks::listen (int s, int backlog) {
00600 if (d->_useSocks && F_listen)
00601 return (*F_listen)(s, backlog);
00602 else return ::listen(s, backlog);
00603 }
00604
00605
00606 int KSocks::bind (int sockfd, const sockaddr *my_addr, kde_socklen_t addrlen) {
00607 if (d->_useSocks && F_bind)
00608 return (*F_bind)(sockfd, my_addr, addrlen);
00609 else return ::bind(sockfd, my_addr, (socklen_t)addrlen);
00610 }
00611
00612 int KSocks::bind (int sockfd, sockaddr *my_addr, kde_socklen_t addrlen) {
00613 if (d->_useSocks && F_bind)
00614 return (*F_bind)(sockfd, my_addr, addrlen);
00615 else return ::bind(sockfd, my_addr, (socklen_t)addrlen);
00616 }
00617
00618
00619