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