You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tork/src/torclient.cpp

1537 lines
53 KiB

/****************************************************************************
** $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. *
***************************************************************************/
#include <ntqsocket.h>
#include <ntqtextstream.h>
#include <ntqstringlist.h>
#include <ntqregexp.h>
#include "torclient.h"
#include "tork.h"
#include "torkconfig.h"
#include "dndlistview.h"
#include "functions.h"
#include <ntqtimer.h>
#include <klocale.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>
#include <ntqdir.h>
#include "crypto.h"
#ifndef EXTERNAL_GEOIP
# include "GeoIP-1.4.0/libGeoIP/GeoIP.h"
#else
# include <GeoIP.h>
#endif
/* 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>"
"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"
"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"
"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b>24 hrs</b>"
"&nbsp;&nbsp;&nbsp;" // 1 space
"&nbsp;&nbsp;&nbsp;" // 1 space
"&nbsp;&nbsp;&nbsp;" // 1 space
"&nbsp;&nbsp;&nbsp;" // 1 space
"&nbsp;&nbsp;&nbsp;<b>12 hrs</b>"
"&nbsp;&nbsp;&nbsp;" // 1 space
"&nbsp;&nbsp;&nbsp;" // 1 space
"&nbsp;&nbsp;&nbsp;" // 1 space
"&nbsp;&nbsp;&nbsp;" // 1 space
"&nbsp;&nbsp;&nbsp;<b>6 hrs</b>"
"&nbsp;&nbsp;&nbsp;" // 1 space
"&nbsp;&nbsp;&nbsp;" // 1 space
"&nbsp;&nbsp;&nbsp;" // 1 space
"&nbsp;&nbsp;&nbsp;" // 1 space
"&nbsp;&nbsp;&nbsp;" // 1 space
"&nbsp;&nbsp;&nbsp;<b>1 hr</b><br>"
"<b>Up</b>"
"&nbsp;&nbsp;&nbsp;&nbsp;" // 1 space
"&nbsp;&nbsp;&nbsp;&nbsp;" // 1 space
"&nbsp;&nbsp;&nbsp;&nbsp;" // 1 space
"<font color='#990000'>$BWUP</font><br>"
"<b>Down</b>"
"&nbsp;&nbsp;&nbsp;" // 1 space
"&nbsp;&nbsp;&nbsp;" // 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))));
}
}
}
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)
#ifndef EXTERNAL_GEOIP
gi = GeoIP_open(locate("data", "tork/geoip/GeoIP.dat").ascii(),0);
#else
gi = GeoIP_new(GEOIP_STANDARD);
#endif
if (gi){
int country_id = 0;
country_id = GeoIP_id_by_name(gi, ip);
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
KLocale* loc = KGlobal::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("&nbsp;&nbsp;");
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("&nbsp;&nbsp;");
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;
KConfigSkeletonItem::List items = TorkConfig::self()->items();
KConfigSkeletonItem::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 KConfigSkeletonItem* 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 KConfigSkeletonItem* 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))));
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"