/*************************************************************************** ** $Id: newfirstrunwizard.ui.h,v 1.29 2008/12/08 19:39:02 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 "torkconfig.h" #include "update.h" #include "crypto.h" #include "torclient.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "functions.h" TorClient* client; KProcIO *whichproc; bool torRunning; bool privoxyRunning; QString tor; QString privoxy; QString netstat; QString torknetstat; QString OriginalHttpProxy; QString OriginalHttpsProxy; QString OriginalFtpProxy; QString OriginalProxyType; QString KonqHttpProxy; QString KonqHttpsProxy; QString KonqFtpProxy; uint KonqHttpProxyPort; uint KonqHttpsProxyPort; uint KonqFtpProxyPort; QString OriginalCookies; QString OriginalUseCache; QString OriginalSendUserAgent; QString OriginalEnableJavascript; QString OriginalEnableJava; QString OriginalEnablePlugins; QValueVector descriptions(6); void FirstRunWizard::init() { torRunning = false; privoxyRunning = false; descriptions[0] = i18n("This will run a client and an exit server with Tor's default settings.
" "An exit server carries the can for traffic leaving the Tor network."); descriptions[1] = i18n("This will run a client and a relay server with Tor's default settings.
" "A relay server carries traffic along the Tor network but does not transmit" "tor traffic outside the network."); descriptions[2] = i18n("This will run an exit server with Tor's default settings.
" "An exit server carries the can for traffic leaving the Tor network."); descriptions[3] = i18n("This will run a relay server with Tor's default settings.
" "A relay server carries traffic along the Tor network but does not transmit" "tor traffic outside the network."); descriptions[4] = i18n("This will run a client with Tor's default settings.
"); descriptions[5] = i18n("You're too clever for your own good.
"); settingsDescription->setText(descriptions[0]); setAppropriate ( CheckNotUsing, false ); setAppropriate ( CheckUsing, false ); setAppropriate ( NonPrivoxyConfirmation, false ); setAppropriate ( Remote_Tor, false ); setAppropriate ( Locate_Tor, false ); setAppropriate ( Locate_Privoxy, false ); setNextEnabled ( Locate_Tor,false ); setAppropriate ( TorServer, false ); TorkConfig::setUser(getenv("USER")); const char *paths = ":/usr/local/sbin:/usr/sbin:/sbin:/usr/local/bin:/usr/bin:/bin"; privoxy = getFullLocation(paths,"privoxy"); tor = getFullLocation(paths,"tor"); netstat = getFullLocation(paths,"netstat"); if (!tor) setAppropriate ( Locate_Tor, true ); else TorLocation_2->setURL(tor); if (!privoxy){ setAppropriate ( Locate_Privoxy, true ); whichProxyText->setText(i18n("I did not find an installation of Privoxy on your system.")); }else{ PrivoxyLocation_2->setURL(privoxy); whichProxyText->setText(i18n("I found an installation of Privoxy on your system.")); } serverName->setText("TorKServer"); KConfig emailConf( QString::fromLatin1("emaildefaults") ); emailConf.setGroup(QString::fromLatin1("Defaults")); QString profile = QString::fromLatin1("PROFILE_"); profile += emailConf.readEntry(QString::fromLatin1("Profile"), QString::fromLatin1("Default")); emailConf.setGroup(profile); contactMail->setText(emailConf.readEntry(QString::fromLatin1("EmailAddress"))); guessDataDir(); //aesthetics cancelButton()->setFixedSize( cancelButton()->sizeHint() ); helpButton()->hide(); whichproc = new KProcIO(); whichproc->setUseShell(TRUE); QString whichCommand="ps -C tor;ps -C privoxy"; *whichproc<start(KProcIO::NotifyOnExit,TRUE); } void FirstRunWizard::monitorRemote_toggled( bool remoteTor) { if ((!tor) && (!remoteTor)) setAppropriate ( Locate_Tor, true ); else setAppropriate ( Locate_Tor, false ); setAppropriate ( HowDoesTorStart, !remoteTor ); setAppropriate ( TorUsage, !remoteTor ); setAppropriate ( TorServer, !remoteTor ); setAppropriate ( Remote_Tor, remoteTor ); setAppropriate ( TestingTor, remoteTor ); } void FirstRunWizard::usingAnotherProxy_toggled( bool state) { setAppropriate ( CheckNotUsing, state ); setAppropriate ( CheckUsing, state ); setAppropriate ( NonPrivoxyConfirmation, state ); setAppropriate ( PrivoxyConfirmation, !state ); if ((!privoxy) && (!state)) setAppropriate ( Locate_Privoxy, !state ); setAppropriate ( HowDoesPrivoxyStart, !state ); setAppropriate ( PrivoxyConfiguration, !state ); setAppropriate ( FinalPrivoxy, !state ); } void FirstRunWizard::torStartsAutomatically_toggled( bool state) { setAppropriate ( TorUsage, !state ); setAppropriate ( TorServer, !state ); setAppropriate ( TestingTor , state ); } void FirstRunWizard::torStartsManually_toggled( bool state) { setAppropriate ( TorUsage, state ); setAppropriate ( TorServer, state ); setAppropriate ( TestingTor , !state ); } void FirstRunWizard::processWhich(KProcIO *whichproc) { QString item = ""; int pos; while ((pos = (whichproc->readln(item,true))) != -1) { if (item.find("tor") != -1) torRunning = true; if (item.find("privoxy") != -1) privoxyRunning = true; } whichproc->ackRead(); } void FirstRunWizard::showPage( QWidget *w ) //virtual { QWizard::showPage( w ); if (currentPage() == HowDoesTorStart){ torStartsAutomatically->setChecked(torRunning); torStartsManually->setChecked(!torRunning); } if (currentPage() == LocalOrRemote){ torStartsAutomatically->setChecked(false); torStartsManually->setChecked(false); } if (currentPage() == HowDoesPrivoxyStart){ privoxyStartsAutomatically->setChecked(privoxyRunning); privoxyStartsManually->setChecked(!privoxyRunning); if (privoxyRunning){ privoxyText->setText(i18n("

To be honest, I'm not that bright." "It looks as if Privoxy is configured to start up by itself when " "your computer boots up, but I can't be sure. So can you help me?" "Does Privoxy start by itself at boot-time?

")); }else{ privoxyText->setText(i18n("

To be honest, I'm not that bright." "It looks as if Privoxy does not start up by itself when " "your computer boots up, but I can't be sure. So can you help me?" "Does Privoxy start by itself at boot-time?

")); } } if (currentPage() == CheckUsing){ saveAnonymousProxySettings(); } if (currentPage() == TestingTor){ testTor(); } if (currentPage() == NonPrivoxyConfirmation){ saveNonAnonymousProxySettings(); } if (currentPage() == PrivoxyConfirmation){ saveNonAnonymousProxySettings(); } setFinishEnabled ( Final,true ); // cancelButton()->setText( w == WizardPage_0 ? i18n("&Skip") : i18n("&Cancel") ); } void FirstRunWizard::downloadPrivoxy_clicked() { TorkUpdate* updater = new TorkUpdate(this); updater->checkForNewPrivoxyDirectly(); } void FirstRunWizard::downloadTor_clicked() { TorkUpdate* updater = new TorkUpdate(this); updater->checkForNewTorDirectly(false); } void FirstRunWizard::accept() { QString paths; paths = ":/usr/local/sbin:/usr/sbin:/sbin:/usr/local/bin:/usr/bin:/bin"; paths.replace("::",":"); torknetstat = getFullLocation(paths,"torknetstat");; if (torknetstat) TorkConfig::setNetstatLocation("torknetstat"); else TorkConfig::setNetstatLocation("netstat"); if (torStartsAutomatically->isChecked()) TorkConfig::setQuickConfigure(7); else if (monitorRemote->isChecked()) TorkConfig::setQuickConfigure(6); else TorkConfig::setQuickConfigure(WizardQuickConfigure->currentItem()); TorkConfig::setTorLocation(TorLocation_2->url()); TorkConfig::setPrivoxyLocation(PrivoxyLocation_2->url()); TorkConfig::setNickName(serverName->text()); TorkConfig::setContactInfo(contactMail->text()); if (monitorRemote->isChecked()){ TorkConfig::setRemoteTorAddress(RemoteTorAddress->text()); TorkConfig::setRemoteTorPort(RemoteTorPort->text().toInt()); } if ((usingAnotherProxy->isChecked()) || (privoxyStartsAutomatically->isChecked())){ TorkConfig::setSystemProxy(true); TorkConfig::setTorkProxy(false); }else{ TorkConfig::setSystemProxy(false); TorkConfig::setTorkProxy(true); } //Non-Anon Proxy Settings TorkConfig::setOriginalHttpProxy(OriginalHttpProxy); TorkConfig::setOriginalHttpsProxy(OriginalHttpsProxy); TorkConfig::setOriginalProxyType(OriginalProxyType); TorkConfig::setOriginalCookies(OriginalCookies); TorkConfig::setOriginalUseCache(OriginalUseCache); TorkConfig::setOriginalSendUserAgent(OriginalSendUserAgent); TorkConfig::setOriginalEnableJavascript(OriginalEnableJavascript); TorkConfig::setOriginalEnableJava(OriginalEnableJava); TorkConfig::setOriginalEnablePlugins(OriginalEnablePlugins); //Anon Proxy Settings TorkConfig::setKonqHttpProxy(KonqHttpProxy); TorkConfig::setKonqHttpProxyPort(KonqHttpProxyPort); TorkConfig::setKonqHttpsProxy(KonqHttpsProxy); TorkConfig::setKonqHttpsProxyPort(KonqHttpsProxyPort); TorkConfig::setKonqFtpProxy(KonqFtpProxy); TorkConfig::setKonqFtpProxyPort(KonqFtpProxyPort); if (!usingAnotherProxy->isChecked()){ TorkConfig::setKonqHttpProxy("http://localhost"); TorkConfig::setKonqHttpProxyPort(8118); TorkConfig::setKonqHttpsProxy("http://localhost"); TorkConfig::setKonqHttpsProxyPort(8118); } TorkConfig::writeConfig(); QDialog::accept(); } void FirstRunWizard::reject() { QDialog::reject(); } void FirstRunWizard::WizardQuickConfigure_activated( int item) { if (item == 4) setAppropriate ( TorServer, false ); else setAppropriate ( TorServer, true ); settingsDescription->setText(descriptions[item]); } void FirstRunWizard::saveNonAnonymousProxySettings() { KConfig* config = new KConfig("kioslaverc", false, false); config->setGroup( "Proxy Settings" ); OriginalHttpProxy = config->readEntry( "httpProxy" ); OriginalHttpsProxy = config->readEntry( "httpsProxy" ); OriginalProxyType = config->readEntry( "ProxyType" ); config = new KConfig("kcookiejarrc", false, false); config->setGroup( "Cookie Policy" ); OriginalCookies = config->readEntry( "Cookies" ); config = new KConfig("kio_httprc", false, false); OriginalUseCache = config->readEntry( "UseCache" ); OriginalSendUserAgent = config->readEntry( "SendUserAgent" ); config = new KConfig("konquerorrc", false, false); config->setGroup( "Java/JavaScript Settings" ); OriginalEnableJavascript = config->readEntry( "EnableJavaScript" ); OriginalEnableJava = config->readEntry( "EnableJava" ); OriginalEnablePlugins = config->readEntry( "EnablePlugins" ); if (currentPage() == PrivoxyConfirmation){ KonqHttpProxy = "http://localhost"; KonqHttpProxyPort = 8118; KonqHttpsProxy = "http://localhost"; KonqHttpsProxyPort = 8118; KonqFtpProxy = "http://localhost"; KonqFtpProxyPort = 8118; } } void FirstRunWizard::saveAnonymousProxySettings() { KConfig* config = new KConfig("kioslaverc", false, false); config->setGroup( "Proxy Settings" ); KonqHttpProxy = config->readEntry( "httpProxy" ).section(":",0,1); KonqHttpProxyPort = config->readEntry( "httpProxy" ).section(":",-1,-1).toInt(); KonqHttpsProxy = config->readEntry( "httpsProxy" ).section(":",0,1); KonqHttpsProxyPort = config->readEntry( "httpsProxy" ).section(":",-1,-1).toInt(); KonqFtpProxy = config->readEntry( "ftpProxy" ).section(":",0,1); KonqFtpProxyPort = config->readEntry( "ftpProxy" ).section(":",-1,-1).toInt(); } void FirstRunWizard::TorLocation_textChanged( const QString & text) { if (text.contains("tor")) setNextEnabled ( Locate_Tor,true ); } void FirstRunWizard::pushButton1_clicked() { KRun::runCommand( "kcmshell proxy" ); } void FirstRunWizard::pushButton1_2_clicked() { KRun::runCommand( "kcmshell proxy" ); } void FirstRunWizard::pushButton1_3_clicked() { KRun::runCommand( "kcmshell proxy" ); } void FirstRunWizard::testTorAgain_clicked() { testTor(); } void FirstRunWizard::testTor() { kdDebug() << "testing tor" << endl; QString host; int port; if (monitorRemote->isChecked()){ host = RemoteTorAddress->text(); port = RemoteTorPort->text().toInt(); TorkConfig::setCookieAuthentication(false); }else{ host = "localhost"; port = TorkConfig::controlPort(); TorkConfig::setCookieAuthentication(false); } if (!TorPassword->text().isEmpty() && TorPassword->isEnabled()) TorkConfig::setHashedControlPassword(TorPassword->text()); if (client) delete client; client = new TorClient(host,port); connect( client, SIGNAL(fatalError()),this, SLOT(cannotContactTor())); connect( client, SIGNAL(authenticationFailed()),this, SLOT(cannotContactTor())); connect( client, SIGNAL(authenticated()),this, SLOT(contactedTor()) ); client->authenticate(); } void FirstRunWizard::modifyConfs_clicked() { examineConfigFiles(); } void FirstRunWizard::cannotContactTor() { disconnect( client, SIGNAL(fatalError()),this, SLOT(cannotContactTor())); disconnect( client, SIGNAL(authenticationFailed()),this, SLOT(cannotContactTor())); disconnect( client, SIGNAL(authenticated()),this, SLOT(contactedTor()) ); if (client != 0L){ client->socketReadyRead(); client->deleteLater(); client = 0L; } if (monitorRemote->isChecked()){ torControlStatus->setText(i18n("

I can't contact or authenticate to Tor.
" "This means you will need to modify Tor's settings if it is to be usable by Tork in future.

" "On the machine that your remote Tor installation runs on add the following to Tor's config file:
" "
" "ControlPort %2
" "
" "Alternatively, you may have entered the wrong password in the previous page.
" "When you've attempted to fix the problem, click 'Test Tor' to try connecting again.") .arg(RemoteTorPort->text())); }else{ torControlStatus->setText(i18n("

I can't contact or authenticate to Tor.
" "This means Tork will need to modify Tor's settings if it is to be usable by Tork in future.

" "To the right is a list of the possible files that Tor may be using for it's configuration.
" "If you click the 'Modify Tor's Control File' button, I'll modify any that exist to make Tor controllable by TorK.
" "Once that's done you can click 'Test Tor' to re-test the connection.")); modifyConfigs->setEnabled(true); } testTorAgain->setEnabled(true); } void FirstRunWizard::contactedTor() { disconnect( client, SIGNAL(fatalError()),this, SLOT(cannotContactTor())); disconnect( client, SIGNAL(authenticated()),this, SLOT(contactedTor()) ); if (client != 0L){ client->socketReadyRead(); client->deleteLater(); client = 0L; } if (!monitorRemote->isChecked()) torControlStatus->setText(i18n("

I contacted Tor successfully.
" "This means TorK can contact and control Tor. That's a good thing.
" "By default, TorK will secure its session with Tor using a random " "password. However, you should consider using a security option on " "Tor that will secure it even when you're not using TorK.
" "See the 'My Tor Client' configuration section for more info" " when you're finished the wizard.
" "You can now click 'Next'.")); else torControlStatus->setText(i18n("

I contacted Tor successfully.
" "This means TorK can contact and control Tor. That's a good thing. " "As a security precaution, you should configure your remote instance " "of Tor to require a password. You can inform TorK of the password " "using the 'My Tor Client' configuration section. " )); modifyConfigs->setEnabled(false); testTorAgain->setEnabled(true); TorkConfig::setGenerateRandomPassword(true); // if (!monitorRemote->isChecked()) // QTimer::singleShot( 3000, this, SLOT(examineConfigFiles()) ); } void FirstRunWizard::examineConfigFiles() { bool foundone = false; for (unsigned int index = 0; index != configCandidates->count(); ++index){ if (QFile::exists(configCandidates->item(index)->text())) { appendControlDirective(configCandidates->item(index)->text()); foundone = true; } } if (!foundone){ appendControlDirective("/usr/local/etc/tor/torrc"); appendControlDirective("/etc/tor/torrc"); appendControlDirective("/usr/etc/tor/torrc"); torControlStatus->setText(i18n("

OK, I didn't find any of the config files in the list.
" "To make tor usable I'm creating config files in three locations: /usr/local/etc/tor/torrc, /usr/etc/tor/torrc and /etc/tor/torrc." "I've also asked Tor to reload and it will catch and use one of these files. " " You'll be asked for your root password in a moment. " " This is to modify the file and necessary to get Tor working. " "When you've entered your password " "click 'Test Tor' to see if it worked. ")); } } void FirstRunWizard::pushButton6_clicked() { rootifyNetstat(); } void FirstRunWizard::rootifyNetstat() { QString newnetstat = QString(netstat).replace("netstat","torknetstat"); KProcIO *catproc = new KProcIO(); catproc->setUseShell(TRUE); QString whichCommand= QString("kdesu -t -c 'cp %1 %2;chmod u+s %3'").arg(netstat).arg(newnetstat).arg(newnetstat); *catproc<start(KProcIO::NotifyOnExit,TRUE); } void FirstRunWizard::sighupTor(const QString& text) { KProcIO *catproc = new KProcIO(); catproc->setUseShell(TRUE); QString whichCommand= QString("killall -s HUP %1").arg(text); *catproc<start(KProcIO::NotifyOnExit,TRUE); } void FirstRunWizard::appendControlDirective(const QString& text) { int result = KMessageBox::questionYesNo(this, i18n( "

I'm going to modify the Tor configuration file: %1.
" "This is so that I can ensure" "TorK can communicate with Tor.
" " If you say Yes, I may have to ask for your root password.").arg(text)); switch (result) { case KMessageBox::No : return; } QFile inf(text); if ( inf.open(IO_WriteOnly | IO_Append) ) { QTextStream ts( &inf ); ts << "ControlPort 9051" << "\n"; inf.close(); sighupTor("tor"); }else{ QString directory = KURL(text).directory(); KProcIO *catproc = new KProcIO(); catproc->setUseShell(TRUE); QString whichCommand= QString("kdesu -c \"sh -c 'mkdir -p %1;printf \\\"ControlPort 9051\\n\\\"" " >> %2;killall -s HUP tor'\"").arg(directory).arg(text); *catproc<start(KProcIO::NotifyOnExit,TRUE); //-c "sh -c 'printf \"ControlPort 9051\n\" >> /etc/tor/torrc'" } } void FirstRunWizard::guessDataDir( ) { QStringList dataDirCands; dataDirCands << QString("%1/.tor/").arg(getenv("HOME")); dataDirCands << QString("/var/lib/tor/"); for ( QStringList::Iterator it = dataDirCands.begin(); it != dataDirCands.end(); ++it ) { QDir inf((*it)); if ( inf.exists() ) { TorkConfig::setDataDirectory((*it)); return; } } } void FirstRunWizard::RemoteTorAddress_textChanged( const QString & text) { if ((text == "127.0.0.1") || (text == "localhost")) TorPassword->setEnabled(false); else TorPassword->setEnabled(true); } void FirstRunWizard::modifyConfPrivoxy_clicked() { examinePrivoxyConfigFiles(); } void FirstRunWizard::examinePrivoxyConfigFiles() { bool foundone = false; for (unsigned int index = 0; index != configCandidatesPrivoxy->count(); ++index){ if (QFile::exists(configCandidatesPrivoxy->item(index)->text())) { appendPrivoxyConfig(configCandidatesPrivoxy->item(index)->text()); foundone = true; } } if (!foundone){ appendPrivoxyConfig("/etc/privoxy/config"); privoxyStatus->setText(i18n("

OK, I didn't find any of the config files in the list.
" "Tork has created a basic config in /etc/privoxy/config." "This may get things working, but possibly not.
" "You should:" "- Check Privoxy is properly installed." "- Re-install privoxy and try running the wizard again." )); } } void FirstRunWizard::appendPrivoxyConfig(const QString& text) { QString privoxyConf = QString( "confdir %1\\n" "logdir .\\n" "listen-address %2:%3\\n" "debug 1 # URLs\\n" "debug 4096 # Info\\n" "debug 8192 # Errors\\n" "toggle 1\\n" "buffer-limit 4069\\n" "forward 192.168.*.*/ .\\n" "forward 10.*.*.*/ .\\n" "forward 127.*.*.*/ .\\n" "forward-socks4a / %4:%5 .\\n") .arg(locate("data","tork/privoxy/")) .arg(TorkConfig::konqHttpProxy().replace("http://","")) .arg(TorkConfig::konqHttpProxyPort()) .arg(TorkConfig::sOCKSBindAddressHost()) .arg(TorkConfig::sOCKSBindAddressPort()); int result = KMessageBox::questionYesNo(this, i18n( "

I'm going to modify the Privoxy configuration file: %1.
" "This is so that I can ensure" "Privoxy can communicate with Tor.
" " If you say Yes, I'll ask for your root password.").arg(text)); switch (result) { case KMessageBox::No : return; } QFile inf(text); if ( inf.open(IO_WriteOnly | IO_Append) ) { QTextStream ts( &inf ); ts << privoxyConf; inf.close(); sighupTor("privoxy"); }else{ KProcIO *catproc = new KProcIO(); catproc->setUseShell(TRUE); QString whichCommand= QString("kdesu -c \"sh -c 'printf \\\"%1\\\"" " >> %2;killall -s HUP privoxy'\"") .arg(privoxyConf) .arg(text); *catproc<start(KProcIO::NotifyOnExit,TRUE); } }