/*************************************************************************** ** $Id: torkview.cpp,v 1.125 2009/11/07 14:21:56 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 #include "torkview.h" #include "tork.h" #include "torclient.h" #include #include #include #include "dndlistview.h" #include "portsandicons.h" #include "torkconfig.h" #include "chart.h" #include "functions.h" #include "mixminion.h" #include "crypto.h" #include "hitwidget.h" #include "kwidgetlistbox.h" #include "kerrylabel.h" #ifndef EXTERNAL_GEOIP # include "GeoIP-1.4.0/libGeoIP/GeoIP.h" #else # include #endif #include "kdebug.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* Linux-specific includes */ #include #include #include "../config.h" using namespace tk; #define MAX_BW_RATE 2 #define MAX_CG_RATE 60*5 #define MAX_TN_RATE 60*20 #define MAX_CBWS_RATE 60 torkView::torkView(QWidget *parent) : torkview_base(parent), m_pop(0L), m_tormon(TorkConfig::showTorMon()), torbtx(0), torbrx(0) { #ifndef EXTERNAL_GEOIP geoip_db = !locate("data", "tork/geoip/GeoIP.dat").isNull(); #else GeoIP * gi = 0; gi = GeoIP_new(GEOIP_STANDARD); if (gi) geoip_db = true; else geoip_db = false; #endif greenonion << "green" << "up" << "built" << "good" << "connected" << "succeeded"; redonion << "red" << "down" << "bad" << "failed"; yellowonion << "yellow" << "sentconnect"; orangeonion << "orange" << "sentresolve"; littleonion << "little" << "launched" << "new" << "detached"; todelete << "todelete" << "closed" << "failed" << "dropped"; iconList << greenonion << redonion << yellowonion << orangeonion << littleonion; guard << "up" << "up" << "built" << "good" << "connected"; redguard << "red" << "down" << "bad" << "dropped" << "unusable" << "failed"; detachedguard << "detached" << "never-connected" << "unlisted" << "succeeded"; littleguard << "little" << "new" << "sentresolve" << "sentconnect"; guardIconList << guard << redguard << detachedguard << littleguard; greenonion << "green" << "built"; redonion << "red" << "failed"; yellowonion << "yellow" << "extended"; littleonion << "little" << "launched"; circuitIconList << greenonion << redonion << yellowonion << littleonion; torType += i18n("running a Tor Client and Server With Default Settings"); torType += i18n("running a Tor Client and Relay Server With Default Settings"); torType += i18n("running a Tor Server With Default Settings"); torType += i18n("running a Tor Relay Server With Default Settings"); torType += i18n("running a Tor Client with Default Settings"); torType += i18n("running an instance of Tor using all the settings in the configure dialog"); torType += i18n("connected to a Remote Instance of Tor"); torType += i18n("connected to a Local Instance of Tor"); streamPurpose["DIR_FETCH"] = "Tor(Directory Fetch)"; streamPurpose["DNS_REQUEST"] = "Tor(DNS)"; streamPurpose["UPLOAD_DESC"] = "Tor(Upload Descriptor)"; streamPurpose["DIRPORT_TEST"] = "Tor(Server Test)"; mFirstUpdate = true; if (checkInterface()) gotEth0 = true; else gotEth0 = false; if (!TorkConfig::showTorBar()) frame4->hide(); settingsChanged(); populateMenu(); menuItems << sshitem << gpgitem << telnetitem << kopeteitem << ksircitem; menuItems << allpurposeitem << konversationitem << pidginitem << gaimitem << operaitem << firefoxitem; menuItems << hiddenservicesitem << konqitem << mixminionitem; for ( QValueList::Iterator it = menuItems.begin(); it != menuItems.end(); ++it ){ if (*it) (*it)->setEnabled(false); } resetBWHistory(); Chart* chart = new Chart(ChartFrame, speedHistoryTx(), speedHistoryRx(), historyBufferSize(), historyPointer(), maxSpeed(), sys_speedHistoryTx(), sys_speedHistoryRx(), sys_historyBufferSize(), sys_historyPointer(), sys_maxSpeed(), gotEth0); chart->setMinimumWidth(ChartFrame->width()); chart->setMinimumHeight(ChartFrame->height()); connect(this, SIGNAL(updateStats()), chart, SLOT(update())); m_osd = new StreamOSD(this, true); m_osd->readSettings(KGlobal::config()); m_nontorosd = new StreamOSD(this, false); m_nontorosd->readSettings(KGlobal::config()); //Icons showing the status of the stream streamStatusIcon["SUCCEEDED"] = QPixmap(SmallIcon("tork_green")); streamStatusIcon["FAILED"] = QPixmap(SmallIcon("tork_red")); streamStatusIcon["SENTCONNECT"] = QPixmap(SmallIcon("tork_yellow")); streamStatusIcon["SENTRESOLVE"] = QPixmap(SmallIcon("tork_orange")); streamStatusIcon["NEW"] = QPixmap(SmallIcon("tork_little")); streamStatusIcon["DETACHED"] = QPixmap(SmallIcon("tork_little")); streamStatusIcon["CLOSED"] = QPixmap(SmallIcon("tork_todelete")); progDisplayCounter = 0; } void torkView::resetBWHistory() { memset(mSpeedHistoryRx, 0, sizeof(double)*HISTORY_SIZE); memset(mSpeedHistoryTx, 0, sizeof(double)*HISTORY_SIZE); memset(mSpeedBufferRx, 0, sizeof(double)*SPEED_BUFFER_SIZE); memset(mSpeedBufferTx, 0, sizeof(double)*SPEED_BUFFER_SIZE); mMaxSpeedAge = 0; mMaxSpeed = 0.0; mSpeedBufferPtr = mSpeedHistoryPtr = 0; mBRx = mBTx = 0; memset(sys_mSpeedHistoryRx, 0, sizeof(double)*HISTORY_SIZE); memset(sys_mSpeedHistoryTx, 0, sizeof(double)*HISTORY_SIZE); memset(sys_mSpeedBufferRx, 0, sizeof(double)*SPEED_BUFFER_SIZE); memset(sys_mSpeedBufferTx, 0, sizeof(double)*SPEED_BUFFER_SIZE); sys_mMaxSpeedAge = 0; sys_mMaxSpeed = 0.0; sys_mSpeedBufferPtr = sys_mSpeedHistoryPtr = 0; sysmBRx = sysmBTx = 0; mFirstUpdate = true; torbtx = 0; torbrx = 0; } void torkView::updateChart() { emit updateStats(); } void torkView::changeQuickConfigure(int no) { /* QValueList qconf; qconf << 4 << 2 << 3 << 5 << 6 << 7;*/ TorkConfig::setQuickConfigure(no); } void torkView::clearStreamMaps() { streams.clear(); osdstreams.clear(); circuitExits.clear(); streamBwIn.clear(); streamBwOut.clear(); logstreams.clear(); cachedStreamIcon.clear(); torservers.clear(); } void torkView::downloadTorButton() { int result = KMessageBox::questionYesNo(0, i18n( "

Once you install TorButton, restart Firefox from here " "rather than letting Firefox restart automatically. This will" " ensure you do not browse with your normal Firefox " "profile.
Continue?

") ,i18n( "Be sure to restart Firefox from Tork!" )); switch (result) { case KMessageBox::Yes : anonymizedFirefox( "http://www.torproject.org/torbutton/torbutton-current.xpi"); } } void torkView::downloadMixminion() { TorkUpdate* updater = new TorkUpdate(this); updater->downloadMixminion(); } void torkView::sendAnonymousEmail() { if (TorkConfig::availablePrograms().contains("mixminion")){ QString caption; QString message; caption = i18n("Mixminion Not Installed!"); message = i18n("

Mixminion does not appear to be installed on your system.
"); message += i18n("

Try installing it from the main interface.
"); KMessageBox::information (this, message, caption); return; } MixMinionClient* mixminion = new MixMinionClient(); mixminion->show(); } bool torkView::checkInterface() { bool gotone = false; //Would anyone have this many ethernet cards? QStringList devices; devices << "eth" << "wlan"; for ( QStringList::Iterator it = devices.begin(); it != devices.end(); ++it ){ for (int i=0; i < 5; i++){ QString devpath = QString("/sys/class/net/%1%2").arg((*it)).arg(i); QDir ethdir(devpath); if (ethdir.exists()){ mSysDevPathList.append(devpath); gotone = true; }else continue; } } return gotone; } void torkView::torify(const QString& text) { QString command = "usewithtor " + text; QString icon = text.section(" ",0,0); KRun::runCommand( command, icon, icon ); } void torkView::anonymousFirefox() { anonymizedFirefox("http://healthcheck.anonymityanywhere.com/"); } void torkView::anonymizedFirefox(const QString& url) { QString text = "firefox"; QString firefoxdir = QString("%1/.mozilla/firefox").arg(getenv("HOME")); QString torkfirefox = QString("%1/tork.TorkAnonymous").arg(firefoxdir); QDir torkdir(torkfirefox); if (!torkdir.exists()){ QFile inf(QString("%1/profiles.ini").arg(firefoxdir)); QString line; int profileno=0; if ( inf.open(IO_ReadOnly) ) { QTextStream stream( &inf ); while ( !stream.atEnd() ) { line = stream.readLine(); // line of text excluding '\n' if (line.contains("[Profile")){ QRegExp rx("([0-9]{1,4})"); rx.search(line); profileno = rx.cap(0).toInt() + 1; } if (line.contains(".default")) break; } inf.close(); }else{ emit processWarning("cantreadprofiles",i18n("Can't read %1") .arg(QString("%1/profiles.ini").arg(firefoxdir))); KIO::NetAccess::del(torkfirefox,0L); return; } QString originalprofile = line.replace("Path=",""); QString originalfirefox = QString("%1/%2").arg(firefoxdir).arg(originalprofile); if (!KIO::NetAccess::dircopy(originalfirefox,torkfirefox, 0L)) { emit processWarning("cantcopyprofile",i18n("Can't copy %1").arg(originalfirefox)); KIO::NetAccess::del(torkfirefox,0L); return; } //Update Profile QFile inf2(QString("%1/profiles.ini").arg(firefoxdir)); if ( inf2.open(IO_WriteOnly | IO_Append) ) { QTextStream ts( &inf2 ); ts << "\n"; ts << "[Profile" << profileno << "]" << "\n"; ts << "Name=TorkAnonymous" << "\n"; ts << "IsRelative=1" << "\n"; ts << "Path=tork.TorkAnonymous" << "\n"; ts << "\n"; inf2.close(); }else{ emit processWarning("cantreadprofiles",i18n("Can't read %1") .arg(QString("%1/profiles.ini").arg(firefoxdir))); KIO::NetAccess::del(torkfirefox,0L); return; } } //Update Profile QFile inf3(QString("%1/prefs.js").arg(torkfirefox)); if ( inf3.open(IO_WriteOnly | IO_Append) ) { QTextStream ts( &inf3 ); ts << "user_pref(\"network.proxy.ftp\", \"\");" << "\n"; ts << "user_pref(\"network.proxy.ftp_port\", 0);" << "\n"; ts << "user_pref(\"network.proxy.gopher\", \"\");" << "\n"; ts << "user_pref(\"network.proxy.gopher_port\", 0);" << "\n"; ts << "user_pref(\"network.proxy.http\", \"" << TorkConfig::konqHttpProxy().replace("http://","") << "\");" << "\n"; ts << "user_pref(\"network.proxy.http_port\", " << TorkConfig::konqHttpProxyPort() << ");" << "\n"; ts << "user_pref(\"network.proxy.share_proxy_settings\", true);" << "\n"; ts << "user_pref(\"network.proxy.ssl\", \"" << TorkConfig::konqHttpsProxy().replace("http://","") << "\");" << "\n"; ts << "user_pref(\"network.proxy.ssl_port\", " << TorkConfig::konqHttpsProxyPort() << ");" << "\n"; ts << "user_pref(\"network.proxy.type\", 1);" << "\n"; //Java/Javascript disabled ts << "user_pref(\"javascript.enabled\", false);" << "\n"; ts << "user_pref(\"pref.advanced.javascript.disable_button.advanced\", false);" << "\n"; ts << "user_pref(\"security.enable_java\", false);" << "\n"; //Cookies Disabled ts << "user_pref(\"network.cookie.cookieBehavior\", 2);" << "\n"; //Point SOCKS to Tor ts << "user_pref(\"network.proxy.socks\", \"" << TorkConfig::sOCKSBindAddressHost().replace("http://","") << "\");" << "\n"; ts << "user_pref(\"network.proxy.socks_port\", " << TorkConfig::sOCKSBindAddressPort() << ");" << "\n"; ts << "user_pref(\"network.proxy.socks_version\", 5);" << "\n"; //Ensure dns requests go through proxy ts << "user_pref(\"network.proxy.socks_remote_dns\", true);" << "\n"; //Tor doesn't do IPv6 ts << "user_pref(\"network.dns.disableIPv6\", true);" << "\n"; //Additional settings taken from TorToGo // //Disable Auto-Updating of Extensions ts << "user_pref(\"extensions.update.autoUpdateEnabled\", false);" << "\n"; ts << "user_pref(\"extensions.update.autoUpdate\",false);" << "\n"; ts << "user_pref(\"extensions.update.enabled\",false);" << "\n"; //Disable Auto-Updating of Firefox ts << "user_pref(\"app.update.auto\",false);" << "\n"; ts << "user_pref(\"app.update.enabled\",false);" << "\n"; //Disable Updating of Searchbar ts << "user_pref(\"browser.search.update\",false);" << "\n"; //No compression. Compression can prevent munging of environmental variables ts << "user_pref(\"network.http.accept-encoding:gzip;q=0,deflate;q=0,compress;q=0\",false);" << "\n"; // --Accept MIME type ts << "user_pref(\"network.http.accept.default:text/xml,application/xml, application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5);" << "\n"; //--English non-localized ts << "user_pref(\"intl.accept_languages\",en);" << "\n"; ts << "user_pref(\"intl.accept_charsets\",ISO-8859-1,*);" << "\n"; //~User Agent/Anonymity Set (This will create a large anonymity set for Tor users): ts << "user_pref(\"general.useragent.override\",Mozilla/5.0 (Windows; U; Windows NT 5.1; en; rv:1.7.10) Gecko/20050716 Firefox/1.5.0.7);" << "\n"; // --Spoof the version of Firefox in use (real version is v.2.0.0.3rc) ts << "user_pref(\"general.useragent.extra.firefox\",Firefox/1.5.0.7);" << "\n"; //--Required to match "intl.accept_languages" above ts << "user_pref(\"general.useragent.locale\",en);" << "\n"; ts << "user_pref(\"extensions.torbutton.tor_enabled\", true);" << "\n"; inf3.close(); }else{ emit processWarning("cantwritefirefoxsettings", i18n("Can't write to %1").arg(QString("%1/prefs.js").arg(torkfirefox))); KIO::NetAccess::del(torkfirefox,0L); return; } KRun::runCommand( QString("%1 -P TorkAnonymous %2").arg(text).arg(url), text, text ); } void torkView::anonymousOpera() { anonymizedOpera("http://healthcheck.anonymityanywhere.com/"); } void torkView::anonymizedOpera(const QString& url) { QString text = "opera"; QString originalopera = QString("%1/.opera").arg(getenv("HOME")); QString torkopera = QString("%1/.opera-tork").arg(getenv("HOME")); QDir torkdir(torkopera); if (!torkdir.exists()) KIO::NetAccess::dircopy(originalopera,torkopera,0L); QFile inf(QString("%1/.opera-tork/opera6.ini").arg(getenv("HOME"))); if ( inf.open(IO_WriteOnly | IO_Append) ) { QTextStream ts( &inf ); ts << "[Proxy]" << "\n"; ts << "HTTPS server=" << TorkConfig::konqHttpsProxy() << ":" << TorkConfig::konqHttpsProxyPort() << "\n"; ts << "HTTP server=" << TorkConfig::konqHttpProxy() << ":" << TorkConfig::konqHttpProxyPort() << "\n"; ts << "Use HTTP=1" << "\n"; ts << "Use HTTPS=1" << "\n"; ts << "Use Automatic Proxy Configuration=0" << "\n"; ts << "[Java]" << "\n"; ts << "Enabled=0" << "\n"; ts << "[Extensions]" << "\n"; ts << "Scripting=0" << "\n"; ts << "Plugins=0" << "\n"; ts << "[User Prefs]" << "\n"; ts << "Enable Cookies=0" << "\n"; inf.close(); KRun::runCommand( QString("%1 -personaldir %2 -newpage %3").arg(text).arg(torkopera).arg(url), text, text ); } } void torkView::privoxiedBash() { QString location = getenv("HOME"); location += "/.tork"; QDir torkdir(location); if (!torkdir.exists() && !torkdir.mkdir(location)) location = getenv("HOME"); QFile inf(QString("%1/privoxy_konsole_session").arg(location)); if (! inf.open(IO_WriteOnly) ) { inf.close(); KMessageBox::information (this,"Couldn't create bash session file!"); return ; } QTextStream ts( &inf ); /* QTextStream &ts = *(inf.textStream());*/ ts << QString("http_proxy=%1:%2").arg(TorkConfig::konqHttpProxy()).arg(TorkConfig::konqHttpProxyPort()) << "\n"; ts << QString("https_proxy=%1:%2").arg(TorkConfig::konqHttpsProxy()).arg(TorkConfig::konqHttpsProxyPort()) << "\n"; ts << "HTTP_PROXY=$http_proxy" << "\n"; ts << "HTTPS_PROXY=$https_proxy" << "\n"; ts << "export HTTP_PROXY HTTP_PROXY http_proxy https_proxy" << "\n"; ts << "echo Using $http_proxy and $https_proxy as a privacy proxy in this bash session." << "\n"; ts << "echo Using commands such as 'su' will cease use of the privacy proxy." << "\n"; inf.close(); KRun::runCommand( QString("konsole --caption 'Shell Using Privoxy for Http requests - Launched From TorK' --noclose -e bash --init-file %1").arg(inf.name()), "konsole", "konsole" ); } void torkView::toggleParanoidMode(int id) { switch(id) { case 0: paranoidmodeicon->setPixmap(SmallIcon("tork_penguin")); paranoidmodetext->setText(i18n("In Normal mode!")); break; case 1: paranoidmodeicon->setPixmap(SmallIcon("tork_agent")); paranoidmodetext->setText(i18n("In DNS FailSafe mode!")); break; case 2: paranoidmodeicon->setPixmap(SmallIcon("gv")); paranoidmodetext->setText(i18n("In System FailSafe mode!")); break; default: return; } TorkConfig::setParanoidMode(id); } void torkView::toggleAnonymizerTork(bool state) { welcomeitem->setEnabled(true); disconnect(welcomeitem->icon, SIGNAL(leftClickedURL()), this, SIGNAL(startEverything())); disconnect(welcomeitem->icon, SIGNAL(leftClickedURL()), this, SIGNAL(stopEverything())); if (state){ connect(welcomeitem->icon, SIGNAL(leftClickedURL()), SIGNAL(stopEverything())); welcomeheaderLabel->setText(i18n("Welcome to the Tor Network!")); welcomeitem->setIcon("tork_stop"); welcomeitem->setDescriptionText(""+i18n("- You are %1.
" ).arg(torType[TorkConfig::quickConfigure()])+"
"); welcomeitem->setPropertiesText(""+i18n( "- The 'Tor Network' tab shows you the state of the Tor network, including your Tor Traffic.
" "- You can use the 'Traffic Log' tab to view Tor and Non-Tor Traffic on your system.
" "- You can use the 'Tor Log' tab to view warning messages from Tor itself.
" "- Try out the services listed below.
" )+"
"); setHiddenServicesText(); welcomeitem->score->setEnabled(false); for ( QValueList::Iterator it = menuItems.begin(); it != menuItems.end(); ++it ){ if (*it) (*it)->setEnabled(true); } }else{ connect(welcomeitem->icon, SIGNAL(leftClickedURL()), SIGNAL(startEverything())); welcomeitem->setIcon("tork_pressplay"); welcomeheaderLabel->setText(i18n("Press 'Play' to get started!")); welcomeitem->setDescriptionText(""+i18n("- Press 'Play' to connect to Tor. (You can also use the toolbar icons.)
" )+"
"); welcomeitem->setPropertiesText(""+i18n( "- The 'Tor Network' tab shows you the state of the Tor network, including your Tor Traffic.
" "- You can use the 'Traffic Log' tab to view Tor and Non-Tor Traffic on your system.
" "- You can use the 'Tor Log' tab to view warning messages from Tor itself.
" "- Once Tor is up and running you can use the services listed below.
" )+"
"); welcomeitem->score->setEnabled(true); setHiddenServicesText(); for ( QValueList::Iterator it = menuItems.begin(); it != menuItems.end(); ++it ){ if (*it) (*it)->setEnabled(false); } } } void torkView::setHiddenServicesText() { QString activeHiddenServices; QStringList hiddenServices = TorkConfig::hiddenServices(); for ( QStringList::Iterator it = hiddenServices.begin(); it != hiddenServices.end(); ++it ) { if ((*it).isEmpty()) continue; if (!(*it).section("\n",-2,-2).isEmpty()) activeHiddenServices.append(i18n("%1 (serving files from %2)").arg((*it).section("\n",-6,-6)).arg((*it).section("\n",-2,-2))); else activeHiddenServices.append(i18n("%1 (redirecting to %2)").arg((*it).section("\n",-6,-6)).arg((*it).section("\n",-3,-3))); } if (!activeHiddenServices.isEmpty()){ hiddenservicesitem->setPropertiesText(""+i18n( "- You are running the following hidden services:
    %1
" ).arg(activeHiddenServices)+"
"); }else{ hiddenservicesitem->setPropertiesText(""+i18n( "- Anonymous web sites/web services are known as 'hidden services'.
" "- Their location and ownership are concealed by the operation of the Tor network.
" )+"
"); } } torkView::~torkView() { } #define MAXPROGDISPLAY 5 void torkView::streamStatusUpdated(const QString &streamID, const QString &status, const QString &circID, const QString &Target, const QString &info) { QString tmpstatus = status.stripWhiteSpace(); streamItem* streamline; QListViewItem* osdstreamline; QListViewItem* torTrafficLine; torTrafficLine=0L; if (!(streamline = streams[streamID])){ if (!(tmpstatus == "CLOSED") && !(tmpstatus == "FAILED")){ m_osd->setShown(m_tormon); m_osd->infoList->adjustColumn(1); infoList->adjustColumn(2); timeLastTorUse = QTime::currentTime(); QString cleanedFullTarget = Target; cleanedFullTarget.replace(QRegExp("(\\.\\$[A-Z0-9]{40})\\."),"."); QString cleanedTarget = cleanedFullTarget.section(":",0,0); QString cleanedPort = cleanedFullTarget.section(":",1,1); addrLastTorUse = cleanedFullTarget; if (TorkConfig::paranoidMode() > 0) emit newIdentity(); // Find the program associated with the stream QString program = ".."; QPixmap programicon; if ((tmpstatus == "NEW")){ if (info.contains("PURPOSE=USER")){ QRegExp rx("(SOURCE_ADDR=127.0.0.1:[0-9]+ )"); rx.search(info); QString port = rx.cap(0).section("SOURCE_ADDR=127.0.0.1:",-1) .stripWhiteSpace(); portStream[streamID] = port; }else{ QString purpose = info.section("PURPOSE=",-1,-1); program = streamPurpose[purpose]; programicon = QPixmap(SmallIcon("tork_tor")); } } // Assign the circuit and exit server to the stream circuitItem* circuitline; QString circuit = "Pending.."; QString exitserver; QPixmap exitserverflag; // Don't look for circuit if one hasn't been assigned yet if (circID != "0") { if ((circuitline = (circuitItem*) circuitList->findItem(circID,0)) != 0){ QListViewItem* serverline; if ((serverline = (QListViewItem*) circuitExits[circID]) != 0){ exitserver = serverline->text(1); exitserverflag = *serverline->pixmap(1); } circuit = circuitline->text(2); } } //Assign an icon to illustrate the type of stream QPixmap icon = cachedStreamIcon[cleanedFullTarget]; if (icon.isNull()){ QString iconPath = locate("cache", KMimeType::favIconForURL("http://"+cleanedTarget) +".png"); if (!iconPath.isEmpty()){ icon.load( iconPath ); if (cleanedPort == "443"){ QPixmap overlay = KSystemTray::loadIcon( "tork_ssl" ); if ( !overlay.isNull() ) { int x = icon.width() - overlay.width(); int y = icon.height() - overlay.height(); if ( icon.mask() ) { QBitmap mask = *icon.mask(); bitBlt( &mask, x, y, overlay.mask() ? const_cast(overlay.mask()) : &overlay, 0, 0, overlay.width(), overlay.height(), overlay.mask() ? OrROP : SetROP ); icon.setMask(mask); } bitBlt( &icon, x, y, &overlay ); } } }else{ int i; for (i = 0; _port_icon[i].port; ++i) { portsandicons_t *pics = &_port_icon[i]; if (cleanedPort == pics->port){ icon = SmallIcon(pics->icon); if ((!pics->secure) && (!pics->display)){ pics->display = DONT_DISPLAY_AGAIN; if (pics->screaminglyinsecure) emit showScreamingNotice(cleanedPort); else emit showSecurityNotice(cleanedPort); } } } } cachedStreamIcon[cleanedFullTarget] = icon; } //Assign an icon to illustrate the stream status QPixmap statusicon = streamStatusIcon[tmpstatus]; //Display the entries in the UI //Add to the traffic log if necessary if (TorkConfig::logTorTraffic()){ torTrafficLine = new QListViewItem(TorTraffic, streamID, QDateTime::currentDateTime(). toString(Qt::ISODate). replace("T"," "), cleanedFullTarget, circuit); torTrafficLine->setPixmap( 2, icon ); } // The stream in the 'Connections' Pane streamline = new streamItem(streamList, streamID, program, cleanedFullTarget, "", "0 B/s", exitserver, circuit); streamline->setPixmap(1,programicon); streamline->setPixmap(2,icon); streamline->setPixmap(3,statusicon); streamline->setPixmap(5,exitserverflag); streamline->setDragEnabled(true); streamline->setDropEnabled(true); //The stream in the OSD display osdstreamline = new QListViewItem(m_osd->infoList,streamID, cleanedTarget,"","0 B/s", circuit); osdstreamline->setPixmap(2,statusicon); osdstreamline->setPixmap(1,icon); // Cache for quick reference streams[streamID] = streamline; osdstreams[streamID] = osdstreamline; logstreams[streamID] = torTrafficLine; } }else{ osdstreamline = osdstreams[streamID]; if (tmpstatus == "CLOSED"){ kdDebug() << "progcnt: " << progDisplayCounter << endl; if ((streamline->text(1) != "..") && (progDisplayCounter > 0)) progDisplayCounter--; streams.erase(streamID); streamBwIn.erase(streamID); streamBwOut.erase(streamID); osdstreams.erase(streamID); portStream.erase(streamID); logstreams.erase(streamID); if (osdstreamline) delete osdstreamline; delete streamline; return; } QPixmap statusicon = streamStatusIcon[status.stripWhiteSpace()]; streamline->setPixmap(3,statusicon); osdstreamline->setPixmap(2,statusicon); // If the stream does not have a verbose circuit description, add one if ((streamline->text(6) == "Pending..")){ QString circuit = "Pending.."; QString exitserver; QPixmap exitserverflag; circuitItem* circuitline; // Don't look for circuit if one hasn't been assigned yet if (circID != "0") { if ((circuitline = (circuitItem*) circuitList->findItem(circID,0)) != 0){ QListViewItem* serverline; if ((serverline = (QListViewItem*) circuitExits[circID]) != 0){ exitserver = serverline->text(1); exitserverflag = *serverline->pixmap(1); } circuit = circuitline->text(2); } if ((torTrafficLine = logstreams[streamID])){ torTrafficLine->setText(3,circuit); } streamline->setText(6, circuit); streamline->setPixmap(5,exitserverflag); streamline->setText(5,exitserver); osdstreamline->setPixmap(4,exitserverflag); osdstreamline->setText(4,exitserver); } } if (tmpstatus == "SUCCEEDED"){ //HACK: this is too process intensive if there are many short-lived // streams so we only look for the program if we aren't // already displaying it in MAXPROGDISPLAY streams and there's // less than MAXPROGDISPLAY * 3 streams active in total. // There's also no point in looking up the program unless // the connection is successful if (streamline->text(1) == ".."){ if ((streamList->childCount() < (MAXPROGDISPLAY * 3)) && (progDisplayCounter < MAXPROGDISPLAY)) { QString program = parseStreamPort(portStream[streamID]); QPixmap programicon = streamProgram(program); streamline->setText(1,program); streamline->setPixmap(1,programicon); progDisplayCounter++; } } } } } QString torkView::parseStreamPort(const QString &str_port) { int m_port = str_port.toInt(); #define MAX_PROC_STR_LEN 32 /* /proc/1234/fd/1234 or socket:[12345] */ #define PROC_NET_TCP_PATH "/proc/net/tcp" #define PROC_NET_UDP_PATH "/proc/net/udp" char fdpath[MAX_PROC_STR_LEN]; char lbuf[MAX_PROC_STR_LEN]; struct dirent *pde; DIR *pdir; QString line; QString inode; bool foundIt = false; QFile tcp("/proc/net/tcp") ; tcp.open (IO_ReadOnly) ; QTextStream input(&tcp) ; while (!input.eof()) { QString line = input.readLine() ; QStringList bits = QStringList::split (QRegExp("[ :]+"), line) ; int port = bits[2].toLong(0, 16) ; if (port == m_port) { inode = bits[13]; break; } } if (inode.isEmpty()) return QString(); QDir d = QDir( "/proc" ); QStringList dirs = d.entryList( QDir::Dirs ); QStringList::Iterator it; for ( it = dirs.begin(); it != dirs.end(); ++it ) { QDir fd = QDir( "/proc/" +*it+"/fd" ); if (!fd.exists()) continue; QString path = "/proc/" +*it+"/fd"; if ((pdir = opendir((const char*)path)) == NULL) continue; while ((pde = readdir(pdir)) != NULL) { snprintf(fdpath, MAX_PROC_STR_LEN, "/proc/%s/fd/%s", (const char*)*it, pde->d_name); fdpath[MAX_PROC_STR_LEN - 1] = '\0'; int len = readlink(fdpath, lbuf, MAX_PROC_STR_LEN); if (len < 0 || len > MAX_PROC_STR_LEN) continue; lbuf[len] = '\0'; if (QString(lbuf).contains(inode)){ foundIt = true; QFile file( "/proc/"+*it+"/cmdline" ); file.open( IO_ReadOnly ); if ( !file.isOpen() ) continue; QTextStream t( &file ); QString program = t.readLine(); program.replace('\0',' '); program = program.section(" ",0,0).section("/",-1); return program; } } closedir(pdir); if (foundIt) break; } return QString(); } void torkView::circuitStatusUpdated(const QString &circuitID, const QString &status, const QString &server, const QString &exit) { QString tmpstatus = status.lower().stripWhiteSpace(); circuitItem* circuitline; if ((circuitline = (circuitItem*)circuitList->findItem(circuitID,0)) == 0){ circuitline = new circuitItem(circuitList, circuitID, "",server); circuitline->setDragEnabled(true); circuitline->setDropEnabled(true); }else{ circuitline->setText(2,server); } for( uint index = 0; index < circuitIconList.count(); index++ ) { if ( circuitIconList[index].contains(tmpstatus)) { circuitline->setPixmap(1,QPixmap(SmallIcon("tork_"+circuitIconList[index].first()))); continue; } } if (tmpstatus.contains("closed") || tmpstatus.contains("failed")){ delete circuitline; circuitExits.erase(circuitID); }else if (!exit.isEmpty()){ QListViewItem* serverline; if ((serverline = (QListViewItem*) serverList->findItem(exit,2)) != 0){ circuitExits[circuitID] = serverline; } } } void torkView::ORStatusUpdated(const QString &ORID, const QString &status) { QString tmpstatus = status.lower().stripWhiteSpace(); QListViewItem* ORline = ORList->findItem(ORID,1); if (ORline == 0) ORline = new QListViewItem(ORList, "", ORID); if (tmpstatus.contains("closed") || tmpstatus.contains("failed")){ delete ORline; if (entryGuards[ORID]) entryGuards.remove(ORID); return; } if (entryGuards[ORID]){ guardStatusUpdated(ORID, status); return; } for( uint index = 0; index < iconList.count(); index++ ) { if ( iconList[index].contains(tmpstatus)) { ORline->setPixmap(0,QPixmap(SmallIcon("tork_"+iconList[index].first()))); return; } } } void torkView::guardStatusUpdated(const QString &ORID, const QString &status) { entryGuards[ORID] = status; QString tmpstatus = status.lower().stripWhiteSpace(); QListViewItem* ORline = ORList->findItem(ORID,1); if (ORline == 0) ORline = new QListViewItem(ORList, "", ORID); for( uint index = 0; index < iconList.count(); index++ ) { if ( guardIconList[index].contains(tmpstatus)) { ORline->setPixmap(0,QPixmap(SmallIcon("tork_guard_"+guardIconList[index].first()))); return; } } } void torkView::infoUpdated(const QString &type, const QString &summary, const QString &) { static int id = 0; uint total = 0; for( uint index = 0; index < summary.length(); index += 120) { total++; } uint count = 1; QString tmpid; for( uint index = 0; index < summary.length(); index += 120) { id++; tmpid = QString("00000000000%1").arg(id).right(10); new QListViewItem(infoList, QDateTime::currentDateTime ().toString(Qt::ISODate).replace("T"," "), tmpid, type, QString("(%1 of %2) %3").arg(count) .arg(total) .arg(summary.mid(index,120))); count++; } } void torkView::bwUpdated(const QString &in, const QString &out) { static time_t time_of_last_bw = time(NULL); static time_t time_of_last_cg = time(NULL); //static time_t time_of_last_tn = time(NULL); static time_t time_of_last_cbws = time(NULL); time_t now = time(NULL); //Tor Tx/Rx torbtx += out.toInt(); torbrx += in.toInt(); if (time_of_last_bw + MAX_BW_RATE <= now){ int secs = now - time_of_last_bw; time_of_last_bw = now; reportBW(secs); } if (time_of_last_cg + MAX_CG_RATE < now){ emit signalCheckGuards(); time_of_last_cg = now; } // if (time_of_last_tn + MAX_TN_RATE < now){ // emit signalCheckTorNet(); // time_of_last_tn = now; // } if (time_of_last_cbws + MAX_CBWS_RATE < now){ emit signalCheckBWSettings(); time_of_last_cbws = now; } } QPixmap torkView::streamProgram(const QString &program) { QString prog = KGlobal::iconLoader()->iconPath(program, KIcon::Small, true); if (prog.isEmpty()) return SmallIcon( "exec" ); else return SmallIcon( program ); } void torkView::streamBwUpdated(const QString &stream, const QString &in, const QString &out) { //Tor Tx/Rx streamBwIn[stream] += in.toInt(); streamBwOut[stream] += out.toInt(); } void torkView::reportBW(int secs) { if ((streamList->childCount() == 0) && m_osd->isShown()) m_osd->hide(); //Calculate Streams Tx/Rx for ( QMap::Iterator stream = streams.begin(); stream != streams.end(); ++stream ) { if (stream.data()){ stream.data()->calcBWRate(streamBwIn[stream.key().latin1()], streamBwOut[stream.key().latin1()], secs); QString sbw = BytesPerSecToString( stream.data()->mSpeedHistoryRx[stream.data()->mSpeedHistoryPtr] + stream.data()->mSpeedHistoryTx[stream.data()->mSpeedHistoryPtr],0); //Overlay here // QPixmap icon = stream.data()->pixmap(3); // QPixmap pm(*(stream.data()->pixmap(3))); // QPainter p; // p.begin(&pm); // // p.drawText(stream.data()->pixmap(3)->rect(),Qt::AlignCenter,sbw); // p.end(); // stream.data()->setPixmap(3,pm); stream.data()->setText(4,sbw); QListViewItem* osdstreamline = osdstreams[stream.data()->text(0)]; osdstreamline->setText(3,sbw); } } //Calculate System Tx/Rx unsigned int sysbrx = 0; unsigned int sysbtx = 0; for ( QStringList::Iterator it = mSysDevPathList.begin(); it != mSysDevPathList.end(); ++it ) { if ((*it).isEmpty()) continue; sysbrx += readInterfaceNumValue((*it),"rx_bytes"); sysbtx += readInterfaceNumValue((*it),"tx_bytes"); } //Calculate Tor Tx/Rx unsigned int btx = (torbtx - mBTx); unsigned int brx = (torbrx - mBRx); mBRx = torbrx; mBTx = torbtx; //Calculate Tor Tx/Rx if (++mSpeedBufferPtr >= SPEED_BUFFER_SIZE) mSpeedBufferPtr = 0; mSpeedBufferTx[mSpeedBufferPtr] = ((btx )*(1000.0f/(secs * 1000))); mSpeedBufferRx[mSpeedBufferPtr] = ((brx )*(1000.0f/(secs * 1000))); if (++mSpeedHistoryPtr >= HISTORY_SIZE) mSpeedHistoryPtr = 0; mSpeedHistoryRx[mSpeedHistoryPtr] = calcSpeed(mSpeedBufferRx); mSpeedHistoryTx[mSpeedHistoryPtr] = calcSpeed(mSpeedBufferTx); mMaxSpeedAge--; if (mSpeedHistoryTx[mSpeedHistoryPtr] > mMaxSpeed) { mMaxSpeed = mSpeedHistoryTx[mSpeedHistoryPtr]; mMaxSpeedAge = HISTORY_SIZE; } if (mSpeedHistoryRx[mSpeedHistoryPtr] > mMaxSpeed) { mMaxSpeed = mSpeedHistoryRx[mSpeedHistoryPtr]; mMaxSpeedAge = HISTORY_SIZE; } if (mMaxSpeedAge < 1) calcMaxSpeed(); //Calculate Sys Tx/Rx if (!mFirstUpdate) { // a primeira velocidade sempre eh absurda, para evitar isso temos o mFirstUpdate if (++sys_mSpeedBufferPtr >= SPEED_BUFFER_SIZE) sys_mSpeedBufferPtr = 0; sys_mSpeedBufferTx[sys_mSpeedBufferPtr] = ((sysbtx - sysmBTx)*(1000.0f/(secs * 1000))); sys_mSpeedBufferRx[sys_mSpeedBufferPtr] = ((sysbrx - sysmBRx)*(1000.0f/(secs * 1000))); if (++sys_mSpeedHistoryPtr >= HISTORY_SIZE) sys_mSpeedHistoryPtr = 0; sys_mSpeedHistoryRx[sys_mSpeedHistoryPtr] = calcSpeed(sys_mSpeedBufferRx); sys_mSpeedHistoryTx[sys_mSpeedHistoryPtr] = calcSpeed(sys_mSpeedBufferTx); sys_mMaxSpeedAge--; if (sys_mSpeedHistoryTx[sys_mSpeedHistoryPtr] > sys_mMaxSpeed) { sys_mMaxSpeed = sys_mSpeedHistoryTx[sys_mSpeedHistoryPtr]; sys_mMaxSpeedAge = HISTORY_SIZE; } if (sys_mSpeedHistoryRx[sys_mSpeedHistoryPtr] > sys_mMaxSpeed) { sys_mMaxSpeed = sys_mSpeedHistoryRx[sys_mSpeedHistoryPtr]; sys_mMaxSpeedAge = HISTORY_SIZE; } if (sys_mMaxSpeedAge < 1) sys_calcMaxSpeed(); } mFirstUpdate = false; sysmBRx = sysbrx; sysmBTx = sysbtx; //Update Main Graphs emit updateStats(); //Update ChartBar in OSD float bitRateIn = brx;// * 8.0 / (secondselapsed / 1000.0); float bitRateOut = btx;// * 8.0 / (secondselapsed / 1000.0); int8_t upperIn = (int8_t) (100.0 * bitRateIn /mMaxSpeed); if (upperIn < 0) upperIn = 0; else if (upperIn > 100) upperIn = 100; int8_t upperOut = (int8_t) (100.0 * bitRateOut / mMaxSpeed ); if (upperOut < 0) upperOut = 0; else if (upperOut > 100) upperOut = 100; QString kbsrx = BytesPerSecToString(mSpeedHistoryRx[mSpeedHistoryPtr]); QString kbstx = BytesPerSecToString(mSpeedHistoryTx[mSpeedHistoryPtr]); m_osd->m_graphIn->addPercentReading(upperIn, false); m_osd->m_graphOut->addPercentReading(upperOut, false); m_osd->m_graphIn->setLabel(QString("Dn: %1") .arg(kbsrx)); m_osd->m_graphOut->setLabel(QString("Up: %1") .arg(kbstx)); // Update Tray and StatusBar emit updateTrayStats(BytesToString(mBRx), BytesToString(mBTx), kbsrx, kbstx); } unsigned long torkView::readInterfaceNumValue(QString interface, const char* name) { // stdio functions appear to be more fast than QFile? FILE* fp = fopen((interface+"/statistics/"+name).latin1(), "r"); if (!fp) return 0; long retval; fscanf(fp, "%lu", &retval); fclose(fp); return retval; } void torkView::activeServersUpdated( const QStringList &servers) { QListViewItem* tm; QStringList tmpservers = servers; for ( QStringList::Iterator it = tmpservers.begin(); it != tmpservers.end(); ++it ) { if ((*it).isEmpty()) continue; if ( (tm = serverList->findItem((*it),1)) > 0){ tm->setPixmap(0,QPixmap(SmallIcon("tork_green"))); }else{ tm = new QListViewItem(serverList, (*it)); tm->setPixmap(0,QPixmap(SmallIcon("tork_green"))); } } } void torkView::serverStatusUpdated(const QString &ip,const QString &fp, const QString &server, const QString &statuses) { QListViewItem* tm; if (!(tm = torservers[fp])){ tm = new QListViewItem(serverList, "", (server), fp, statuses); torservers[fp] = tm; } QString cc; int country_id = 0; 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){ country_id = GeoIP_id_by_name(gi, ip); cc = GeoIP_country_code[country_id]; GeoIP_delete(gi); if (!m_countryList.contains(country_id)) m_countryList << country_id; }else cc = "--"; QString ccode = QString("%1").arg(country_id); tm->setText(4,ccode); tm->setText(5,ip); /* QRegExp rx("^[0-9]{1,3}\\."); rx.search(ip); QString tmp = rx.cap(0); if (!m_subnet16List.contains(tmp)) m_subnet16List << tmp; */ if (cc == "--") tm->setPixmap(1,QPixmap(SmallIcon("help"))); else tm->setPixmap(1,QPixmap(SmallIcon("tork_" + cc.lower()))); QString icontouse; if ((statuses.contains("Stable")) && (statuses.contains("Running")) && (statuses.contains("Fast"))) icontouse = "tork_green"; else if ((statuses.contains("Fast")) && (statuses.contains("Running"))) icontouse = "tork_yellow"; else if ((statuses.contains("Running")) && (statuses.contains("Stable"))) icontouse = "tork_orange"; else if ((statuses.contains("Running"))) icontouse = "tork_little"; else // if ((statuses.contains("Valid"))) icontouse = "tork_red"; if ((statuses.contains("Exit"))) icontouse += "_exit"; // Update Exclude Nodes if Country is Excluded and this server is new to us if (TorkConfig::excludeCountries().contains(ccode)){ if (!TorkConfig::excludeServersHistory().contains(QString("%1-%2-%3") .arg(ccode).arg(fp).arg(server))){ QStringList existingServers = TorkConfig::excludeServersHistory(); existingServers.append(QString("%1-%2-%3").arg(ccode).arg(fp).arg(server)); TorkConfig::setExcludeServersHistory(existingServers); QStringList permList; permList = TorkConfig::excludeNodes(); QString node = "$"+getFPFromFPDigest(fp); permList.append(node); } } tm->setPixmap(0,QPixmap(SmallIcon(icontouse))); } void torkView::switchColors() { // switch the foreground/background colors of the label /* QColor color = Settings::col_background(); Settings::setCol_background( Settings::col_foreground() ); Settings::setCol_foreground( color ); */ settingsChanged(); } void torkView::settingsChanged() { /* sillyLabel->setPaletteBackgroundColor( Settings::col_background() ); sillyLabel->setPaletteForegroundColor( Settings::col_foreground() ); // i18n : internationalization sillyLabel->setText( i18n("This project is %1 days old").arg(Settings::val_time()) ); emit signalChangeStatusbar( i18n("Settings changed") );*/ } void torkView::displayError( const QString &caption, const QString &infol) { if (!circuitList->recentDropEvent()) return; QString info = infol;; info.replace(QRegExp("(\\$[A-Z0-9]{40})(~|=)"),""); delete m_pop; KPassivePopup* pop; QPoint pnt; if (kmain->isActiveWindow()){ pop = new KPassivePopup( kmain ); pnt = kmain->pos() += kmain->m_view->pos() += kmain->m_view->circuitList->pos() += kmain->m_view->circuitList->getMousePos() += kmain->m_view->splitter3->pos() += kmain->m_view->splitter4->pos() += kmain->m_view->groupBox1->pos(); }else{ pop = new KPassivePopup( kmain->_tray ); pnt = kmain->_tray->pos(); } pop->setView( caption,info ); pop->show(QPoint(pnt)); m_pop = pop; } void torkView::displayServer( const QString &caption, const QString &info) { KPassivePopup* pop; QPoint pnt; if (kmain->isActiveWindow()){ pop = new KPassivePopup( serverList ); //pnt = kmain->pos() -= kmain->m_view->serverList->getMousePos() -= kmain->m_view->serverList->getMousePos() -= kmain->m_view->serverList->getMousePos(); }else{ pop = new KPassivePopup( kmain->_tray ); pnt = kmain->_tray->pos(); } pop->setView( caption,info ); //pop->show(QPoint(pnt)); pop->show(); } void torkView::showServerBW(const QString &fp ) { QString fl; QString tmpFile; fl = QString("http://www.noreply.org/tor-running-routers/%1/node-traf-%2.png") .arg(fp.left(2)).arg(fp); KIO::NetAccess::download( fl, tmpFile, 0L ); kapp->processEvents(); streamList-> setPaletteBackgroundPixmap( QPixmap(tmpFile) ); } void torkView::hidePopup( ) { delete m_pop; } void torkView::populateMenu() { Anonymizer->clear(); QFont font; //Welcome welcomeitem = new HitWidget(QString::null, QString::null); welcomeheaderLabel = new QLabel(welcomeitem); welcomeheaderLabel->setText(i18n("Press 'Play' to get started!")); font.setBold( true ); welcomeheaderLabel->setFont( font ); welcomeitem->insertHeaderWidget(0,welcomeheaderLabel); welcomeitem->setIcon("tork_pressplay"); welcomeitem->setDescriptionText(""+i18n("- Press 'Play' to connect to Tor. (You can also use the toolbar icons.)")+""); // item->icon->setURL("konqueror"); welcomeitem->setPropertiesText(""+i18n( "- The 'Tor Network' tab shows you the state of the Tor network, including your Tor Traffic.
" "- You can use the 'Traffic Log' tab to view Tor and Non-Tor Traffic on your system.
" "- You can use the 'Tor Log' tab to view warning messages from Tor itself.
" "- Once Tor is up and running you can use the services listed below.
" )+"
"); KURLLabel *buttonStart = new KURLLabel(welcomeitem); buttonStart->setPixmap(SmallIcon("info")); welcomeitem->insertHitWidget(0,buttonStart); connect(buttonStart, SIGNAL(leftClickedURL()), SIGNAL(aboutTor())); buttonStart = new KURLLabel(welcomeitem); buttonStart->setText(i18n("What You Need To Know When Using TorK!")); welcomeitem->insertHitWidget(1,buttonStart); connect(buttonStart, SIGNAL(leftClickedURL()), SIGNAL(aboutTor())); paranoidmodeicon = new KURLLabel(welcomeitem); welcomeitem->insertHitWidget(2,paranoidmodeicon); connect(paranoidmodeicon, SIGNAL(leftClickedURL()), SIGNAL(aboutParanoidMode())); paranoidmodetext = new KURLLabel(welcomeitem); welcomeitem->insertHitWidget(3,paranoidmodetext); connect(paranoidmodetext, SIGNAL(leftClickedURL()), SIGNAL(aboutParanoidMode())); paranoidmodeicon->setPixmap(SmallIcon("tork_penguin")); paranoidmodetext->setText(i18n("In Normal mode!")); QStringList qconf; qconf << "Clnt/Exit" << "Clnt/Relay" << "Exit" << "Relay" << "Client" << "Custom" << "Remote" << "Local"; welcomeitem->score->setHidden(false); welcomeitem->score->insertStringList(qconf); welcomeitem->score->setPalette(QPalette(Qt::white,Qt::white)); welcomeitem->score->setCurrentItem(TorkConfig::quickConfigure()); connect(welcomeitem->score, SIGNAL(activated(int)), SLOT(changeQuickConfigure(int))); Anonymizer->insertItem(welcomeitem); connect(welcomeitem->icon, SIGNAL(leftClickedURL()), SIGNAL(startEverything())); QLabel *headerLabel; //Firefox firefoxitem = 0L; #ifndef LIVECD if (TorkConfig::availablePrograms().contains("firefox")){ firefoxitem = new HitWidget(QString::null, QString::null); headerLabel = new QLabel(firefoxitem); headerLabel->setText(i18n("Anonymous Browsing (with Firefox)")); font.setBold( true ); headerLabel->setFont( font ); firefoxitem->insertHeaderWidget(0,headerLabel); firefoxitem->setIcon("tork_firefox"); firefoxitem->setDescriptionText(""+i18n("Click the icon to launch an anonymous browsing session in Firefox.
" )+"
"); firefoxitem->setPropertiesText(""+i18n( "- TorK will make a copy of your normal Firefox settings and modify them for anonymous browsing.
" "- Firefox will use Privoxy in combination with Tor to anonymize your browsing.
" "- No other Firefox sessions will be anonymous!
" )+"
"); firefoxitem->icon->setURL("firefox"); //QComboBox* countries = new QComboBox( FALSE, "this" ); //firefoxitem->insertWidget(1,countries); buttonStart = new KURLLabel(firefoxitem); buttonStart->setPixmap(SmallIcon("info")); firefoxitem->insertHitWidget(0,buttonStart); connect(buttonStart, SIGNAL(leftClickedURL()), SLOT(downloadTorButton())); buttonStart = new KURLLabel(firefoxitem); buttonStart->setText(i18n("Install TorButton First (Recommended)")); firefoxitem->insertHitWidget(1,buttonStart); connect(buttonStart, SIGNAL(leftClickedURL()), SLOT(downloadTorButton())); Anonymizer->insertItem(firefoxitem); connect(firefoxitem->icon, SIGNAL(leftClickedURL()), SLOT(anonymousFirefox())); } //Kopete #endif //Anonymous Mail mixminionitem = new HitWidget(QString::null, QString::null); headerLabel = new QLabel(mixminionitem); headerLabel->setText(i18n("Anonymous Email")); font.setBold( true ); headerLabel->setFont( font ); mixminionitem->insertHeaderWidget(0,headerLabel); mixminionitem->setIcon("tork_mail"); mixminionitem->setDescriptionText(""+i18n("Click the icon to compose and send an anonymous email.
" )+"
"); mixminionitem->setPropertiesText(""+i18n( "- The email will be routed through the anonymizing mixminion network.
" "- Delivery of anonymous email can take a while, sometimes up to 24 hours!
" "- If you don't have mixminion already, click the link below to install it.
" "- Visit the mixminion homepage to find out more.
" )+"
"); // QStringList qconf; // qconf << "Simple" << "KMail"; // // QFont f( sshitem->score->font().rawName(), // sshitem->score->font().pointSize() - 1 ); // mixminionitem->score->setFont( f ); // mixminionitem->score->setHidden(false); // mixminionitem->score->insertStringList(shellsAvailable); // mixminionitem->score->setPalette(QPalette(Qt::white,Qt::white)); // connect(mixminionitem->score, SIGNAL(activated(int)),mixminionitem, // SLOT(changeTerminalUrl(int))); buttonStart = new KURLLabel(mixminionitem); buttonStart->setPixmap(SmallIcon("info")); mixminionitem->insertHitWidget(0,buttonStart); connect(buttonStart, SIGNAL(leftClickedURL()), SLOT(downloadMixminion())); buttonStart = new KURLLabel(mixminionitem); buttonStart->setText(i18n("Install Mixminion")); mixminionitem->insertHitWidget(1,buttonStart); connect(buttonStart, SIGNAL(leftClickedURL()), SLOT(downloadMixminion())); buttonStart = new KURLLabel(mixminionitem); buttonStart->setPixmap(SmallIcon("konqueror")); mixminionitem->insertHitWidget(2,buttonStart); connect(buttonStart, SIGNAL(leftClickedURL()), SIGNAL(mixminionHome())); buttonStart = new KURLLabel(mixminionitem); buttonStart->setText(i18n("Visit the Mixminion Project page.")); mixminionitem->insertHitWidget(3,buttonStart); connect(buttonStart, SIGNAL(leftClickedURL()), SIGNAL(mixminionHome())); Anonymizer->insertItem(mixminionitem); connect(mixminionitem->icon, SIGNAL(leftClickedURL()), SLOT(sendAnonymousEmail())); konqitem=0L; //Konqueror #ifndef LIVECD if (TorkConfig::availablePrograms().contains("konqueror")){ konqitem = new HitWidget(QString::null, QString::null); headerLabel = new QLabel(konqitem); headerLabel->setText(i18n("Anonymous Browsing (with Konqueror)")); font.setBold( true ); headerLabel->setFont( font ); konqitem->insertHeaderWidget(0,headerLabel); konqitem->setIcon("tork_konqueror_play"); if (TorkConfig::kDEUsesTor()) konqitem->icon->pixmap()->fill(Qt::red); konqitem->setDescriptionText(""+i18n("Click the icon to launch an anonymous browsing session.
" )+"
"); konqitem->setPropertiesText(""+i18n( "- This will also make any other Konqueror sessions you use anonymous.
" "- Konqueror windows that have anonymous browsing enabled are a funny green colour.
" "- Konqueror uses Privoxy in combination with Tor to anonymize your browsing.
" "- You can toggle this setting at any time using the Konqueror icon in the toolbar or the miniview.
" )+"
"); konqitem->icon->setURL("konqueror"); buttonStart = new KURLLabel(konqitem); buttonStart->setPixmap(SmallIcon("configure")); konqitem->insertHitWidget(0,buttonStart); connect(buttonStart, SIGNAL(leftClickedURL()), SIGNAL(showMyKonqueror())); buttonStart = new KURLLabel(konqitem); buttonStart->setText(i18n("Configure Anonymous Konqueror")); konqitem->insertHitWidget(1,buttonStart); connect(buttonStart, SIGNAL(leftClickedURL()), SIGNAL(showMyKonqueror())); configurePriv = new KURLLabel(konqitem); configurePriv->setPixmap(SmallIcon("configure")); konqitem->insertHitWidget(2,configurePriv); connect(configurePriv, SIGNAL(leftClickedURL()), SIGNAL(configurePrivoxy())); configurePrivText = new KURLLabel(konqitem); configurePrivText->setText(i18n("Configure Privoxy")); konqitem->insertHitWidget(3,configurePrivText); connect(configurePrivText, SIGNAL(leftClickedURL()), SIGNAL(configurePrivoxy())); Anonymizer->insertItem(konqitem); connect(konqitem->icon, SIGNAL(leftClickedURL()), SIGNAL(konqWithTor())); } #endif operaitem = 0L; #ifndef LIVECD if (TorkConfig::availablePrograms().contains("opera")){ operaitem = new HitWidget(QString::null, QString::null); headerLabel = new QLabel(operaitem); headerLabel->setText(i18n("Anonymous Browsing (with Opera)")); font.setBold( true ); headerLabel->setFont( font ); operaitem->insertHeaderWidget(0,headerLabel); operaitem->setIcon("tork_opera"); operaitem->setDescriptionText(""+i18n("Click the icon to launch an anonymous browsing session in Opera.
" )+"
"); operaitem->setPropertiesText(""+i18n( "- TorK will make a copy of your normal Opera settings and modify them for anonymous browsing.
" "- Opera will use Privoxy in combination with Tor to anonymize your browsing.
" "- No other Opera sessions will be anonymous!
" )+"
"); operaitem->icon->setURL("opera"); Anonymizer->insertItem(operaitem); connect(operaitem->icon, SIGNAL(leftClickedURL(const QString&)), SLOT(anonymizedOpera(const QString&))); } #endif hiddenservicesitem = 0L; //Hidden Services hiddenservicesitem = new HitWidget(QString::null, QString::null); headerLabel = new QLabel(hiddenservicesitem); headerLabel->setText(i18n("Anonymous Websites and Web Services")); font.setBold( true ); headerLabel->setFont( font ); hiddenservicesitem->insertHeaderWidget(0,headerLabel); hiddenservicesitem->setIcon("tork_agent"); hiddenservicesitem->setDescriptionText(""+i18n("Click the icon to create an anonymous web site or manage existing ones.
" )+"
"); setHiddenServicesText(); buttonStart = new KURLLabel(hiddenservicesitem); buttonStart->setPixmap(SmallIcon("konqueror")); hiddenservicesitem->insertHitWidget(0,buttonStart); connect(buttonStart, SIGNAL(leftClickedURL()), SIGNAL(hiddenServices())); buttonStart = new KURLLabel(hiddenservicesitem); buttonStart->setText(i18n("Search Hidden Services")); hiddenservicesitem->insertHitWidget(1,buttonStart); connect(buttonStart, SIGNAL(leftClickedURL()), SIGNAL(hiddenServices())); Anonymizer->insertItem(hiddenservicesitem); connect(hiddenservicesitem->icon, SIGNAL(leftClickedURL()), SIGNAL(showMyHiddenServices())); //Kopete kopeteitem = 0L; #ifndef LIVECD if (TorkConfig::availablePrograms().contains("kopete")){ kopeteitem = new HitWidget(QString::null, QString::null); headerLabel = new QLabel(kopeteitem); headerLabel->setText(i18n("Anonymous Instant Messaging/IRC (with Kopete)")); font.setBold( true ); headerLabel->setFont( font ); kopeteitem->insertHeaderWidget(0,headerLabel); kopeteitem->setIcon("kopete"); kopeteitem->setDescriptionText(""+i18n(" Click to start an anonymized Kopete session.
" )+"
"); kopeteitem->setPropertiesText(""+i18n( "- You won't be anonymous if you use your real name!
" )+"
"); kopeteitem->icon->setURL("kopete --caption 'Anonymous IM Session - Launched From TorK'"); Anonymizer->insertItem(kopeteitem); connect(kopeteitem->icon, SIGNAL(leftClickedURL(const QString&)), SLOT(torify(const QString&))); } #endif //Gaim gaimitem = 0L; #ifndef LIVECD if (TorkConfig::availablePrograms().contains("gaim")){ gaimitem = new HitWidget(QString::null, QString::null); headerLabel = new QLabel(gaimitem); headerLabel->setText(i18n("Anonymous Instant Messaging/IRC (with Gaim)")); font.setBold( true ); headerLabel->setFont( font ); gaimitem->insertHeaderWidget(0,headerLabel); gaimitem->setIcon("gaim"); gaimitem->setDescriptionText(""+i18n(" Click to start an anonymized Gaim session.
" )+"
"); gaimitem->setPropertiesText(""+i18n( "- You won't be anonymous if you use your real name!
" )+"
"); gaimitem->icon->setURL("gaim"); Anonymizer->insertItem(gaimitem); connect(gaimitem->icon, SIGNAL(leftClickedURL(const QString&)), SLOT(torify(const QString&))); } #endif //Pidgin pidginitem = 0L; #ifndef LIVECD if (TorkConfig::availablePrograms().contains("pidgin")){ pidginitem = new HitWidget(QString::null, QString::null); headerLabel = new QLabel(pidginitem); headerLabel->setText(i18n("Anonymous Instant Messaging/IRC (with Pidgin)")); font.setBold( true ); headerLabel->setFont( font ); pidginitem->insertHeaderWidget(0,headerLabel); pidginitem->setIcon("pidgin"); pidginitem->setDescriptionText(""+i18n(" Click to start an anonymized Pidgin session.
" )+"
"); pidginitem->setPropertiesText(""+i18n( "- You won't be anonymous if you use your real name!
" )+"
"); pidginitem->icon->setURL("pidgin"); Anonymizer->insertItem(pidginitem); connect(pidginitem->icon, SIGNAL(leftClickedURL(const QString&)), SLOT(torify(const QString&))); } #endif //Gaim konversationitem = 0L; #ifndef LIVECD if (TorkConfig::availablePrograms().contains("konversation")){ konversationitem = new HitWidget(QString::null, QString::null); headerLabel = new QLabel(konversationitem); headerLabel->setText(i18n("Anonymous Instant Messaging/IRC (with Konversation)")); font.setBold( true ); headerLabel->setFont( font ); konversationitem->insertHeaderWidget(0,headerLabel); konversationitem->setIcon("konversation"); konversationitem->setDescriptionText(""+i18n(" Click to start an anonymized Konversation session.
" )+"
"); konversationitem->setPropertiesText(""+i18n( "- You won't be anonymous if you use your real name!
" )+"
"); konversationitem->icon->setURL("konversation"); Anonymizer->insertItem(konversationitem); connect(konversationitem->icon, SIGNAL(leftClickedURL(const QString&)), SLOT(torify(const QString&))); } #endif //KSIRC ksircitem =0L; #ifndef LIVECD if (TorkConfig::availablePrograms().contains("ksirc")){ ksircitem = new HitWidget(QString::null, QString::null); headerLabel = new QLabel(ksircitem); headerLabel->setText(i18n("Anonymous IRC (with KSirc)")); font.setBold( true ); headerLabel->setFont( font ); ksircitem->insertHeaderWidget(0,headerLabel); ksircitem->setIcon("ksirc"); ksircitem->setDescriptionText(""+i18n(" Click to start an anonymous KSirc IRC session.
" )+"
"); ksircitem->setPropertiesText(""+i18n( "- Leaking DNS requests is not fatal but something to keep an eye on. Use the traffic-log.
" )+"
"); ksircitem->icon->setURL("ksirc --caption 'Anonymous IRC Shell - Launched From TorK'"); Anonymizer->insertItem(ksircitem); connect(ksircitem->icon, SIGNAL(leftClickedURL(const QString&)), SLOT(torify(const QString&))); } #endif //SSH QStringList shellCandidates; QStringList shellsAvailable; shellCandidates << "konsole" << "yakuake" << "xterm" << "rxvt" << "gnome-terminal"; for ( QStringList::Iterator it = shellCandidates.begin(); it != shellCandidates.end(); it++ ) { if (TorkConfig::availablePrograms().contains(*it)) shellsAvailable << (*it); } QStringList hkpShellsAvailable = shellsAvailable; if (TorkConfig::availablePrograms().contains("x3270")) shellsAvailable << "x3270"; sshitem = 0L; #ifndef LIVECD if (!shellsAvailable.isEmpty()){ sshitem = new HitWidget(QString::null, QString::null); headerLabel = new QLabel(sshitem); headerLabel->setText(i18n("Anonymous SSH Session")); font.setBold( true ); headerLabel->setFont( font ); sshitem->insertHeaderWidget(0,headerLabel); sshitem->setIcon("tork_konsolessh"); sshitem->setDescriptionText(""+i18n("Click the icon to start a Konsole terminal session.
" )+"
"); sshitem->setPropertiesText(""+i18n( "- Use ssh within the session to connect securely and anonymously. " "e.g. ssh shell.sf.net
" "- Use the traffic-log tab to ensure you are not leaking DNS requests.
" )+"
"); sshitem->icon->setURL("konsole --caption 'Anonymous SSH Shell - Launched From TorK'"); buttonStart = new KURLLabel(sshitem); buttonStart->setPixmap(SmallIcon("help")); sshitem->insertHitWidget(0,buttonStart); connect(buttonStart, SIGNAL(leftClickedURL()), SIGNAL(aboutTorify())); buttonStart = new KURLLabel(sshitem); buttonStart->setText(i18n("How can I be sure this is working?")); sshitem->insertHitWidget(1,buttonStart); connect(buttonStart, SIGNAL(leftClickedURL()), SIGNAL(aboutTorify())); sshitem->shellTitles["konsole"] = " --caption 'Anonymous SSH Shell - Launched From TorK'"; sshitem->shellTitles["yakuake"] = " --caption 'Anonymous SSH Shell - Launched From TorK'"; sshitem->shellTitles["xterm"] = " -title 'Anonymous SSH Shell - Launched From TorK'"; sshitem->shellTitles["rxvt"] = " -title 'Anonymous SSH Shell - Launched From TorK'"; sshitem->shellTitles["gnome-terminal"] = " --title 'Anonymous SSH Shell - Launched From TorK'"; QFont f( sshitem->score->font().rawName(), sshitem->score->font().pointSize() - 1 ); sshitem->score->setFont( f ); sshitem->score->setHidden(false); sshitem->score->insertStringList(shellsAvailable); sshitem->score->setPalette(QPalette(Qt::white,Qt::white)); connect(sshitem->score, SIGNAL(activated(int)),sshitem, SLOT(changeTerminalUrl(int))); Anonymizer->insertItem(sshitem); connect(sshitem->icon, SIGNAL(leftClickedURL(const QString&)), SLOT(torify(const QString&))); } #endif //Telnet telnetitem =0L; #ifndef LIVECD if (!shellsAvailable.isEmpty()){ telnetitem = new HitWidget(QString::null, QString::null); headerLabel = new QLabel(telnetitem); headerLabel->setText(i18n("Anonymous Telnet Session")); font.setBold( true ); headerLabel->setFont( font ); telnetitem->insertHeaderWidget(0,headerLabel); telnetitem->setIcon("tork_konsole"); telnetitem->setDescriptionText(""+i18n(" This will start a Konsole terminal session.
" )+"
"); telnetitem->setPropertiesText(""+i18n( "- Use telnet within the session to connect anonymously. " "e.g. telnet shell.sf.net 23
" "- Telnet passwords are sent in clear-text - so do be careful 007!.
" )+"
"); telnetitem->icon->setURL("konsole --caption 'Anonymous Telnet Session - Launched From TorK'"); buttonStart = new KURLLabel(telnetitem); buttonStart->setPixmap(SmallIcon("help")); telnetitem->insertHitWidget(0,buttonStart); connect(buttonStart, SIGNAL(leftClickedURL()), SIGNAL(riskySession())); buttonStart = new KURLLabel(telnetitem); buttonStart->setText(i18n("Why is anonymous telnet risky?")); telnetitem->insertHitWidget(1,buttonStart); connect(buttonStart, SIGNAL(leftClickedURL()), SIGNAL(riskySession())); telnetitem->shellTitles["konsole"] = " --caption 'Anonymous Telnet Session - Launched From TorK'"; telnetitem->shellTitles["yakuake"] = " --caption 'Anonymous Telnet Session - Launched From TorK'"; telnetitem->shellTitles["xterm"] = " -title 'Anonymous Telnet Session - Launched From TorK'"; telnetitem->shellTitles["rxvt"] = " -title 'Anonymous Telnet Session - Launched From TorK'"; telnetitem->shellTitles["gnome-terminal"] = " --title 'Anonymous Telnet Session - Launched From TorK'"; QFont f( telnetitem->score->font().rawName(), telnetitem->score->font().pointSize() - 1 ); telnetitem->score->setFont( f ); telnetitem->score->setHidden(false); telnetitem->score->insertStringList(shellsAvailable); telnetitem->score->setPalette(QPalette(Qt::white,Qt::white)); connect(telnetitem->score, SIGNAL(activated(int)),telnetitem, SLOT(changeTerminalUrl(int))); Anonymizer->insertItem(telnetitem); connect(telnetitem->icon, SIGNAL(leftClickedURL(const QString&)), SLOT(torify(const QString&))); } //GPG #endif gpgitem = 0L; #ifndef LIVECD if ((TorkConfig::availablePrograms().contains("gpg")) && !shellsAvailable.isEmpty()){ gpgitem = new HitWidget(QString::null, QString::null); headerLabel = new QLabel(gpgitem); headerLabel->setText(i18n("Anonymously Refresh GPG Keys")); font.setBold( true ); headerLabel->setFont( font ); gpgitem->insertHeaderWidget(0,headerLabel); gpgitem->setIcon("tork_kgpg"); gpgitem->setDescriptionText(""+i18n("This will refresh your GPG keys anonymously.
" "
")); gpgitem->setPropertiesText(""+i18n( "- To use the hidden service for GPG keys, add these lines to %1/.gnupg/gpg.conf:
" "     keyserver x-hkp://yod73zr3y6wnm2sw.onion
" "     keyserver x-hkp://d3ettcpzlta6azsm.onion
" "
").arg(getenv("HOME"))); gpgitem->icon->setURL("konsole --caption 'Anonymous GPG Keys Refresh - Launched From TorK' --noclose -e gpg --refresh-keys"); gpgitem->shellTitles["konsole"] = " --caption 'Anonymous GPG Keys Refresh - Launched From TorK' --noclose -e gpg --refresh-keys"; gpgitem->shellTitles["yakuake"] = " --caption 'Anonymous GPG Keys Refresh - Launched From TorK' --noclose -e gpg --refresh-keys"; gpgitem->shellTitles["xterm"] = " -title 'Anonymous GPG Keys Refresh - Launched From TorK' -e gpg --refresh-keys"; gpgitem->shellTitles["rxvt"] = " -title 'Anonymous GPG Keys Refresh - Launched From TorK' -e gpg --refresh-keys"; gpgitem->shellTitles["gnome-terminal"] = " --title 'Anonymous GPG Keys Refresh - Launched From TorK' -e gpg --refresh-keys"; QFont f( gpgitem->score->font().rawName(), gpgitem->score->font().pointSize() - 1 ); gpgitem->score->setFont( f ); gpgitem->score->setHidden(false); gpgitem->score->insertStringList(hkpShellsAvailable); gpgitem->score->setPalette(QPalette(Qt::white,Qt::white)); connect(gpgitem->score, SIGNAL(activated(int)),gpgitem, SLOT(changeTerminalUrl(int))); Anonymizer->insertItem(gpgitem); connect(gpgitem->icon, SIGNAL(leftClickedURL(const QString&)), SLOT(torify(const QString&))); } #endif //All Purpose Shell allpurposeitem = 0L; #ifndef LIVECD if (!shellsAvailable.isEmpty()){ allpurposeitem = new HitWidget(QString::null, QString::null); headerLabel = new QLabel(allpurposeitem); headerLabel->setText(i18n("Anonymous Shell for Command-Line Programs using HTTP/HTTPS")); font.setBold( true ); headerLabel->setFont( font ); allpurposeitem->insertHeaderWidget(0,headerLabel); allpurposeitem->setIcon("tork_konsole"); allpurposeitem->setDescriptionText(""+i18n("Click to start a Konsole session.
" )+"
"); allpurposeitem->setDescriptionText(""+i18n("- Your http(s) requests will be routed through a privacy proxy and Tor.
" "- Suitable for such programs as wget, slapt-get and lynx.
" )+"
"); // QFont f( allpurposeitem->score->font().rawName(), 8 ); // allpurposeitem->score->setFont( f ); // allpurposeitem->score->setHidden(false); // allpurposeitem->score->insertStringList(shellsAvailable); // allpurposeitem->score->setPalette(QPalette(Qt::white,Qt::white)); Anonymizer->insertItem(allpurposeitem); connect(allpurposeitem->icon, SIGNAL(leftClickedURL()), SLOT(privoxiedBash())); } #endif } circuitItem::circuitItem( DndListView *parent, const QString &id, const QString &status, const QString &server ) : QListViewItem( parent, id, status, server) { } streamItem::streamItem( DndListView *parent, const QString &id, const QString &program, const QString &target, const QString &status, const QString &bw, const QString &exit, const QString &circuit ) : QListViewItem( parent, id, program, target, status, bw, exit, circuit) { /* setDragEnabled(true); setDropEnabled(true);*/ memset(mSpeedHistoryRx, 0, sizeof(double)*HISTORY_SIZE); memset(mSpeedHistoryTx, 0, sizeof(double)*HISTORY_SIZE); memset(mSpeedBufferRx, 0, sizeof(double)*SPEED_BUFFER_SIZE); memset(mSpeedBufferTx, 0, sizeof(double)*SPEED_BUFFER_SIZE); mMaxSpeedAge = 0; mMaxSpeed = 0.0; mSpeedBufferPtr = mSpeedHistoryPtr = 0; mBRx = mBTx = 0; } #include "torkview.moc"