Commit 738248c8 authored by Matt Edman's avatar Matt Edman
Browse files

r2049@adrastea: edmanm | 2007-08-23 19:31:23 -0400

 If cookie authentication is selected, explicitly disable password
 authentication when starting Tor (and vice versa). Otherwise, Tor would die
 with "Cannot set both HashedControlPassword and CookieAuthentication" if the
 user started Tor with one method, changed some settings and did a SAVECONF,
 then started Tor with a different authentication method. Also, change how we
 pass arguments to QProcess::start() so we can actually do
 'HashedControlPassword ""' without Qt foiling my plans.


svn:r1864
parent ba978712
Loading
Loading
Loading
Loading
+26 −34
Changes for src/config/torsettings.cpp: 26 added lines, 34 removed lines.
Original line number Diff line number Diff line
@@ -114,65 +114,57 @@ TorSettings::setExecutable(QString torExecutable)
  setValue(SETTING_TOR_EXECUTABLE, torExecutable);
}

/** Formats the argument name <b>name</b> with the given value <b>value</b>.
 * If <b>value</b> contains a space, <b>value</b> will be wrapped in quotes. */
QString
TorSettings::formatArgument(QString name, QString value)
{
  if (value.indexOf(" ") >= 0) {
    value = "\"" + value + "\"";
  }
  return name + " " + value;
}

/** Returns a formatted QString of all currently set command-line arguments.
 * If an argument's value contains a space, then it will be wrapped in quotes.
 * */
QString
QStringList
TorSettings::getArguments()
{
  QString args;
  QStringList args;

  /* Add the torrc argument (if specified) */
  QString torrc = getTorrc();
  if (!torrc.isEmpty()) {
    args += formatArgument(TOR_ARG_TORRC, 
                           expand_filename(torrc)) + " ";
  }
  if (!torrc.isEmpty())
    args << TOR_ARG_TORRC << expand_filename(torrc);
  
  /* Specify the location to use for Tor's data directory, if different from
   * the default. */
  QString dataDirectory = getDataDirectory();
  if (!dataDirectory.isEmpty()) {
    args += formatArgument(TOR_ARG_DATA_DIRECTORY,
                           expand_filename(dataDirectory)) + " ";
  }
  if (!dataDirectory.isEmpty())
    args << TOR_ARG_DATA_DIRECTORY << expand_filename(dataDirectory);
  
  /* Add the ControlPort value */
  quint16 controlPort = getControlPort();
  if (controlPort) {
    args += formatArgument(TOR_ARG_CONTROL_PORT, 
                           QString::number(controlPort)) + " ";
  }
  if (controlPort)
    args << TOR_ARG_CONTROL_PORT << QString::number(controlPort);

  /* Add the control port authentication argument */
  AuthenticationMethod authMethod = getAuthenticationMethod();
  if (authMethod == PasswordAuth) {
    if (useRandomPassword())
      setControlPassword(generateRandomPassword());
    
    QString password = getControlPassword();
    args += formatArgument(TOR_ARG_HASHED_PASSWORD,
                           hashPassword(password)) + " ";
    args << TOR_ARG_HASHED_PASSWORD << hashPassword(password);
    args << TOR_ARG_COOKIE_AUTH << "0";
  } else if (authMethod == CookieAuth) {
    args += formatArgument(TOR_ARG_COOKIE_AUTH, "1") + " ";
    args << TOR_ARG_COOKIE_AUTH << "1";
    args << TOR_ARG_HASHED_PASSWORD << "";
  } else {
    args << TOR_ARG_COOKIE_AUTH << "0";
    args << TOR_ARG_HASHED_PASSWORD << "";
  }
  
  /* Add the User argument (if specified) */
  QString user = getUser();
  if (!user.isEmpty()) {
    args += formatArgument(TOR_ARG_USER, user) + " ";
  }
  if (!user.isEmpty())
    args << TOR_ARG_USER << user;
    
  /* Add the Group argument (if specified) */
  QString group = getGroup();
  if (!group.isEmpty()) {
    args += formatArgument(TOR_ARG_GROUP, group);
  }
  if (!group.isEmpty())
    args << TOR_ARG_GROUP << group;
  
  return args;
}

+1 −4
Changes for src/config/torsettings.h: 1 added line, 4 removed lines.
Original line number Diff line number Diff line
@@ -59,7 +59,7 @@ public:
  void setDataDirectory(QString dataDir);
  
  /** Builds and formats a list of command-line arguments. */
  QString getArguments();
  QStringList getArguments();
  
  /** Gets the torrc to use when starting Tor. */
  QString getTorrc();
@@ -106,9 +106,6 @@ public:
  void setGroup(QString group);

private:
  /** Formats the argument name <b>name</b> with the given value <b>value</b>.
   * If <b>value</b> contains a space, <b>value</b> will be wrapped in quotes. */
  QString formatArgument(QString name, QString value);
  /** Returns the string description of the authentication method specified by
   * <b>method</b>. The authentication method string is stored in  Vidalia's
   * configuration file. */
+15 −4
Changes for src/control/torprocess.cpp: 15 added lines, 4 removed lines.
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@

#include <QString>
#include <vidalia.h>
#include <util/string.h>

/* Needed for _PROCESS_INFORMATION so that pid() works on Win32 */
#if defined (Q_OS_WIN32)
@@ -46,19 +47,29 @@ TorProcess::TorProcess()
          this,   SLOT(onError(QProcess::ProcessError)));
}

/** Formats the Tor process arguments for logging. */
QString
TorProcess::formatArguments(const QStringList args)
{
  QStringList out;
  foreach (QString arg, args) {
    out << (arg.contains(" ") || arg.isEmpty() ? string_escape(arg) : arg);
  }
  return out.join(" ");
}

/** Attempts to start the Tor process using the location, executable, and
 * command-line arguments specified in Vidalia's settings. If Tor starts, the
 * signal started() will be emitted. If Tor fails to start,
 * startFailed(errmsg) will be emitted, with an appropriate error message. */
void
TorProcess::start(QString app, QString args) 
TorProcess::start(QString app, QStringList args) 
{
#if defined(Q_OS_WIN32)
  /* If we're on Windows, QProcess::start requires that paths with spaces are
   * quoted before being passed to it. */
  app = "\"" + app + "\"";
#endif
  app = app + " " + args;
  
  /* Attempt to start Tor with the given command-line arguments */
  QStringList env = QProcess::systemEnvironment();
@@ -74,8 +85,8 @@ TorProcess::start(QString app, QString args)
#endif
  setEnvironment(env);

  vNotice("Starting Tor using '%1'").arg(app);
  QProcess::start(app, QIODevice::ReadOnly | QIODevice::Text);
  vNotice("Starting Tor using '%1 %2'").arg(app).arg(formatArguments(args));
  QProcess::start(app, args, QIODevice::ReadOnly | QIODevice::Text);
}

/** Stops the Tor process */
+5 −1
Changes for src/control/torprocess.h: 5 added lines, 1 removed line.
Original line number Diff line number Diff line
@@ -40,7 +40,7 @@ public:
  TorProcess();

  /** Start the Tor process */
  void start(QString app, QString args);
  void start(QString app, QStringList args);
  /** Stop the Tor process */
  bool stop(QString *errmsg = 0);

@@ -64,6 +64,10 @@ private slots:
  void onReadyRead();
  /** Called when an error occurs in the process. */
  void onError(QProcess::ProcessError error);

private:
  /** Formats the Tor process arguments for logging. */
  QString formatArguments(const QStringList args);
};

#endif