|
|
|
/****************************************************************************
|
|
|
|
** $Id: torclient.cpp,v 1.138 2009/10/13 20:19:51 hoganrobert Exp $
|
|
|
|
* Copyright (C) 2006 - 2008 Robert Hogan *
|
|
|
|
* robert@roberthogan.net *
|
|
|
|
* *
|
|
|
|
* This program is free software; you can redistribute it and/or modify *
|
|
|
|
* it under the terms of the GNU General Public License as published by *
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or *
|
|
|
|
* (at your option) any later version. *
|
|
|
|
* *
|
|
|
|
* This program 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 General Public License for more details. *
|
|
|
|
* *
|
|
|
|
* You should have received a copy of the GNU General Public License *
|
|
|
|
* along with this program; if not, write to the *
|
|
|
|
* Free Software Foundation, Inc., *
|
|
|
|
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
|
|
|
***************************************************************************/
|
|
|
|
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
#include "config.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <tqdir.h>
|
|
|
|
#include <tqsocket.h>
|
|
|
|
#include <tqtextstream.h>
|
|
|
|
#include <tqstringlist.h>
|
|
|
|
#include <tqregexp.h>
|
|
|
|
#include <tqtimer.h>
|
|
|
|
|
|
|
|
#include <tdelocale.h>
|
|
|
|
#include <assert.h>
|
|
|
|
#include <ntqfile.h>
|
|
|
|
#include <sys/socket.h>
|
|
|
|
#include <netdb.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <netinet/in.h>
|
|
|
|
#include <arpa/inet.h>
|
|
|
|
#include <kstandarddirs.h>
|
|
|
|
|
|
|
|
#ifdef EXTERNAL_GEOIP
|
|
|
|
# include <GeoIP.h>
|
|
|
|
#else
|
|
|
|
# include "GeoIP-1.4.0/libGeoIP/GeoIP.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "torclient.h"
|
|
|
|
#include "tork.h"
|
|
|
|
#include "torkconfig.h"
|
|
|
|
#include "dndlistview.h"
|
|
|
|
#include "functions.h"
|
|
|
|
#include "crypto.h"
|
|
|
|
|
|
|
|
/* Linux-specific includes */
|
|
|
|
#include <dirent.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
|
|
|
|
using namespace tk;
|
|
|
|
|
|
|
|
|
|
|
|
TorClient::TorClient( const TQString &host, TQ_UINT16 port )
|
|
|
|
{
|
|
|
|
// create the socket and connect various of its signals
|
|
|
|
socket = new TQSocket( this );
|
|
|
|
connect( socket, SIGNAL(connected()),
|
|
|
|
SLOT(socketConnected()) );
|
|
|
|
connect( socket, SIGNAL(connectionClosed()),
|
|
|
|
SLOT(socketConnectionClosed()) );
|
|
|
|
connect( socket, SIGNAL(readyRead()),
|
|
|
|
SLOT(socketReadyRead()) );
|
|
|
|
connect( socket, SIGNAL(error(int)),
|
|
|
|
SLOT(socketError(int)) );
|
|
|
|
|
|
|
|
// connect to the server
|
|
|
|
//infoText->append( tr("Trying to connect to the server\n") );
|
|
|
|
socket->connectToHost( host, port );
|
|
|
|
m_expectingCircuitInfo= false;
|
|
|
|
m_expectingStreamInfo= false;
|
|
|
|
m_expectingOrconnInfo= false;
|
|
|
|
m_expectingGuardsInfo= false;
|
|
|
|
m_expectingDirStatus= false;
|
|
|
|
m_expectingServerInfo= false;
|
|
|
|
m_controllerWorking= false;
|
|
|
|
m_firstloadcomplete = false;
|
|
|
|
m_resolvingServerAddress = false;
|
|
|
|
|
|
|
|
clearServers();
|
|
|
|
|
|
|
|
serverReport.append("<font color='#990000'>Status Not Known</font>");
|
|
|
|
clientReport.append("<font color='#990000'>Status Not Known</font>");
|
|
|
|
serverStatus["DANGEROUS_VERSION"] = "<font color='#990000'>Server Requires Upgrade</font>";
|
|
|
|
serverStatus["TOO_MANY_CONNECTIONS"] = "<font color='#990000'>Recently Exceeded Local Connection Limit. Check Local System</font>";
|
|
|
|
serverStatus["CLOCK_SKEW"] = "<font color='#990000'>Your Local Clock Is Skewed. Check Local System.</font>";
|
|
|
|
serverStatus["BAD_LIBEVENT"] = "<font color='#990000'>Libevent Installation Requires Upgrade</font>";
|
|
|
|
serverStatus["DIR_ALL_UNREACHABLE"] = "<font color='#990000'>Tor Network Unreachable.</font>";
|
|
|
|
// serverStatus["NAMESERVER_ALL_DOWN"] = "Your DNS Servers are down.";
|
|
|
|
serverStatus["DNS_HIJACKED"] = "<font color='#990000'>Your Provider is Hijacking DNS Requests.</font>";
|
|
|
|
serverStatus["DNS_USELESS"] = "<font color='#990000'>Your Provider is Hijacking DNS Requests.</font>";
|
|
|
|
serverStatus["EXTERNAL_ADDRESS"] = "Using Address ADDRESS";
|
|
|
|
|
|
|
|
serverStatus["REACHABILITY_SUCCEEDED"] = "Reachable By Tor Network";
|
|
|
|
serverStatus["REACHABILITY_FAILED"] = "<font color='#990000'>Reachability Tests Failed. Trying again..</font>";
|
|
|
|
serverStatus["BAD_SERVER_DESCRIPTOR"] = "<font color='#990000'>Server Not Accepted By Tor Network Yet.</font>";
|
|
|
|
serverStatus["GOOD_SERVER_DESCRIPTOR"] = "Accepted By Tor Network";
|
|
|
|
|
|
|
|
serverStatusIcon["REACHABILITY_SUCCEEDED"] = "tork_green";
|
|
|
|
serverStatusIcon["REACHABILITY_FAILED"] = "tork_orange";
|
|
|
|
serverStatusIcon["BAD_SERVER_DESCRIPTOR"] = "tork_little";
|
|
|
|
serverStatusIcon["GOOD_SERVER_DESCRIPTOR"] = "tork_green";
|
|
|
|
serverStatusIcon["DIR_ALL_UNREACHABLE"] = "tork_red";
|
|
|
|
|
|
|
|
clientStatus["NOT_ENOUGH_DIR_INFO"] = "<font color='#990000'>Not Enough Info To Try Network Yet</font>";
|
|
|
|
clientStatus["ENOUGH_DIR_INFO"] = "Enough Info To Try Network";
|
|
|
|
clientStatus["CIRCUIT_ESTABLISHED"] = "Connected to Network.";
|
|
|
|
clientStatus["CIRCUIT_NOT_ESTABLISHED"] = "<font color='#990000'>Still Trying Network</font>";
|
|
|
|
|
|
|
|
clientStatusIcon[clientStatus["NOT_ENOUGH_DIR_INFO"]] = "tork_red";
|
|
|
|
clientStatusIcon[clientStatus["ENOUGH_DIR_INFO"]] = "tork_little";
|
|
|
|
clientStatusIcon[clientStatus["CIRCUIT_ESTABLISHED"]] = "tork_green";
|
|
|
|
clientStatusIcon[clientStatus["CIRCUIT_NOT_ESTABLISHED"]] = "tork_orange";
|
|
|
|
|
|
|
|
portMessage["23"] = " Port 23 is used by telnet, which transmits usernames "
|
|
|
|
"and passwords unencrypted.";
|
|
|
|
portMessage["110"] = " Port 110 is used to download email, so your login "
|
|
|
|
"details can be transmitted unencrypted.";
|
|
|
|
portMessage["109"] = " Port 109 is used to download email, so your login "
|
|
|
|
"details can be transmitted unencrypted.";
|
|
|
|
portMessage["143"] = " Port 143 is used to download email, so your login "
|
|
|
|
"details can be transmitted unencrypted.";
|
|
|
|
|
|
|
|
|
|
|
|
statusMessage["DANGEROUS_PORT"] = "QUESTIONMESSAGETraffic on Port PORT "
|
|
|
|
"has been rejected by Tor.";
|
|
|
|
statusMessage["DANGEROUS_VERSION"] = "QUESTIONMESSAGEYou are using Tor CURRENT."
|
|
|
|
" This version is REASON. "
|
|
|
|
"You should use Tor RECOMMENDED instead";
|
|
|
|
statusMessage["TOO_MANY_CONNECTIONS"] = "MESSAGETor has reached its native"
|
|
|
|
" limit on file descriptors: CURRENT. ";
|
|
|
|
statusMessage["BUG"] = "WARNINGMESSAGETor encountered an unexpected error: REASON. ";
|
|
|
|
statusMessage["CLOCK_SKEW"] = "WARNINGMESSAGEYour local clock is skewed by SKEW seconds. ";
|
|
|
|
statusMessage["BAD_LIBEVENT"] = "WARNINGMESSAGEYour version of libevent, VERSION, is BADNESS. ";
|
|
|
|
statusMessage["DIR_ALL_UNREACHABLE"] = "WARNINGMESSAGEAll known directory servers are unreachable. ";
|
|
|
|
statusMessage["ENOUGH_DIR_INFO"] = "WARNINGMESSAGETor has gathered enough info to start working. ";
|
|
|
|
statusMessage["NOT_ENOUGH_DIR_INFO"] = "WARNINGMESSAGETor does not have enough info to work. ";
|
|
|
|
statusMessage["CIRCUIT_ESTABLISHED"] = "WARNINGMESSAGETor has gathered enough info to start working. ";
|
|
|
|
statusMessage["CIRCUIT_NOT_ESTABLISHED"] = "WARNINGMESSAGETor does not have enough info to work. ";
|
|
|
|
statusMessage["SOCKS_BAD_HOSTNAME"] = "WARNINGMESSAGESome application gave us"
|
|
|
|
" a funny-looking hostname."
|
|
|
|
"Perhaps it is broken?";
|
|
|
|
statusMessage["NAMESERVER_ALL_DOWN"] = "WARNINGMESSAGEAll your configured nameservers appear to be down.";
|
|
|
|
statusMessage["DNS_HIJACKED"] = "WARNINGMESSAGEYour DNS requests are being hijacked by your provider.";
|
|
|
|
statusMessage["DNS_USELESS"] = "WARNINGMESSAGEYour DNS requests are being hijacked by your provider.";
|
|
|
|
statusMessage["BAD_SERVER_DESCRIPTOR"] = "WARNINGMESSAGEYour descriptor was rejected by DIRAUTH "
|
|
|
|
"because of REASON.";
|
|
|
|
|
|
|
|
m_statustip = i18n("<b>Name:</b> $SERVERNAME<br>"
|
|
|
|
"<b>IP:</b> $IP ($HOSTNAME) <b>Port:</b> $PORT<br>"
|
|
|
|
"<b>Country:</b> $COUNTRY <br>"
|
|
|
|
"<b>Version:</b> $VERSION <b>OS:</b> $OS<br>"
|
|
|
|
"<b>Published:</b> $PUBLISHED <b>Up Time:</b> $UPTIME minutes<br>"
|
|
|
|
"<center><b>Avg BW up to $INTERVALTIME</b></center>"
|
|
|
|
" "
|
|
|
|
" "
|
|
|
|
" <b>24 hrs</b>"
|
|
|
|
" " // 1 space
|
|
|
|
" " // 1 space
|
|
|
|
" " // 1 space
|
|
|
|
" " // 1 space
|
|
|
|
" <b>12 hrs</b>"
|
|
|
|
" " // 1 space
|
|
|
|
" " // 1 space
|
|
|
|
" " // 1 space
|
|
|
|
" " // 1 space
|
|
|
|
" <b>6 hrs</b>"
|
|
|
|
" " // 1 space
|
|
|
|
" " // 1 space
|
|
|
|
" " // 1 space
|
|
|
|
" " // 1 space
|
|
|
|
" " // 1 space
|
|
|
|
" <b>1 hr</b><br>"
|
|
|
|
"<b>Up</b>"
|
|
|
|
" " // 1 space
|
|
|
|
" " // 1 space
|
|
|
|
" " // 1 space
|
|
|
|
"<font color='#990000'>$BWUP</font><br>"
|
|
|
|
"<b>Down</b>"
|
|
|
|
" " // 1 space
|
|
|
|
" " // 1 space
|
|
|
|
"<font color='#1c9a1c'>$BWDN</font><br>"
|
|
|
|
);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void TorClient::configureServer( int orPort, int dirPort)
|
|
|
|
{
|
|
|
|
|
|
|
|
sendToServer(TQString("SETCONF ContactInfo=%1").arg(TorkConfig::contactInfo())) ;
|
|
|
|
|
|
|
|
sendToServer(TQString("SETCONF ClientOnly=%1").arg(TorkConfig::clientOnly())) ;
|
|
|
|
|
|
|
|
|
|
|
|
if (TorkConfig::middleMan())
|
|
|
|
( sendToServer(TQString("SETCONF ExitPolicy=%1").arg(("\"reject *:*\"")))) ;
|
|
|
|
else
|
|
|
|
( sendToServer(TQString("SETCONF ExitPolicy=\"%2\"").arg( TorkConfig::exitPolicy().join(","))));
|
|
|
|
|
|
|
|
sendToServer(TQString("SETCONF NickName=%1").arg(TorkConfig::nickName())) ;
|
|
|
|
if (!TorkConfig::clientOnly()){
|
|
|
|
//We send the orport configs together to avoid error messages from Tor
|
|
|
|
//telling us that one cannot be set without the other.
|
|
|
|
sendToServer(TQString("SETCONF ORPort=%1 "
|
|
|
|
"ORListenAddress=0.0.0.0:%2")
|
|
|
|
.arg(orPort)
|
|
|
|
.arg(TorkConfig::oRListenAddress())) ;
|
|
|
|
//We send the dirport configs together to avoid error messages from Tor
|
|
|
|
//telling us that one cannot be set without the other.
|
|
|
|
sendToServer(TQString("SETCONF DIRPort=%1 "
|
|
|
|
"DIRListenAddress=0.0.0.0:%2")
|
|
|
|
.arg(dirPort)
|
|
|
|
.arg(TorkConfig::dirListenAddress())) ;
|
|
|
|
sendToServer(TQString("SETCONF BridgeRelay=%1").arg(TorkConfig::bridgeRelay())) ;
|
|
|
|
setBandwidth(TQString("%1").arg(TorkConfig::bandwidthRate()),
|
|
|
|
TQString("%1").arg(TorkConfig::bandwidthBurst()),
|
|
|
|
TQString("%1").arg(TorkConfig::maxAdvertisedBandwidth()));
|
|
|
|
}else{
|
|
|
|
sendToServer(TQString("SETCONF ORPort= ORListenAddress=")) ;
|
|
|
|
sendToServer(TQString("SETCONF DirPort= DirListenAddress=")) ;
|
|
|
|
sendToServer(TQString("SETCONF BridgeRelay=")) ;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (TorkConfig::clientOnly())
|
|
|
|
resetClientReport();
|
|
|
|
TorkConfig::writeConfig();
|
|
|
|
}
|
|
|
|
void TorClient::clearNodes( )
|
|
|
|
{
|
|
|
|
|
|
|
|
sendToServer("SETCONF ExcludeNodes=");
|
|
|
|
sendToServer("SETCONF ExitNodes=");
|
|
|
|
sendToServer("SETCONF EntryNodes=");
|
|
|
|
TorkConfig::setCurrentExcludeNodes("");
|
|
|
|
TorkConfig::setCurrentEntryNodes("");
|
|
|
|
TorkConfig::setCurrentExitNodes("");
|
|
|
|
emit copyOldConfig();
|
|
|
|
}
|
|
|
|
|
|
|
|
void TorClient::updateExcludeNodes( )
|
|
|
|
{
|
|
|
|
////kdDebug() << "SETCONF ExcludeNodes=" + TorkConfig::currentExcludeNodes().join(",") << endl;
|
|
|
|
sendToServer("SETCONF ExcludeNodes=" + TorkConfig::currentExcludeNodes().join(","));
|
|
|
|
sendToServer("GETCONF ExcludeNodes");
|
|
|
|
sendToServer("signal newnym");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void TorClient::updateExitNodes( )
|
|
|
|
{
|
|
|
|
////kdDebug() << "SETCONF ExitNodes=" + TorkConfig::currentExitNodes().join(",") << endl;
|
|
|
|
sendToServer("SETCONF ExitNodes=" + TorkConfig::currentExitNodes().join(","));
|
|
|
|
sendToServer("GETCONF ExitNodes");
|
|
|
|
sendToServer("signal newnym");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void TorClient::strictExitNodes( bool strict )
|
|
|
|
{
|
|
|
|
if (strict)
|
|
|
|
sendToServer("SETCONF StrictExitNodes=1");
|
|
|
|
else
|
|
|
|
sendToServer("SETCONF StrictExitNodes=0");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void TorClient::safeLogging( bool safe )
|
|
|
|
{
|
|
|
|
if (safe)
|
|
|
|
sendToServer("SETCONF SafeLogging=1");
|
|
|
|
else
|
|
|
|
sendToServer("SETCONF SafeLogging=0");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void TorClient::updateEntryNodes( )
|
|
|
|
{
|
|
|
|
////kdDebug() << "SETCONF EntryNodes=" + TorkConfig::currentEntryNodes().join(",") << endl;
|
|
|
|
sendToServer("SETCONF EntryNodes=" + TorkConfig::currentEntryNodes().join(","));
|
|
|
|
sendToServer("GETCONF EntryNodes");
|
|
|
|
sendToServer("signal newnym");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void TorClient::enableDNS( bool set )
|
|
|
|
{
|
|
|
|
if (set)
|
|
|
|
sendToServer("SETCONF DNSPort=9999");
|
|
|
|
else
|
|
|
|
sendToServer("SETCONF DNSPort=");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void TorClient::enableTransPort( bool set )
|
|
|
|
{
|
|
|
|
if (set)
|
|
|
|
sendToServer("SETCONF TransPort=9040");
|
|
|
|
else
|
|
|
|
sendToServer("SETCONF TransPort=");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void TorClient::fetchServerInfo( const TQString & server)
|
|
|
|
{
|
|
|
|
|
|
|
|
TQString fp = getFPFromFPDigest(server);
|
|
|
|
fp.replace("$","");
|
|
|
|
|
|
|
|
kdDebug() << fp << endl;
|
|
|
|
// emit showServerBW(fp);
|
|
|
|
|
|
|
|
sendToServer("GETINFO dir/server/fp/" + fp);
|
|
|
|
}
|
|
|
|
|
|
|
|
void TorClient::fetchServerInfoByNick( const TQString & server)
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
TQString fp = getFPFromNickName(server);
|
|
|
|
fp.replace("$","");
|
|
|
|
|
|
|
|
sendToServer("GETINFO dir/server/fp/" + fp);
|
|
|
|
}
|
|
|
|
|
|
|
|
void TorClient::slotCheckTorNet()
|
|
|
|
{
|
|
|
|
sendToServer("GETINFO ns/all");
|
|
|
|
}
|
|
|
|
|
|
|
|
void TorClient::slotCheckGuards()
|
|
|
|
{
|
|
|
|
|
|
|
|
sendToServer("GETINFO entry-guards");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void TorClient::terminateTor()
|
|
|
|
{
|
|
|
|
|
|
|
|
sendToServer("SIGNAL SHUTDOWN");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void TorClient::createService(const TQString &dir, const TQString &port)
|
|
|
|
{
|
|
|
|
sendToServer(TQString("setconf hiddenservicedir=\"%1\" hiddenserviceport=\"%2\"").arg(dir).arg(port));
|
|
|
|
}
|
|
|
|
|
|
|
|
void TorClient::authenticate()
|
|
|
|
{
|
|
|
|
|
|
|
|
// if (TorkConfig::defaultRunningNormalOptions()){
|
|
|
|
// sendToServer("AUTHENTICATE");
|
|
|
|
// return;
|
|
|
|
// }
|
|
|
|
|
|
|
|
if (TorkConfig::cookieAuthentication()){
|
|
|
|
if (!readCookie()){
|
|
|
|
emit processQuestion("cookienotfound",
|
|
|
|
TQString("Couldn't find authentication"
|
|
|
|
" cookie in %1/.tor!").arg(getenv("HOME")));
|
|
|
|
emit fatalError();
|
|
|
|
}
|
|
|
|
}else if (!TorkConfig::hashedControlPassword().isEmpty())
|
|
|
|
sendToServer(TQString("AUTHENTICATE \"%1\"").arg(TorkConfig::hashedControlPassword()));
|
|
|
|
else{
|
|
|
|
sendToServer("AUTHENTICATE");
|
|
|
|
/* Lock the control port */
|
|
|
|
if (TorkConfig::generateRandomPassword()){
|
|
|
|
crypto_seed_rng();
|
|
|
|
sendToServer(TQString("setconf HashedControlPassword=16:%2")
|
|
|
|
.arg(hashPassword(crypto_rand_string(16).latin1())));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool TorClient::readCookie()
|
|
|
|
{
|
|
|
|
|
|
|
|
TQString hex;
|
|
|
|
char hx[2];
|
|
|
|
|
|
|
|
TQStringList cookieCandidates;
|
|
|
|
cookieCandidates << TQString("%1/.tor/control_auth_cookie").arg(getenv("HOME"));
|
|
|
|
cookieCandidates << TQString("/var/lib/tor/control_auth_cookie");
|
|
|
|
|
|
|
|
for ( TQStringList::Iterator it = cookieCandidates.begin(); it != cookieCandidates.end(); ++it ) {
|
|
|
|
TQFile inf((*it));
|
|
|
|
if ( inf.open(IO_ReadOnly) ) {
|
|
|
|
TQByteArray array = inf.readAll();
|
|
|
|
inf.close();
|
|
|
|
if (array.size() != 32)
|
|
|
|
continue;
|
|
|
|
for ( unsigned int i = 0; i < array.size(); i++ ) {
|
|
|
|
sprintf(hx,"%02x",array[i]);
|
|
|
|
hex += TQString(hx).right(2);
|
|
|
|
}
|
|
|
|
sendToServer(TQString("AUTHENTICATE %1").arg(hex));
|
|
|
|
return true;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void TorClient::readRouters()
|
|
|
|
{
|
|
|
|
|
|
|
|
TQFile inf(TQString("%1/.tor/cached-status/7EA6EAD6FD83083C538F44038BBFA077587DD755").arg(getenv("HOME")));
|
|
|
|
if ( inf.open(IO_ReadOnly) ) {
|
|
|
|
TQTextStream stream( &inf );
|
|
|
|
TQString line;
|
|
|
|
while ( !stream.atEnd() ) {
|
|
|
|
line = stream.readLine(); // line of text excluding '\n'
|
|
|
|
parseDirStatus(line);
|
|
|
|
}
|
|
|
|
inf.close();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void TorClient::newIdentity()
|
|
|
|
{
|
|
|
|
kdDebug() << "changing id" << endl;
|
|
|
|
sendToServer("signal newnym");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void TorClient::bandwidth()
|
|
|
|
{
|
|
|
|
|
|
|
|
sendToServer("usefeature verbose_names");
|
|
|
|
sendToServer("usefeature extended_events");
|
|
|
|
sendToServer("GETINFO ns/all");
|
|
|
|
sendToServer("GETINFO circuit-status");
|
|
|
|
sendToServer("GETINFO stream-status");
|
|
|
|
sendToServer("GETINFO orconn-status");
|
|
|
|
sendToServer("GETINFO version");
|
|
|
|
sendToServer("GETINFO status/enough-dir-info");
|
|
|
|
sendToServer("GETINFO status/good-server-descriptor");
|
|
|
|
sendToServer("GETINFO status/reachability-succeeded/or");
|
|
|
|
|
|
|
|
//Always enable for each session, user can disable through yes/no
|
|
|
|
//interface when warned - but only for that session.
|
|
|
|
m_portsToReject.clear();
|
|
|
|
m_portsToReject << "23" << "109" << "110" << "143";
|
|
|
|
sendToServer(TQString("SETCONF WarnPlainTextPorts=%1")
|
|
|
|
.arg(m_portsToReject.join(",")));
|
|
|
|
sendToServer(TQString("SETCONF RejectPlainTextPorts=%1")
|
|
|
|
.arg(m_portsToReject.join(",")));
|
|
|
|
sendToServer("SETEVENTS EXTENDED CIRC STREAM ORCONN NOTICE "
|
|
|
|
"WARN ERR ADDRMAP BW STREAM_BW NS STATUS_GENERAL "
|
|
|
|
"STATUS_CLIENT STATUS_SERVER GUARD");
|
|
|
|
sendToServer(TQString("SETCONF __ReloadTorrcOnSIGHUP=0"));
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void TorClient::handle250(const TQString &lin)
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
TQString line = lin;
|
|
|
|
|
|
|
|
if ((line.contains("250-circuit-status="))){
|
|
|
|
if (line != ".")
|
|
|
|
parseEvent("CIRC",line.replace("250-circuit-status=",""));
|
|
|
|
else
|
|
|
|
m_expectingCircuitInfo = false;
|
|
|
|
}else if ((line.contains("250-orconn-status="))){
|
|
|
|
if (line != ".")
|
|
|
|
parseEvent("ORCONN",line.replace("250-orconn-status=",""));
|
|
|
|
else
|
|
|
|
m_expectingOrconnInfo = false;
|
|
|
|
}else if ((line.contains("250-stream-status="))){
|
|
|
|
if (line != ".")
|
|
|
|
parseEvent("STREAM",line.replace("250-stream-status=",""));
|
|
|
|
else
|
|
|
|
m_expectingStreamInfo = false;
|
|
|
|
}else if (line.contains("250+circuit-status="))
|
|
|
|
m_expectingCircuitInfo= true;
|
|
|
|
else if (line.contains("250+orconn-status="))
|
|
|
|
m_expectingOrconnInfo= true;
|
|
|
|
else if (line.contains("250+stream-status="))
|
|
|
|
m_expectingStreamInfo= true;
|
|
|
|
else if (line.contains("250+entry-guards="))
|
|
|
|
m_expectingGuardsInfo= true;
|
|
|
|
else if (line.contains("250+dir/server/fp/"))
|
|
|
|
m_expectingServerInfo= true;
|
|
|
|
else if (line.contains("250+extra-info/digest/"))
|
|
|
|
m_expectingServerInfo= true;
|
|
|
|
else if (line.contains("250+ns/all=")){
|
|
|
|
m_expectingDirStatus= true;
|
|
|
|
emit whatImDoing("Inspecting the Tor network..");
|
|
|
|
}else if (line.contains("250-ns/all=")){
|
|
|
|
emit warnNoServerInfo();
|
|
|
|
emit shouldIApplySettings();
|
|
|
|
}else if (line.contains("250-version="))
|
|
|
|
handleTorVersion(line.section("=",1,1));
|
|
|
|
else if (line.contains("250 BandwidthRate="))
|
|
|
|
m_CurBandwidthRate = line.section("=",1,1).toInt();
|
|
|
|
else if (line.contains("250 BandwidthBurst="))
|
|
|
|
m_CurBandwidthBurst = line.section("=",1,1).toInt();
|
|
|
|
else if (line.contains("250 MaxAdvertisedBandwidth="))
|
|
|
|
m_CurMaxAdvertisedBandwidth = line.section("=",1,1).toInt();
|
|
|
|
else if (line.contains("250 ExcludeNodes="))
|
|
|
|
TorkConfig::setCurrentExcludeNodes(TQStringList::split(",",line.replace("250 ExcludeNodes=","")));
|
|
|
|
else if (line.contains("250 EntryNodes="))
|
|
|
|
TorkConfig::setCurrentEntryNodes(TQStringList::split(",",line.replace("250 EntryNodes=","")));
|
|
|
|
else if (line.contains("250 ExitNodes="))
|
|
|
|
TorkConfig::setCurrentExitNodes(TQStringList::split(",",line.replace("250 ExitNodes=","")));
|
|
|
|
else if (line.contains("250-status/circuit-established=1"))
|
|
|
|
updateClientReport("CIRCUIT_ESTABLISHED");
|
|
|
|
else if (line.contains("250-status/circuit-established=0"))
|
|
|
|
updateClientReport("CIRCUIT_NOT_ESTABLISHED");
|
|
|
|
else if (line.contains("250-status/enough-dir-info=1")){
|
|
|
|
updateClientReport("ENOUGH_DIR_INFO");
|
|
|
|
sendToServer("GETINFO status/circuit-established");
|
|
|
|
}else if (line.contains("250-status/enough-dir-info=0"))
|
|
|
|
updateClientReport("NOT_ENOUGH_DIR_INFO");
|
|
|
|
else if (line.contains("250-status/good-server-descriptor=1"))
|
|
|
|
updateServerReport("GOOD_SERVER_DESCRIPTOR", TQString());
|
|
|
|
else if (line.contains("250-status/good-server-descriptor=0"))
|
|
|
|
updateServerReport("BAD_SERVER_DESCRIPTOR", TQString());
|
|
|
|
else if (line.contains("250-status/reachability-succeeded/or=1"))
|
|
|
|
updateServerReport("REACHABILITY_SUCCEEDED", TQString());
|
|
|
|
else if (line.contains("250-status/reachability-succeeded/or=0"))
|
|
|
|
updateServerReport("REACHABILITY_FAILED", TQString());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void TorClient::socketReadyRead()
|
|
|
|
{
|
|
|
|
TQString line;
|
|
|
|
// read from the server
|
|
|
|
while ( socket->canReadLine() ) {
|
|
|
|
|
|
|
|
line = (socket->readLine()).stripWhiteSpace();
|
|
|
|
|
|
|
|
if (line.contains("250 OK")){
|
|
|
|
if (!m_controllerWorking){
|
|
|
|
bandwidth();
|
|
|
|
emit authenticated();
|
|
|
|
m_controllerWorking = true;
|
|
|
|
}
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (m_expectingDirStatus){
|
|
|
|
if (!(line == ".")){
|
|
|
|
parseDirStatus(line);
|
|
|
|
}else{
|
|
|
|
m_expectingDirStatus = false;
|
|
|
|
sendToServer("GETINFO entry-guards");
|
|
|
|
if (!m_firstloadcomplete)
|
|
|
|
emit shouldIApplySettings();
|
|
|
|
m_firstloadcomplete = true;
|
|
|
|
}
|
|
|
|
continue;
|
|
|
|
}else if ((m_expectingCircuitInfo)){
|
|
|
|
if (line != "."){
|
|
|
|
parseEvent("CIRC",line);
|
|
|
|
}else
|
|
|
|
m_expectingCircuitInfo = false;
|
|
|
|
continue;
|
|
|
|
}else if ((m_expectingOrconnInfo)){
|
|
|
|
if (line != "."){
|
|
|
|
parseEvent("ORCONN",line);
|
|
|
|
}else
|
|
|
|
m_expectingOrconnInfo = false;
|
|
|
|
continue;
|
|
|
|
}else if ((m_expectingStreamInfo)){
|
|
|
|
if (line != "."){
|
|
|
|
parseEvent("STREAM",line);
|
|
|
|
}else
|
|
|
|
m_expectingStreamInfo = false;
|
|
|
|
continue;
|
|
|
|
}else if (m_expectingServerInfo){
|
|
|
|
if (line != "."){
|
|
|
|
parseEvent("SERVER",line);
|
|
|
|
}else
|
|
|
|
m_expectingServerInfo = false;
|
|
|
|
continue;
|
|
|
|
}else if (m_expectingGuardsInfo){
|
|
|
|
if (line != "."){
|
|
|
|
parseEvent("GUARDS",line);
|
|
|
|
emit whatImDoing(i18n("Ready for use."));
|
|
|
|
}else{
|
|
|
|
m_expectingGuardsInfo = false;
|
|
|
|
}
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (line.contains("552 Unrecognized key \"ns/all\"")){
|
|
|
|
emit needAlphaVersion();
|
|
|
|
emit shouldIApplySettings();
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString code = line.left(3);
|
|
|
|
|
|
|
|
if (code == "250")
|
|
|
|
handle250(line);
|
|
|
|
else if (code == "650"){
|
|
|
|
if (line.contains("650+NS")){
|
|
|
|
m_expectingDirStatus= true;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
TQString eventType = line.section(" ",1,1);
|
|
|
|
TQString eventInfo = line.section(" ",2);
|
|
|
|
if (eventInfo.contains("circuit_testing_failed"))
|
|
|
|
emit serverError();
|
|
|
|
parseEvent(eventType,eventInfo);
|
|
|
|
}else if (code == "552"){
|
|
|
|
TQString eventInfo = line.section(" ",1);
|
|
|
|
emit displayError("Sorry!", eventInfo);
|
|
|
|
}else if (code == "514"){
|
|
|
|
TQString eventInfo = line.section(" ",1);
|
|
|
|
emit processWarning("authenticationrequired", eventInfo);
|
|
|
|
emit fatalError();
|
|
|
|
}else if (code == "515"){
|
|
|
|
TQString eventInfo = line.section(" ",1);
|
|
|
|
if (eventInfo.contains("Wrong length"))
|
|
|
|
emit processQuestion("cookierequired", eventInfo);
|
|
|
|
else{
|
|
|
|
if (TorkConfig::generateRandomPassword())
|
|
|
|
emit processQuestion("passwordlost", eventInfo);
|
|
|
|
else
|
|
|
|
emit processWarning("authenticationfailed", eventInfo);
|
|
|
|
}
|
|
|
|
//Only used by the first-run wizard
|
|
|
|
emit authenticationFailed();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void TorClient::parseEvent(const TQString &type, const TQString &info)
|
|
|
|
{
|
|
|
|
|
|
|
|
if (info.isEmpty())
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (type == "STREAM")
|
|
|
|
parseStream(info);
|
|
|
|
else if (type == "ORCONN")
|
|
|
|
parseORConn(info);
|
|
|
|
else if (type == "CIRC")
|
|
|
|
parseCircuit(info);
|
|
|
|
else if (type == "GUARDS")
|
|
|
|
parseGuards(info);
|
|
|
|
else if (type == "GUARD")
|
|
|
|
parseGuards(info.section(" ",1));
|
|
|
|
else if (type == "SERVER")
|
|
|
|
parseServer(info);
|
|
|
|
else if (type == "DIRSTATUS")
|
|
|
|
parseDirStatus(info);
|
|
|
|
else if (type == "BW")
|
|
|
|
parseBW(info);
|
|
|
|
else if (type == "STREAM_BW")
|
|
|
|
parseStreamBW(info);
|
|
|
|
else if (type.contains( "STATUS_"))
|
|
|
|
parseStatusGeneral(info);
|
|
|
|
else if (type == "ADDRMAP")
|
|
|
|
parseAddrmap(info);
|
|
|
|
/* else if (type == "STREAM_PORT")
|
|
|
|
parseStreamPort(info);*/
|
|
|
|
else if ((type == "WARN") || (type == "NOTICE") || (type == "ERR"))
|
|
|
|
parseInfo(type,info);
|
|
|
|
}
|
|
|
|
|
|
|
|
void TorClient::parseStatusGeneral(const TQString &info)
|
|
|
|
{
|
|
|
|
TQString severity = info.section(" ",0,0);
|
|
|
|
TQString action = info.section(" ",1,1);
|
|
|
|
TQString message = statusMessage[action];
|
|
|
|
|
|
|
|
if (!serverStatus[action].isEmpty())
|
|
|
|
updateServerReport(action, info);
|
|
|
|
|
|
|
|
if (!clientStatus[action].isEmpty())
|
|
|
|
updateClientReport(action);
|
|
|
|
|
|
|
|
/* kdDebug() << info << endl;
|
|
|
|
kdDebug() << info.section(" ",2) << endl;*/
|
|
|
|
populateMessageFromStatusDetail(info.section(" ",2), message);
|
|
|
|
|
|
|
|
if (message.left(14) == "WARNINGMESSAGE"){
|
|
|
|
message.replace("WARNINGMESSAGE","");
|
|
|
|
emit processWarning(action, message);
|
|
|
|
}else{
|
|
|
|
message.replace("QUESTIONMESSAGE","");
|
|
|
|
emit processQuestion(action, message);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void TorClient::populateMessageFromStatusDetail(const TQString &line, TQString &message)
|
|
|
|
{
|
|
|
|
TQRegExp rx("[\\sA-Z0-9]+[=]([\\-\\:\\.\\(\\)a-zA-Z0-9]+|\\\"[\\-\\.\\,a-zA-Z0-9\\s]+\\\")");
|
|
|
|
int pos = 0;
|
|
|
|
while ( (pos = rx.search(line, pos)) != -1 ) {
|
|
|
|
/* kdDebug() << rx.cap(0) << endl;*/
|
|
|
|
TQString keyword = rx.cap(0).section("=",0,0).stripWhiteSpace();
|
|
|
|
TQString value = rx.cap(0).section("=",1,1).stripWhiteSpace();
|
|
|
|
message.replace(keyword,value);
|
|
|
|
pos += rx.matchedLength();
|
|
|
|
if (keyword=="PORT"){
|
|
|
|
m_WarnedPorts << value;
|
|
|
|
message.append(portMessage[value]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void TorClient::updateServerReport(const TQString &message, const TQString &info)
|
|
|
|
{
|
|
|
|
// kdDebug() << serverStatusIcon[message] << endl;
|
|
|
|
// kdDebug() << message << endl;
|
|
|
|
|
|
|
|
//If we're back to being a client, ensure the server symbol is removed from the tray icon
|
|
|
|
if (TorkConfig::clientOnly()){
|
|
|
|
emit updateTrayIcon(serverStatusIcon[message].replace("server",""));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (!serverStatusIcon[message].isEmpty())
|
|
|
|
emit updateTrayIcon(serverStatusIcon[message]);
|
|
|
|
|
|
|
|
serverReport.remove("<font color='#990000'>Status Not Known</font>");
|
|
|
|
TQString msg = serverStatus[message];
|
|
|
|
|
|
|
|
if (message.contains("EXTERNAL_ADDRESS")){
|
|
|
|
for ( TQStringList::Iterator it = serverReport.begin(); it != serverReport.end(); ++it )
|
|
|
|
{
|
|
|
|
// XXX Fixme
|
|
|
|
if ((*it).contains("Using Address")){
|
|
|
|
serverReport.remove((*it));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
populateMessageFromStatusDetail(info.section(" ",2),msg);
|
|
|
|
}else if (message.contains("REACHABILITY")){
|
|
|
|
serverReport.remove(serverStatus["REACHABILITY_FAILED"]);
|
|
|
|
serverReport.remove(serverStatus["REACHABILITY_SUCCEEDED"]);
|
|
|
|
}else if (message.contains("SERVER_DESCRIPTOR")){
|
|
|
|
serverReport.remove(serverStatus["DIR_ALL_UNREACHABLE"]);
|
|
|
|
serverReport.remove(serverStatus["BAD_SERVER_DESCRIPTOR"]);
|
|
|
|
serverReport.remove(serverStatus["GOOD_SERVER_DESCRIPTOR"]);
|
|
|
|
}else // Prevent multiple reports
|
|
|
|
serverReport.remove(msg);
|
|
|
|
|
|
|
|
serverReport.append(msg);
|
|
|
|
}
|
|
|
|
|
|
|
|
void TorClient::updateClientReport(const TQString &message)
|
|
|
|
{
|
|
|
|
if (!clientStatusIcon[message].isEmpty() && (TorkConfig::clientOnly()))
|
|
|
|
emit updateTrayIcon(clientStatusIcon[clientStatus[message]]);
|
|
|
|
clientReport.clear();
|
|
|
|
clientReport.append(clientStatus[message]);
|
|
|
|
}
|
|
|
|
|
|
|
|
void TorClient::resetClientReport()
|
|
|
|
{
|
|
|
|
emit updateTrayIcon(clientStatusIcon[clientReport.first()]);
|
|
|
|
}
|
|
|
|
|
|
|
|
void TorClient::parseBW(const TQString &info)
|
|
|
|
{
|
|
|
|
|
|
|
|
TQString in = info.section(" ",0,0);
|
|
|
|
TQString out = info.section(" ",1,1);
|
|
|
|
|
|
|
|
emit bwUpdate(in, out);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void TorClient::parseStreamBW(const TQString &info)
|
|
|
|
{
|
|
|
|
|
|
|
|
TQString stream = info.section(" ",0,0);
|
|
|
|
/* Tor spec had it wrong way round! */
|
|
|
|
TQString out = info.section(" ",1,1);
|
|
|
|
TQString in = info.section(" ",2,2);
|
|
|
|
|
|
|
|
emit streamBwUpdate(stream, in, out);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void TorClient::parseStream(const TQString &info)
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
TQString streamID = info.section(" ",0,0);
|
|
|
|
TQString status = info.section(" ",1,1);
|
|
|
|
TQString circID = info.section(" ",2,2);
|
|
|
|
TQString Target = info.section(" ",3,3);
|
|
|
|
|
|
|
|
//We ignore REMAPs because we don't do anything with them
|
|
|
|
if (status == "REMAP")
|
|
|
|
return;
|
|
|
|
|
|
|
|
emit streamStatusUpdate(streamID, status, circID, Target, info);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void TorClient::parseServer(const TQString &info)
|
|
|
|
{
|
|
|
|
|
|
|
|
kdDebug() << "server info " << info << endl;
|
|
|
|
if (info.left(7) == "router "){
|
|
|
|
TQString ip = info.section(" ",2,2);
|
|
|
|
TQString cc;
|
|
|
|
|
|
|
|
GeoIP * gi = 0;
|
|
|
|
|
|
|
|
if (geoip_db)
|
|
|
|
#ifdef EXTERNAL_GEOIP
|
|
|
|
gi = GeoIP_new(GEOIP_STANDARD);
|
|
|
|
#else
|
|
|
|
gi = GeoIP_open(locate("data", "tork/geoip/GeoIP.dat").ascii(),0);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (gi){
|
|
|
|
int country_id = 0;
|
|
|
|
country_id = GeoIP_id_by_name(gi, ip.latin1());
|
|
|
|
cc = GeoIP_country_name[country_id];
|
|
|
|
GeoIP_delete(gi);
|
|
|
|
}else
|
|
|
|
cc = "a1";
|
|
|
|
|
|
|
|
m_statustiptmp = m_statustip;
|
|
|
|
m_statustipIP = ip;
|
|
|
|
|
|
|
|
m_statustiptmp.replace("$SERVERNAME",info.section(" ",1,1));
|
|
|
|
m_statustiptmp.replace("$IP",ip);
|
|
|
|
m_statustiptmp.replace("$PORT",info.section(" ",3,3));
|
|
|
|
m_statustiptmp.replace("$COUNTRY",cc);
|
|
|
|
|
|
|
|
}else if (info.left(8) == "platform"){
|
|
|
|
m_statustiptmp.replace("$VERSION",info.section(" ",1,2));
|
|
|
|
m_statustiptmp.replace("$OS",info.section(" ",4).section("{",0,0));
|
|
|
|
|
|
|
|
}else if (info.left(9) == "published"){
|
|
|
|
m_statustiptmp.replace("$PUBLISHED",info.section(" ",1));
|
|
|
|
|
|
|
|
}else if (info.left(6) == "uptime"){
|
|
|
|
//from the clever ktorrent
|
|
|
|
TDELocale* loc = TDEGlobal::locale();
|
|
|
|
TQTime t;
|
|
|
|
int nsecs = info.section(" ",1).toInt();
|
|
|
|
int ndays = (nsecs) / 86400;
|
|
|
|
t = t.addSecs(nsecs % 86400);
|
|
|
|
TQString s = loc->formatTime(t,true,true);
|
|
|
|
if (ndays > 0)
|
|
|
|
s = i18n("1 day ","%n days ",ndays) + s;
|
|
|
|
|
|
|
|
m_statustiptmp.replace("$UPTIME",s);
|
|
|
|
|
|
|
|
|
|
|
|
}else if (info.left(20).contains("write-history")){
|
|
|
|
TQStringList bwlist = TQStringList::split(",",info.section(" ",-1));
|
|
|
|
|
|
|
|
TQValueList<int> bws;
|
|
|
|
bws << 4 << 24 << 48 << bwlist.count();
|
|
|
|
|
|
|
|
TQString bwup;
|
|
|
|
TQString avgbw;
|
|
|
|
for ( TQValueList<int>::Iterator it = bws.begin(); it != bws.end(); ++it ){
|
|
|
|
avgbw = calcBW(bwlist, (*it));
|
|
|
|
for (int i = avgbw.length(); i < 14; i++)
|
|
|
|
avgbw.append(" ");
|
|
|
|
bwup.append(avgbw);
|
|
|
|
}
|
|
|
|
|
|
|
|
m_statustiptmp.replace("$BWUP",bwup);
|
|
|
|
|
|
|
|
m_statustiptmp.replace("$INTERVALTIME", info.section(" ",2,3));
|
|
|
|
|
|
|
|
}else if (info.left(20).contains("read-history")){
|
|
|
|
TQStringList bwlist = TQStringList::split(",",info.section(" ",-1));
|
|
|
|
TQValueList<int> bws;
|
|
|
|
bws << 4 << 24 << 48 << bwlist.count();
|
|
|
|
|
|
|
|
TQString bwup;
|
|
|
|
TQString avgbw;
|
|
|
|
for ( TQValueList<int>::Iterator it = bws.begin(); it != bws.end(); ++it ){
|
|
|
|
avgbw = calcBW(bwlist, (*it));
|
|
|
|
for (int i = avgbw.length(); i < 14; i++)
|
|
|
|
avgbw.append(" ");
|
|
|
|
bwup.append(avgbw);
|
|
|
|
}
|
|
|
|
m_statustiptmp.replace("$BWDN",bwup);
|
|
|
|
|
|
|
|
|
|
|
|
if (m_currentTorVersion.left(3) == "0.2"){
|
|
|
|
m_resolvingServerAddress=true;
|
|
|
|
sendToServer("RESOLVE mode=reverse " + m_statustipIP);
|
|
|
|
}else{
|
|
|
|
m_statustiptmp.replace("($HOSTNAME)","");
|
|
|
|
emit displayServer("Server Info", m_statustiptmp);
|
|
|
|
}
|
|
|
|
}else if (info.left(25).contains("opt extra-info-digest")){
|
|
|
|
if (m_currentTorVersion.left(3) == "0.2"){
|
|
|
|
sendToServer("GETINFO extra-info/digest/" + info.section(" ",2));
|
|
|
|
}else{
|
|
|
|
m_statustiptmp.replace("($HOSTNAME)","");
|
|
|
|
m_statustiptmp.replace("$BWDN","Unavailable");
|
|
|
|
m_statustiptmp.replace("$BWUP","Unavailable");
|
|
|
|
m_statustiptmp.replace("$INTERVALTIME", "Unavailable");
|
|
|
|
emit displayServer("Server Info", m_statustiptmp);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void TorClient::parseAddrmap(const TQString &info)
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
TQString type = info.section(" ",0,0);
|
|
|
|
TQString address = info.section(" ",1,1);
|
|
|
|
|
|
|
|
// If this is a request to resolve a hostname/address from the traffic
|
|
|
|
// logs
|
|
|
|
if (logResolveList.contains(type)){
|
|
|
|
emit resolvedAddress(info);
|
|
|
|
logResolveList.remove(logResolveList.find(type));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!m_resolvingServerAddress)
|
|
|
|
return;
|
|
|
|
|
|
|
|
// If this is a request to resolve a node name from the server list
|
|
|
|
if (type.startsWith("REVERSE")){
|
|
|
|
m_statustiptmp.replace("$HOSTNAME",address);
|
|
|
|
}else
|
|
|
|
m_statustiptmp.replace("$HOSTNAME","Cannot Resolve Hostname.");
|
|
|
|
|
|
|
|
emit displayServer("Server Info", m_statustiptmp);
|
|
|
|
m_resolvingServerAddress = false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void TorClient::parseGuards(const TQString &info)
|
|
|
|
{
|
|
|
|
|
|
|
|
TQString fp_identity = info.section(" ",0,0);
|
|
|
|
TQString status = info.section(" ",1,1);
|
|
|
|
TQRegExp rx("(\\$[A-Z0-9]{40})");
|
|
|
|
rx.search(fp_identity);
|
|
|
|
TQString server = getNickNameFromFP(rx.cap(0));
|
|
|
|
|
|
|
|
if (!server.isEmpty()){
|
|
|
|
emit guardStatusUpdate(server, status);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void TorClient::parseCircuit(const TQString &info)
|
|
|
|
{
|
|
|
|
|
|
|
|
if (info.contains("FAILED"))
|
|
|
|
emit displayError("Circuit Failed - "+info.section(" ",3,3).replace("REASON=",""), "Circuit: " + info.section(" ",2,2));
|
|
|
|
|
|
|
|
TQString circuitID = info.section(" ",0,0).stripWhiteSpace();
|
|
|
|
TQString status = info.section(" ",1,1).stripWhiteSpace();
|
|
|
|
TQString path = info.section(" ",2,2).stripWhiteSpace();
|
|
|
|
|
|
|
|
//Get the FP Digest (if any) of the last server in the circuit
|
|
|
|
TQString exit;
|
|
|
|
TQRegExp rx("(\\$[A-Z0-9]{40})");
|
|
|
|
int count = 0;
|
|
|
|
int pos = 0;
|
|
|
|
while ( (pos = rx.search(path, pos)) != -1 ) {
|
|
|
|
count++;
|
|
|
|
pos += rx.matchedLength();
|
|
|
|
exit = rx.cap(0);
|
|
|
|
}
|
|
|
|
if (!exit.isEmpty())
|
|
|
|
exit = getFPDigestFromFP(exit);
|
|
|
|
//Strip out the FPs from the circuit, if any
|
|
|
|
path.replace(TQRegExp("(\\$[A-Z0-9]{40})(~|=)"),"");
|
|
|
|
|
|
|
|
emit circuitStatusUpdate(circuitID, status, path, exit);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void TorClient::parseORConn(const TQString &info)
|
|
|
|
{
|
|
|
|
TQString serverID = info.section(" ",0,0);
|
|
|
|
TQString status = info.section(" ",1,1);
|
|
|
|
|
|
|
|
if (serverID.startsWith("$")){
|
|
|
|
TQString server = getNickNameFromFP(serverID);
|
|
|
|
if (!server.isEmpty())
|
|
|
|
serverID = server;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!status.contains("NEW")){
|
|
|
|
serverID.replace(TQRegExp("^[A-Z0-9$=~]{42}"),"");
|
|
|
|
emit ORStatusUpdate(serverID, status);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void TorClient::parseInfo(const TQString &type,const TQString &info)
|
|
|
|
{
|
|
|
|
|
|
|
|
TQString message = info;
|
|
|
|
message.replace(TQRegExp("^[a-zA-Z0-9_]+\\(\\):"),"");
|
|
|
|
// TQString summary = info.section(":",0,0);
|
|
|
|
// TQString data = info.section(":",1);
|
|
|
|
|
|
|
|
if (info.contains("Servers unavailable"))
|
|
|
|
emit displayServer("Server Info", "<b>Server appears to be down!</b>");
|
|
|
|
emit infoUpdate(type, message, TQString());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void TorClient::updateCandidateServers(const TQString &path)
|
|
|
|
{
|
|
|
|
|
|
|
|
TQStringList servers = TQStringList::split(",", path);
|
|
|
|
TQStringList existingServers = TorkConfig::serversHistory();
|
|
|
|
for ( TQStringList::Iterator it = servers.begin(); it != servers.end(); ++it )
|
|
|
|
{
|
|
|
|
if ((*it).isEmpty())
|
|
|
|
continue;
|
|
|
|
if (existingServers.find(*it) == existingServers.end())
|
|
|
|
existingServers.append(*it);
|
|
|
|
}
|
|
|
|
TorkConfig::setServersHistory(existingServers);
|
|
|
|
|
|
|
|
TorkConfig::writeConfig();
|
|
|
|
}
|
|
|
|
|
|
|
|
void TorClient::attemptAttach(const TQString &circid, const TQString &streamid)
|
|
|
|
{
|
|
|
|
|
|
|
|
TQStringList streams = TQStringList::split( " ", streamid);
|
|
|
|
for ( TQStringList::Iterator it = streams.begin(); it != streams.end(); ++it )
|
|
|
|
{
|
|
|
|
if ((*it).isEmpty())
|
|
|
|
continue;
|
|
|
|
sendToServer(TQString("ATTACHSTREAM %1 %2").arg(*it).arg(circid));
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void TorClient::attemptExtendCircuit(const TQString &circid, const TQString &serverlist, bool usefp)
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
TQStringList servers = TQStringList::split( " ", serverlist);
|
|
|
|
TQStringList circuitlist;
|
|
|
|
for ( TQStringList::Iterator it = servers.begin(); it != servers.end(); ++it )
|
|
|
|
{
|
|
|
|
if ((*it).isEmpty())
|
|
|
|
continue;
|
|
|
|
if (usefp)
|
|
|
|
circuitlist.append(getFPFromFPDigest((*it)));
|
|
|
|
else
|
|
|
|
circuitlist.append((*it));
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString circuit = circuitlist.join(",");
|
|
|
|
sendToServer(TQString("EXTENDCIRCUIT %1 %2").arg(circid).arg(circuit));
|
|
|
|
}
|
|
|
|
|
|
|
|
void TorClient::attemptCreateCircuit(const TQString &serverlist, bool usefp)
|
|
|
|
{
|
|
|
|
|
|
|
|
TQStringList servers = TQStringList::split( " ", serverlist);
|
|
|
|
TQStringList circuitlist;
|
|
|
|
for ( TQStringList::Iterator it = servers.begin(); it != servers.end(); ++it )
|
|
|
|
{
|
|
|
|
if ((*it).isEmpty())
|
|
|
|
continue;
|
|
|
|
if (usefp)
|
|
|
|
circuitlist.append(getFPFromFPDigest((*it)));
|
|
|
|
else
|
|
|
|
circuitlist.append((*it));
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString circuit = circuitlist.join(",");
|
|
|
|
sendToServer(TQString("EXTENDCIRCUIT 0 %1").arg(circuit));
|
|
|
|
}
|
|
|
|
|
|
|
|
void TorClient::attemptCloseStream(const TQString &streamid)
|
|
|
|
{
|
|
|
|
sendToServer(TQString("CLOSESTREAM %1 1").arg(streamid));
|
|
|
|
}
|
|
|
|
|
|
|
|
void TorClient::attemptAttachStreams( bool attachStreams)
|
|
|
|
{
|
|
|
|
sendToServer(TQString("SETCONF __LeaveStreamsUnattached=%1").arg(attachStreams));
|
|
|
|
}
|
|
|
|
|
|
|
|
void TorClient::attemptCloseCircuit(const TQString &circuitid)
|
|
|
|
{
|
|
|
|
sendToServer(TQString("CLOSECIRCUIT %1").arg(circuitid));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void TorClient::updatePrevConfig(PrevConfig::PrevConfigList prevlist)
|
|
|
|
{
|
|
|
|
|
|
|
|
m_previtems = prevlist;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void TorClient::applySettingsToRunningTor()
|
|
|
|
{
|
|
|
|
|
|
|
|
//FIXME: use function pointers and a list to do this
|
|
|
|
|
|
|
|
|
|
|
|
switch (TorkConfig::quickConfigure()) {
|
|
|
|
case 0 : //Tor client and server with default settings
|
|
|
|
return;
|
|
|
|
case 1 : //Tor client with default settings
|
|
|
|
return;
|
|
|
|
case 2 : //Tor server with default settings
|
|
|
|
return;
|
|
|
|
case 3 : //Tor server with default settings
|
|
|
|
return;
|
|
|
|
case 4 : //Tor server with default settings
|
|
|
|
return;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
// kdDebug() << "1" << endl;
|
|
|
|
TDEConfigSkeletonItem::List items = TorkConfig::self()->items();
|
|
|
|
TDEConfigSkeletonItem::List::ConstIterator it;
|
|
|
|
|
|
|
|
for( it = items.begin(); it != items.end(); ++it ) {
|
|
|
|
if (elementShouldBeUsed((*it))){
|
|
|
|
if (noSpecialProcessing((*it))){
|
|
|
|
PrevConfig::PrevConfigList::iterator mit;
|
|
|
|
TQVariant oldvalue;
|
|
|
|
for( mit = m_previtems.begin(); mit != m_previtems.end(); ++mit ) {
|
|
|
|
if ((*mit).name() == (*it)->name()){
|
|
|
|
oldvalue = (*mit).property();
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if ( (*it)->property().type() == TQVariant::String ) {
|
|
|
|
if ((oldvalue !=(*it)->property())){
|
|
|
|
( sendToServer(TQString("SETCONF %1=%2").arg((*it)->name()).arg((*it)->property().toString())));
|
|
|
|
}
|
|
|
|
}else if ( (*it)->property().type() == TQVariant::StringList ) {
|
|
|
|
if ((oldvalue !=(*it)->property())){
|
|
|
|
( sendToServer(TQString("SETCONF %1=\"%2\"").arg((*it)->name()).arg( (*it)->property().toStringList().join(","))));
|
|
|
|
}
|
|
|
|
}else if ( (*it)->property().type() == TQVariant::Int ) {
|
|
|
|
if ((oldvalue !=(*it)->property())){
|
|
|
|
( sendToServer(TQString("SETCONF %1=%2").arg((*it)->name()).arg( (*it)->property().toString())));
|
|
|
|
}
|
|
|
|
}else if ( (*it)->property().type() == TQVariant::Bool ) {
|
|
|
|
if ((oldvalue !=(*it)->property())){
|
|
|
|
( sendToServer(TQString("SETCONF %1=%2").arg((*it)->name()).arg( (*it)->property().toInt())));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (TorkConfig::useProxy()){
|
|
|
|
if ((TorkConfig::httpProxyPort() > 0) && (!TorkConfig::httpProxyHost().isEmpty()))
|
|
|
|
( sendToServer(TQString("SETCONF HttpProxy=%1:%2").arg(TorkConfig::httpProxyHost()).arg(TorkConfig::httpProxyPort()))) ;
|
|
|
|
if ((TorkConfig::httpsProxyPort() > 0) && (!TorkConfig::httpsProxyHost().isEmpty()))
|
|
|
|
( sendToServer(TQString("SETCONF HttpsProxy=%1:%2").arg(TorkConfig::httpsProxyHost()).arg(TorkConfig::httpsProxyPort()))) ;
|
|
|
|
|
|
|
|
if ((!TorkConfig::httpProxyAuthenticatorUserName().isEmpty()) && (!TorkConfig::httpProxyAuthenticatorPassword().isEmpty()))
|
|
|
|
( sendToServer(TQString("SETCONF HttpProxyAuthenticator=%1:%2").arg(TorkConfig::httpProxyAuthenticatorUserName()).arg(TorkConfig::httpProxyAuthenticatorPassword())));
|
|
|
|
|
|
|
|
if ((!TorkConfig::httpsProxyAuthenticatorUserName().isEmpty()) && (!TorkConfig::httpsProxyAuthenticatorPassword().isEmpty()))
|
|
|
|
( sendToServer(TQString("SETCONF HttpsProxyAuthenticator=%1:%2").arg(TorkConfig::httpsProxyAuthenticatorUserName() ).arg(TorkConfig::httpsProxyAuthenticatorPassword())));
|
|
|
|
}else{
|
|
|
|
( sendToServer(TQString("SETCONF HttpProxy=")));
|
|
|
|
( sendToServer(TQString("SETCONF HttpsProxy=")));
|
|
|
|
( sendToServer(TQString("SETCONF HttpProxyAuthenticator=")));
|
|
|
|
( sendToServer(TQString("SETCONF HttpsProxyAuthenticator=")));
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((!TorkConfig::sOCKSBindAddressHost().isEmpty()) && (TorkConfig::sOCKSBindAddressPort() > -1))
|
|
|
|
( sendToServer(TQString("SETCONF SOCKSListenAddress=%1:%2").arg(TorkConfig::sOCKSBindAddressHost()).arg( TorkConfig::sOCKSBindAddressPort()))) ;
|
|
|
|
|
|
|
|
if ((TorkConfig::sOCKSBindAddressHost().isEmpty()) && (TorkConfig::sOCKSBindAddressPort() > -1))
|
|
|
|
( sendToServer(TQString("SETCONF SOCKSPort=%2").arg(TorkConfig::sOCKSBindAddressPort()))) ;
|
|
|
|
|
|
|
|
emit copyOldConfig();
|
|
|
|
emit makeTorkStoppable();
|
|
|
|
sendToServer(TQString("GETCONF ExcludeNodes")) ;
|
|
|
|
sendToServer(TQString("GETCONF ExitNodes")) ;
|
|
|
|
sendToServer(TQString("GETCONF EntryNodes")) ;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
bool TorClient::elementShouldBeUsed(const TDEConfigSkeletonItem* it)
|
|
|
|
{
|
|
|
|
|
|
|
|
//Maxmin Settings are always applied, defaults if 'let Tor decide' selected.
|
|
|
|
if (((*it).group() == "MaxMin") ||
|
|
|
|
((!(TorkConfig::clientOnly())) && ((*it).group() == "DefaultServerAddress")) ||
|
|
|
|
((*it).group() == "FirewallEvasion") ||
|
|
|
|
((*it).group() == "Censorship") ||
|
|
|
|
(((*it).group() == "RunningSpecial")) ||
|
|
|
|
(((*it).group() == "Servers")) ||
|
|
|
|
// Server settings are applied by calling configureServer() later
|
|
|
|
//(((*it).group() == "MyServer")) ||
|
|
|
|
(((*it).group() == "Usability")) ||
|
|
|
|
(((*it).group() == "UsingTor")) ||
|
|
|
|
(((*it).group() == "MyHiddenServices")) ||
|
|
|
|
//Serverperformance Settings are always applied, defaults if 'let Tor decide' selected.
|
|
|
|
(((*it).group() == "ServerPerformance")))
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
|
|
//Excluded:
|
|
|
|
//((*it).group() == "RunningNormal")) - Because they aren't appropriate for a running Tor
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool TorClient::noSpecialProcessing(const TDEConfigSkeletonItem* it)
|
|
|
|
{
|
|
|
|
|
|
|
|
if (((*it).name() == "PublishServerDescriptor") && (TorkConfig::bridgeRelay())){
|
|
|
|
sendToServer(TQString("setconf PublishServerDescriptor=bridge"));
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((*it).name() == "HashedControlPassword"){
|
|
|
|
if ((*it).property().toString().isEmpty() &&
|
|
|
|
(!TorkConfig::cookieAuthentication()) &&
|
|
|
|
TorkConfig::generateRandomPassword()){
|
|
|
|
crypto_seed_rng();
|
|
|
|
sendToServer(TQString("setconf %1=16:%2")
|
|
|
|
.arg((*it).name())
|
|
|
|
.arg(hashPassword(crypto_rand_string(16).latin1())));
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((*it).group() == "DefaultServerAddress"){
|
|
|
|
if ((*it).name() == "ORPort")
|
|
|
|
( sendToServer(TQString("SETCONF %1=%2").arg((*it).name())
|
|
|
|
.arg( (*it).property().toString())));
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (((*it).name() == "BandwidthBurst") || ((*it).name() == "BandwidthRate")){
|
|
|
|
( sendToServer(TQString("SETCONF BandwidthBurst=%1KB BandwidthRate=%2KB")
|
|
|
|
.arg(TorkConfig::bandwidthBurst()).arg(TorkConfig::bandwidthRate())));
|
|
|
|
getBandwidth();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((*it).name() == "MaxAdvertisedBandwidth"){
|
|
|
|
( sendToServer(TQString("SETCONF %1=%2KB").arg((*it).name()).arg( (*it).property().toString())));
|
|
|
|
getBandwidth();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((*it).name() == "AccountingMax"){
|
|
|
|
( sendToServer(TQString("SETCONF %1=\"%2 bytes\"").arg((*it).name()).arg( ((*it).property().toInt() * 1024 * 1024))));
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((*it).name() == "AccountingStart"){
|
|
|
|
if ((*it).property().toString() == "day")
|
|
|
|
( sendToServer(TQString("SETCONF %1=\"%2 00:00\"").arg((*it).name()).arg( (*it).property().toString())));
|
|
|
|
else
|
|
|
|
( sendToServer(TQString("SETCONF %1=\"%2 1 00:00\"").arg((*it).name()).arg( (*it).property().toString())));
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if ((*it).name() == "KeepalivePeriod"){
|
|
|
|
if (!TorkConfig::reachableAddresses().isEmpty()){
|
|
|
|
( sendToServer(TQString("SETCONF %1=%2").arg((*it).name()).arg( ((*it).property().toInt() * 60)))) ;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((*it).name() == "TrackHostExits"){
|
|
|
|
if (!TorkConfig::trackHostExits().isEmpty()){
|
|
|
|
( sendToServer(TQString("SETCONF %1=%2").arg((*it).name()).arg( ((*it).property().toStringList().join(","))))) ;
|
|
|
|
if (TorkConfig::trackHostExitsExpire() > 0)
|
|
|
|
( sendToServer(TQString("SETCONF TrackHostExitsExpire=%2").arg((TorkConfig::trackHostExitsExpire() * 60)))) ;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if ((*it).name() == "SOCKSBindAddressMany"){
|
|
|
|
|
|
|
|
if (!TorkConfig::sOCKSBindAddressMany().isEmpty()){
|
|
|
|
TQStringList socksbind = TorkConfig::sOCKSBindAddressMany();
|
|
|
|
for ( TQStringList::Iterator it = (socksbind).begin(); it != (socksbind).end(); it++ )
|
|
|
|
{
|
|
|
|
if ((*it).isEmpty())
|
|
|
|
continue;
|
|
|
|
( sendToServer(TQString("SETCONF SOCKSListenAddress=%2").arg((*it)))) ;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((*it).name() == "ExitPolicy"){
|
|
|
|
if (TorkConfig::middleMan())
|
|
|
|
( sendToServer(TQString("SETCONF ExitPolicy=%1").arg(("\"reject *:*\"")))) ;
|
|
|
|
else
|
|
|
|
( sendToServer(TQString("SETCONF %1=\"%2\"").arg((*it).name()).arg( (*it).property().toStringList().join(","))));
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if ((*it).name() == "HiddenServices"){
|
|
|
|
TQStringList hiddenServices = TorkConfig::hiddenServices();
|
|
|
|
TQString allservices;
|
|
|
|
for ( TQStringList::Iterator it = (hiddenServices).begin(); it != (hiddenServices).end(); it++ )
|
|
|
|
{
|
|
|
|
if ((*it).isEmpty())
|
|
|
|
continue;
|
|
|
|
allservices += (TQString("HiddenServiceDir=\"%1\" HiddenServicePort=\"%2 %3\" ").arg((*it).section("\n",-1)).arg((*it).section("\n",-4,-4)).arg((*it).section("\n",-3,-3))) ;
|
|
|
|
}
|
|
|
|
if (!allservices.isEmpty())
|
|
|
|
( sendToServer(TQString("SETCONF %1").arg(allservices))) ;
|
|
|
|
else
|
|
|
|
( sendToServer(TQString("SETCONF HiddenServiceDir= HiddenServicePort="))) ;
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((TorkConfig::useBridges()) && ((*it).name() == "Bridge")){
|
|
|
|
|
|
|
|
TQStringList bridges = TorkConfig::bridge();
|
|
|
|
TQString allbridges;
|
|
|
|
for ( TQStringList::Iterator it = (bridges).begin(); it != (bridges).end(); it++ )
|
|
|
|
{
|
|
|
|
if ((*it).isEmpty())
|
|
|
|
continue;
|
|
|
|
allbridges += (TQString("Bridge=\"%1\" ")
|
|
|
|
.arg((*it))) ;
|
|
|
|
}
|
|
|
|
if (!allbridges.isEmpty())
|
|
|
|
( sendToServer(TQString("SETCONF %1").arg(allbridges))) ;
|
|
|
|
else
|
|
|
|
( sendToServer(TQString("SETCONF Bridge="))) ;
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((*it).name() == "MyFamily"){
|
|
|
|
|
|
|
|
TQStringList family = TorkConfig::myFamily();
|
|
|
|
TQStringList allfamily;
|
|
|
|
for ( TQStringList::Iterator it = (family).begin(); it != (family).end(); it++ )
|
|
|
|
{
|
|
|
|
if ((*it).isEmpty())
|
|
|
|
continue;
|
|
|
|
TQString node = "$"+getFPFromFPDigest((*it).section("-",1,1));
|
|
|
|
allfamily.append(node) ;
|
|
|
|
}
|
|
|
|
if (!allfamily.isEmpty())
|
|
|
|
( sendToServer(TQString("SETCONF MyFamily=%1").arg(allfamily.join(",")))) ;
|
|
|
|
else
|
|
|
|
( sendToServer(TQString("SETCONF MyFamily="))) ;
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((*it).name() == "MapAddress"){
|
|
|
|
|
|
|
|
TQStringList maps = TorkConfig::mapAddress();
|
|
|
|
for ( TQStringList::Iterator it = (maps).begin();
|
|
|
|
it != (maps).end(); it++ )
|
|
|
|
{
|
|
|
|
if ((*it).isEmpty())
|
|
|
|
continue;
|
|
|
|
( sendToServer(TQString("SETCONF MapAddress=%2").arg((*it)))) ;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((!TorkConfig::fascistFirewall()) && ((*it).name() == "ReachableAddresses")){
|
|
|
|
( sendToServer(TQString("SETCONF ReachableAddresses="))) ;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void TorClient::cleanUp()
|
|
|
|
{
|
|
|
|
|
|
|
|
if (TorkConfig::hashedControlPassword().isEmpty() &&
|
|
|
|
(!TorkConfig::cookieAuthentication()) &&
|
|
|
|
TorkConfig::generateRandomPassword()){
|
|
|
|
sendToServer(TQString("setconf HashedControlPassword="));
|
|
|
|
socket->flush();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
TorClient::~TorClient()
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void TorClient::parseDirStatus(const TQString &info)
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
if (info.left(2) == "r "){
|
|
|
|
ds_identity = info.section(" ",2,2);
|
|
|
|
ds_ip = info.section(" ",6,6);
|
|
|
|
ds_server = info.section(" ",1,1);
|
|
|
|
ds_date = info.section(" ",4,4);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (info.left(2) == "s "){
|
|
|
|
|
|
|
|
if (TQDate::currentDate().daysTo(TQDate(ds_date.left(4).toInt(),
|
|
|
|
ds_date.mid(5,2).toInt(),ds_date.right(2).toInt())) > -30) {
|
|
|
|
if (server(ds_identity).isEmpty())
|
|
|
|
storeServer(ds_server,ds_identity);
|
|
|
|
|
|
|
|
ds_statuses = info;
|
|
|
|
emit updateServerStatus(ds_ip, ds_identity, ds_server, ds_statuses);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
bool TorClient::isControllerWorking()
|
|
|
|
{
|
|
|
|
return m_controllerWorking;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void TorClient::setBandwidth(const TQString &rate, const TQString &burst, const TQString &max)
|
|
|
|
{
|
|
|
|
( sendToServer(TQString("SETCONF BandwidthRate=%2KB BandwidthBurst=%2KB")
|
|
|
|
.arg(rate).arg(burst)));
|
|
|
|
if (!max.isEmpty())
|
|
|
|
( sendToServer(TQString("SETCONF MaxAdvertisedBandwidth=%2KB").arg(max)));
|
|
|
|
getBandwidth();
|
|
|
|
}
|
|
|
|
|
|
|
|
void TorClient::getBandwidth()
|
|
|
|
{
|
|
|
|
( sendToServer(TQString("GETCONF BandwidthRate")));
|
|
|
|
( sendToServer(TQString("GETCONF BandwidthBurst")));
|
|
|
|
( sendToServer(TQString("GETCONF MaxAdvertisedBandwidth")));
|
|
|
|
}
|
|
|
|
|
|
|
|
void TorClient::handleTorVersion( const TQString &caption)
|
|
|
|
{
|
|
|
|
m_currentTorVersion = caption;
|
|
|
|
if (m_currentTorVersion.left(3) == "0.2")
|
|
|
|
sendToServer("SETCONF DownloadExtraInfo=1");
|
|
|
|
emit setTorCaption(caption);
|
|
|
|
}
|
|
|
|
|
|
|
|
void TorClient::closeAllCircuits( TQListView* &circuitList)
|
|
|
|
{
|
|
|
|
TQListViewItemIterator cit(circuitList);
|
|
|
|
while ( cit.current() ) {
|
|
|
|
attemptCloseCircuit(cit.current()->text(0));
|
|
|
|
++cit;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void TorClient::assignPortToRemove()
|
|
|
|
{
|
|
|
|
//called by the warning message to get the port to remove in case
|
|
|
|
// user requests it.
|
|
|
|
if (m_WarnedPorts[0].isNull())
|
|
|
|
return;
|
|
|
|
kdDebug() << "warnedports " << m_WarnedPorts[0] << endl;
|
|
|
|
m_portToRemove = m_WarnedPorts[0];
|
|
|
|
kdDebug() << "porttoremove" << m_portToRemove << endl;
|
|
|
|
m_WarnedPorts.pop_front();
|
|
|
|
kdDebug() << "porttoremove" << m_portToRemove << endl;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void TorClient::allowPlainTextPorts()
|
|
|
|
{
|
|
|
|
|
|
|
|
kdDebug() << "m_portsToReject " << m_portsToReject << endl;
|
|
|
|
|
|
|
|
m_portsToReject.remove(m_portsToReject.find(m_portToRemove));
|
|
|
|
sendToServer(TQString("SETCONF WarnPlainTextPorts=%1")
|
|
|
|
.arg(m_portsToReject.join(",")));
|
|
|
|
sendToServer(TQString("SETCONF RejectPlainTextPorts=%1")
|
|
|
|
.arg(m_portsToReject.join(",")));
|
|
|
|
}
|
|
|
|
|
|
|
|
void TorClient::resolveAddress(const TQString &address)
|
|
|
|
{
|
|
|
|
TQRegExp rx("[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}");
|
|
|
|
rx.search(address);
|
|
|
|
TQString tmp = rx.cap(0);
|
|
|
|
if (tmp.isEmpty()) {
|
|
|
|
sendToServer("RESOLVE " + address);
|
|
|
|
logResolveList << address;
|
|
|
|
}else{
|
|
|
|
sendToServer("RESOLVE mode=reverse " + tmp);
|
|
|
|
logResolveList << TQString("REVERSE[%1]").arg(tmp);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#include "torclient.moc"
|
|
|
|
|