Vidalia  0.3.1
TorSettings.cpp
Go to the documentation of this file.
1 /*
2 ** This file is part of Vidalia, and is subject to the license terms in the
3 ** LICENSE file, found in the top level directory of this distribution. If you
4 ** did not receive the LICENSE file with this file, you may obtain it from the
5 ** Vidalia source package distributed by the Vidalia Project at
6 ** http://www.torproject.org/projects/vidalia.html. No part of Vidalia,
7 ** including this file, may be copied, modified, propagated, or distributed
8 ** except according to the terms described in the LICENSE file.
9 */
10 
11 /*
12 ** \file TorSettings.cpp
13 ** \brief Settings used for starting and running Tor
14 */
15 
16 #include "TorSettings.h"
17 #include "Vidalia.h"
18 #include "crypto.h"
19 #include "file.h"
20 #include "stringutil.h"
21 #if defined(Q_OS_WIN32)
22 #include "win32.h"
23 #include <QFileInfo>
24 #endif
25 
26 #include <QDir>
27 #include <QProcess>
28 
29 /* Tor Settings */
30 #define SETTING_TOR_EXECUTABLE "TorExecutable"
31 #define SETTING_TORRC "Torrc"
32 #define SETTING_CONTROL_ADDR "ControlAddr"
33 #define SETTING_CONTROL_PORT "ControlPort"
34 #define SETTING_SOCKET_PATH "ControlSocket"
35 #define SETTING_CONTROL_METHOD "ControlMethod"
36 #define SETTING_AUTH_TOKEN "AuthToken"
37 #define SETTING_TOR_USER "User"
38 #define SETTING_TOR_GROUP "Group"
39 #define SETTING_DATA_DIRECTORY "DataDirectory"
40 #define SETTING_AUTH_METHOD "AuthenticationMethod"
41 #define SETTING_CONTROL_PASSWORD "ControlPassword"
42 #define SETTING_USE_RANDOM_PASSWORD "UseRandomPassword"
43 #define SETTING_WARN_PLAINTEXT_PORTS "WarnPlaintextPorts"
44 #define SETTING_REJECT_PLAINTEXT_PORTS "RejectPlaintextPorts"
45 #define SETTING_BOOTSTRAP "Bootstrap"
46 #define SETTING_BOOTSTRAP_FROM "BootstrapFrom"
47 #define SETTING_AUTOCONTROL "AutoControl"
48 
49 /** Default to using hashed password authentication */
50 #define DEFAULT_AUTH_METHOD PasswordAuth
51 /** Default control method */
52 #define DEFAULT_CONTROL_METHOD "ControlPort"
53 /** Default socket path */
54 #define DEFAULT_SOCKET_PATH ""
55 
56 /* Arguments we can pass to Tor on the command-line */
57 #define TOR_ARG_CONTROL_PORT "ControlPort"
58 #define TOR_ARG_TORRC "-f"
59 #define TOR_ARG_DATA_DIRECTORY "DataDirectory"
60 #define TOR_ARG_HASHED_PASSWORD "HashedControlPassword"
61 #define TOR_ARG_COOKIE_AUTH "CookieAuthentication"
62 #define TOR_ARG_SOCKSPORT "SocksPort"
63 
64 /** Generate random control passwords of 16 characters */
65 #define PASSWORD_LEN 16
66 
67 
68 /** Default constructor */
70 : AbstractTorSettings("Tor", torControl)
71 {
72 #if defined(Q_OS_WIN32)
73  QString programFiles = win32_program_files_folder();
74  if (QFileInfo(programFiles + "\\Vidalia Bundle\\Tor\\tor.exe").exists())
76  programFiles + "\\Vidalia Bundle\\Tor\\tor.exe");
77  else
78  setDefault(SETTING_TOR_EXECUTABLE, programFiles + "\\Tor\\tor.exe");
79 #else
80  setDefault(SETTING_TOR_EXECUTABLE, "/usr/bin/tor");
81 #endif
82 
84  setDefault(SETTING_CONTROL_ADDR, "127.0.0.1");
89  setDefault(SETTING_DATA_DIRECTORY, "~/.vidalia");
92  setDefault(SETTING_WARN_PLAINTEXT_PORTS, QList<QVariant>() << 23 << 109
93  << 110 << 143);
94  setDefault(SETTING_REJECT_PLAINTEXT_PORTS, QList<QVariant>());
98 }
99 
100 /** Applies any changes to Tor's control port or authentication settings. */
101 bool
102 TorSettings::apply(QString *errmsg)
103 {
104  QHash<QString, QString> conf;
105  QString hashedPassword;
106 
107  conf.insert(SETTING_CONTROL_PORT,
109 
110  if(localValue(SETTING_AUTOCONTROL).toBool())
111  conf.insert(TOR_ARG_SOCKSPORT, "auto");
112  else
113  conf.insert(TOR_ARG_SOCKSPORT, "9050");
114 
115  AuthenticationMethod authMethod =
117  switch (authMethod) {
118  case CookieAuth:
119  conf.insert(TOR_ARG_COOKIE_AUTH, "1");
120  conf.insert(TOR_ARG_HASHED_PASSWORD, "");
121  break;
122  case PasswordAuth:
123  hashedPassword = useRandomPassword()
126  if (hashedPassword.isEmpty()) {
127  if (errmsg)
128  *errmsg = tr("Failed to hash the control password.");
129  return false;
130  }
131  conf.insert(TOR_ARG_COOKIE_AUTH, "0");
132  conf.insert(TOR_ARG_HASHED_PASSWORD, hashedPassword);
133  break;
134  default:
135  conf.insert(TOR_ARG_COOKIE_AUTH, "0");
136  conf.insert(TOR_ARG_HASHED_PASSWORD, "");
137  }
138 
139  conf.insert(SETTING_WARN_PLAINTEXT_PORTS,
140  localValue(SETTING_WARN_PLAINTEXT_PORTS).toStringList().join(","));
141  conf.insert(SETTING_REJECT_PLAINTEXT_PORTS,
142  localValue(SETTING_REJECT_PLAINTEXT_PORTS).toStringList().join(","));
143 
144  return torControl()->setConf(conf, errmsg);
145 }
146 
147 /** Gets the location of Tor's data directory. */
148 QString
150 {
151  return QDir::convertSeparators(value(SETTING_DATA_DIRECTORY).toString());
152 }
153 
154 /** Sets the location to use as Tor's data directory. */
155 void
156 TorSettings::setDataDirectory(const QString &dataDirectory)
157 {
158  setValue(SETTING_DATA_DIRECTORY, dataDirectory);
159 }
160 
161 /** Returns a fully-qualified path to Tor's executable, including the
162  * executable name. */
163 QString
165 {
166  QString tor = localValue(SETTING_TOR_EXECUTABLE).toString();
167  if (tor.isEmpty()) /* Don't let the Tor executable name be empty */
168  tor = defaultValue(SETTING_TOR_EXECUTABLE).toString();
169  return QDir::convertSeparators(tor);
170 }
171 
172 /** Sets the location and name of Tor's executable to the given string. */
173 void
174 TorSettings::setExecutable(const QString &torExecutable)
175 {
176  setValue(SETTING_TOR_EXECUTABLE, torExecutable);
177 }
178 
179 /** Returns the torrc that will be used when starting Tor. */
180 QString
182 {
183  QString torrc;
184  TorControl *tc = torControl();
185  if (tc && tc->isConnected() && tc->getInfo("config-file", torrc))
186  return QDir::convertSeparators(torrc);
187  return QDir::convertSeparators(localValue(SETTING_TORRC).toString());
188 }
189 
190 /** Sets the torrc that will be used when starting Tor.
191  * \param torrc The torrc to use.
192  */
193 void
194 TorSettings::setTorrc(const QString &torrc)
195 {
196  setValue(SETTING_TORRC, torrc);
197 }
198 
199 /** Get the address or hostname used to connect to Tor */
200 QHostAddress
202 {
203  QString addr = localValue(SETTING_CONTROL_ADDR).toString();
204  return QHostAddress(addr);
205 }
206 
207 /** Set the address or hostname used to connect to Tor */
208 void
209 TorSettings::setControlAddress(const QHostAddress &addr)
210 {
211  setValue(SETTING_CONTROL_ADDR, addr.toString());
212 }
213 
214 /** Get the control port used to connect to Tor */
215 quint16
217 {
218  return (quint16)value(SETTING_CONTROL_PORT).toInt();
219 }
220 
221 /** Set the control port used to connect to Tor */
222 void
224 {
226 }
227 
228 /** Get the path for ControlSocket */
229 QString
231 {
232  return value(SETTING_SOCKET_PATH).toString();
233 }
234 
235 /** Set the path for ControlSocket */
236 void
237 TorSettings::setSocketPath(const QString &path)
238 {
240 }
241 
242 /** Get the current control method */
245 {
247 }
248 
249 /** Set the control method */
250 void
252 {
254 }
255 
256 /** Returns the plaintext (i.e., not hashed) control password used when
257  * authenticating to Tor. */
258 QString
260 {
261  return localValue(SETTING_CONTROL_PASSWORD).toString();
262 }
263 
264 /** Sets the control password used when starting Tor with
265  * HashedControlPassword to <b>password</b>. */
266 void
267 TorSettings::setControlPassword(const QString &password)
268 {
270 }
271 
272 /** Returns true if a new, random control password is to be used each time Tor
273  * is started. */
274 bool
276 {
277  return localValue(SETTING_USE_RANDOM_PASSWORD).toBool();
278 }
279 
280 /** Sets whether or not to generate and use a random control password each
281  * time Tor is started. */
282 void
283 TorSettings::setUseRandomPassword(bool useRandomPassword)
284 {
286 }
287 
288 /** Returns the current authentication method used when connecting to Tor. */
291 {
293  TorControl *tc = torControl();
294 
295  if (tc && tc->isConnected()) {
296  QHash<QString,QString> conf;
297  conf.insert(TOR_ARG_COOKIE_AUTH, "");
298  conf.insert(TOR_ARG_HASHED_PASSWORD, "");
299  if (tc->getConf(conf)) {
300  if (conf.value(TOR_ARG_COOKIE_AUTH) == "1")
301  type = CookieAuth;
302  else if (!conf.value(TOR_ARG_HASHED_PASSWORD).isEmpty())
303  type = PasswordAuth;
304  }
305  }
306  if (type == UnknownAuth)
308  return (type == UnknownAuth ? DEFAULT_AUTH_METHOD : type);
309 }
310 
311 /** Sets the authentication method used when starting Tor to <b>method</b>. */
312 void
314 {
316 }
317 
318 /** Returns the current list of ports that will cause Tor to issue a warning
319  * when the user tries to connect to one of them. */
320 QList<quint16>
322 {
323  QList<quint16> out;
324  QList<QVariant> ports;
325 
326  ports = value(SETTING_WARN_PLAINTEXT_PORTS).toList();
327  foreach (QVariant port, ports) {
328  out << port.toUInt();
329  }
330  return out;
331 }
332 
333 /** Sets the list of ports that will cause Tor to issue a warning when the
334  * user tries to connect to one of them. */
335 void
336 TorSettings::setWarnPlaintextPorts(const QList<quint16> &ports)
337 {
338  QList<QVariant> warnList;
339  foreach (quint16 port, ports) {
340  warnList << QVariant(port);
341  }
343 }
344 
345 /** Returns the current list of ports that will cause Tor to reject the
346  * connection when the user tries to connect to one of them. */
347 QList<quint16>
349 {
350  QList<quint16> out;
351  QList<QVariant> ports;
352 
353  ports = value(SETTING_REJECT_PLAINTEXT_PORTS).toList();
354  foreach (QVariant port, ports) {
355  out << port.toUInt();
356  }
357  return out;
358 }
359 
360 /** Sets the list of ports that will cause Tor to reject the connection
361  * when the user tries to connect to one of them. */
362 void
363 TorSettings::setRejectPlaintextPorts(const QList<quint16> &ports)
364 {
365  QList<QVariant> rejectList;
366  foreach (quint16 port, ports) {
367  rejectList << QVariant(port);
368  }
370 }
371 
372 /** Returns the string description of the authentication method specified by
373  * <b>method</b>. The authentication method string is stored in Vidalia's
374  * configuration file. */
375 QString
377 {
378  switch (method) {
379  case NullAuth: return "none";
380  case PasswordAuth: return "password";
381  case CookieAuth: return "cookie";
382  default: break;
383  }
384  return "unknown";
385 }
386 
387 /** Returns the AuthenticationMethod enum value for the string
388  * description of the authentication method given in <b>authMethod</b>. */
390 TorSettings::toAuthenticationMethod(const QString &authMethod) const
391 {
392  QString str = authMethod.toLower();
393  if (str == toString(NullAuth))
394  return NullAuth;
395  else if (str == toString(PasswordAuth))
396  return PasswordAuth;
397  else if (str == toString(CookieAuth))
398  return CookieAuth;
399  return UnknownAuth;
400 }
401 
402 /** Generates a random control password consisting of PASSWORD_LEN characters. */
403 QString
405 {
407 }
408 
409 /** Returns the hash of <b>password</b> as given by the command "tor
410  * --hash-password foo". */
411 QString
412 TorSettings::hashPassword(const QString &password)
413 {
414  QByteArray salt;
415 
416  /* Generate an 8 octet salt value. Bail if we fail to generate enough
417  * random bytes (unlikely). */
418  while (salt.size() < 8) {
419  QByteArray bytes = crypto_rand_bytes(8-salt.size());
420  if (bytes.isNull())
421  return QString();
422  salt.append(bytes);
423  }
424 
425  /* Generate the salted hash of the specified password. 96 is the one-octet
426  * RFC 2440 coded count value hardcoded into Tor. Specifies that we should
427  * hash 64K worth of data. */
428  QByteArray key = crypto_secret_to_key(password, salt, 96);
429  if (key.isNull())
430  return QString();
431  salt.append(96); /* Append the coded count value to the salt */
432 
433  /* Convert the result to hexadecimal and put it in the format Tor wants. */
434  return QString("16:%1%2").arg(base16_encode(salt))
435  .arg(base16_encode(key));
436 }
437 
438 void
440 {
441  setValue(SETTING_BOOTSTRAP, enabled);
442 }
443 
444 bool
446 {
447  return value(SETTING_BOOTSTRAP).toBool();
448 }
449 
450 void
451 TorSettings::setBootstrapFrom(const QString &from)
452 {
454 }
455 
456 QString
458 {
459  return QDir::convertSeparators(value(SETTING_BOOTSTRAP_FROM).toString());
460 }
461 
462 bool
464 {
465  return value(SETTING_AUTOCONTROL).toBool();
466 }
467 
468 void
469 TorSettings::setAutoControlPort(const bool autoControl)
470 {
471  setValue(SETTING_AUTOCONTROL, autoControl);
472 }
TorSettings::UnknownAuth
@ UnknownAuth
Definition: TorSettings.h:36
AbstractTorSettings::localValue
virtual QVariant localValue(const QString &key) const
Definition: AbstractTorSettings.cpp:88
DEFAULT_SOCKET_PATH
#define DEFAULT_SOCKET_PATH
Definition: TorSettings.cpp:54
TOR_ARG_HASHED_PASSWORD
#define TOR_ARG_HASHED_PASSWORD
Definition: TorSettings.cpp:60
TorSettings::NullAuth
@ NullAuth
Definition: TorSettings.h:33
TorSettings::toString
QString toString(AuthenticationMethod type) const
Definition: TorSettings.cpp:376
TorSettings::setAutoControlPort
void setAutoControlPort(const bool autoControl)
Definition: TorSettings.cpp:469
PASSWORD_LEN
#define PASSWORD_LEN
Definition: TorSettings.cpp:65
TorSettings::setControlPort
void setControlPort(quint16 port)
Definition: TorSettings.cpp:223
win32.h
TorSettings::getDataDirectory
QString getDataDirectory() const
Definition: TorSettings.cpp:149
SETTING_CONTROL_PORT
#define SETTING_CONTROL_PORT
Definition: TorSettings.cpp:33
win32_program_files_folder
QString win32_program_files_folder()
Definition: win32.cpp:78
TorSettings::CookieAuth
@ CookieAuth
Definition: TorSettings.h:34
TorSettings::setControlMethod
void setControlMethod(ControlMethod::Method method)
Definition: TorSettings.cpp:251
TOR_ARG_SOCKSPORT
#define TOR_ARG_SOCKSPORT
Definition: TorSettings.cpp:62
TorControl
Definition: TorControl.h:49
TorSettings::randomPassword
static QString randomPassword()
Definition: TorSettings.cpp:404
TorSettings::bootstrapFrom
QString bootstrapFrom() const
Definition: TorSettings.cpp:457
SETTING_WARN_PLAINTEXT_PORTS
#define SETTING_WARN_PLAINTEXT_PORTS
Definition: TorSettings.cpp:43
TorSettings::getControlPassword
QString getControlPassword() const
Definition: TorSettings.cpp:259
QVariant
stop errmsg QVariant
Definition: TorControlPrototype.cpp:180
crypto_rand_string
QString crypto_rand_string(int len)
Definition: crypto.cpp:150
TorSettings::getControlMethod
ControlMethod::Method getControlMethod() const
Definition: TorSettings.cpp:244
Vidalia::dataDirectory
static QString dataDirectory()
Definition: Vidalia.cpp:355
crypto_rand_bytes
QByteArray crypto_rand_bytes(int len)
Definition: crypto.cpp:71
Vidalia.h
TorSettings::apply
bool apply(QString *errmsg=0)
Definition: TorSettings.cpp:102
VSettings::defaultValue
QVariant defaultValue(const QString &key) const
Definition: VSettings.cpp:79
TorSettings::getRejectPlaintextPorts
QList< quint16 > getRejectPlaintextPorts() const
Definition: TorSettings.cpp:348
SETTING_DATA_DIRECTORY
#define SETTING_DATA_DIRECTORY
Definition: TorSettings.cpp:39
ControlMethod::fromString
static Method fromString(QString method)
Definition: ControlMethod.cpp:36
TorSettings::setControlPassword
void setControlPassword(const QString &password)
Definition: TorSettings.cpp:267
TorSettings::autoControlPort
bool autoControlPort() const
Definition: TorSettings.cpp:463
SETTING_SOCKET_PATH
#define SETTING_SOCKET_PATH
Definition: TorSettings.cpp:34
TorControl::setConf
bool setConf(QHash< QString, QString > map, QString *errmsg=0)
Definition: TorControl.cpp:722
TorSettings::setWarnPlaintextPorts
void setWarnPlaintextPorts(const QList< quint16 > &ports)
Definition: TorSettings.cpp:336
AbstractTorSettings::torControl
TorControl * torControl() const
Definition: AbstractTorSettings.h:68
crypto_secret_to_key
QByteArray crypto_secret_to_key(const QString &secret, const QByteArray &salt, quint8 c)
Definition: crypto.cpp:166
ControlMethod::toString
static QString toString(ControlMethod::Method method)
Definition: ControlMethod.cpp:19
TorSettings::setUseRandomPassword
void setUseRandomPassword(bool useRandomPassword)
Definition: TorSettings.cpp:283
SETTING_TOR_EXECUTABLE
#define SETTING_TOR_EXECUTABLE
Definition: TorSettings.cpp:30
TorSettings::setBootstrap
void setBootstrap(bool enabled)
Definition: TorSettings.cpp:439
SETTING_BOOTSTRAP
#define SETTING_BOOTSTRAP
Definition: TorSettings.cpp:45
SETTING_CONTROL_ADDR
#define SETTING_CONTROL_ADDR
Definition: TorSettings.cpp:32
TorSettings::setControlAddress
void setControlAddress(const QHostAddress &addr)
Definition: TorSettings.cpp:209
SETTING_CONTROL_METHOD
#define SETTING_CONTROL_METHOD
Definition: TorSettings.cpp:35
SETTING_AUTH_METHOD
#define SETTING_AUTH_METHOD
Definition: TorSettings.cpp:40
tc
Definition: tcglobal.cpp:19
crypto.h
TorSettings::setAuthenticationMethod
void setAuthenticationMethod(AuthenticationMethod method)
Definition: TorSettings.cpp:313
stringutil.h
TorSettings::setExecutable
void setExecutable(const QString &torExecutable)
Definition: TorSettings.cpp:174
TorSettings::getAuthenticationMethod
AuthenticationMethod getAuthenticationMethod() const
Definition: TorSettings.cpp:290
TorSettings::setDataDirectory
void setDataDirectory(const QString &dataDir)
Definition: TorSettings.cpp:156
TorSettings::toAuthenticationMethod
AuthenticationMethod toAuthenticationMethod(const QString &authMethod) const
Definition: TorSettings.cpp:390
SETTING_CONTROL_PASSWORD
#define SETTING_CONTROL_PASSWORD
Definition: TorSettings.cpp:41
TorSettings::getSocketPath
QString getSocketPath() const
Definition: TorSettings.cpp:230
TorSettings::setSocketPath
void setSocketPath(const QString &path)
Definition: TorSettings.cpp:237
TorSettings::setRejectPlaintextPorts
void setRejectPlaintextPorts(const QList< quint16 > &ports)
Definition: TorSettings.cpp:363
ControlMethod::Method
Method
Definition: ControlMethod.h:24
TorSettings::getControlAddress
QHostAddress getControlAddress() const
Definition: TorSettings.cpp:201
VSettings::setDefault
void setDefault(const QString &key, const QVariant &val)
Definition: VSettings.cpp:71
TorSettings::TorSettings
TorSettings(TorControl *torControl=0)
Definition: TorSettings.cpp:69
TorSettings::getTorrc
QString getTorrc() const
Definition: TorSettings.cpp:181
TorSettings.h
DEFAULT_AUTH_METHOD
#define DEFAULT_AUTH_METHOD
Definition: TorSettings.cpp:50
TorSettings::setBootstrapFrom
void setBootstrapFrom(const QString &from)
Definition: TorSettings.cpp:451
TorSettings::getWarnPlaintextPorts
QList< quint16 > getWarnPlaintextPorts() const
Definition: TorSettings.cpp:321
SETTING_REJECT_PLAINTEXT_PORTS
#define SETTING_REJECT_PLAINTEXT_PORTS
Definition: TorSettings.cpp:44
TorSettings::getControlPort
quint16 getControlPort() const
Definition: TorSettings.cpp:216
SETTING_USE_RANDOM_PASSWORD
#define SETTING_USE_RANDOM_PASSWORD
Definition: TorSettings.cpp:42
base16_encode
QString base16_encode(const QByteArray &buf)
Definition: stringutil.cpp:115
TorSettings::AuthenticationMethod
AuthenticationMethod
Definition: TorSettings.h:32
AbstractTorSettings::setValue
virtual void setValue(const QString &key, const QVariant &value)
Definition: AbstractTorSettings.cpp:123
TorSettings::hashPassword
static QString hashPassword(const QString &password)
Definition: TorSettings.cpp:412
TorSettings::getExecutable
QString getExecutable() const
Definition: TorSettings.cpp:164
file.h
TorSettings::setTorrc
void setTorrc(const QString &torrc)
Definition: TorSettings.cpp:194
SETTING_AUTOCONTROL
#define SETTING_AUTOCONTROL
Definition: TorSettings.cpp:47
SETTING_BOOTSTRAP_FROM
#define SETTING_BOOTSTRAP_FROM
Definition: TorSettings.cpp:46
AbstractTorSettings
Definition: AbstractTorSettings.h:22
TOR_ARG_COOKIE_AUTH
#define TOR_ARG_COOKIE_AUTH
Definition: TorSettings.cpp:61
TorSettings::useRandomPassword
bool useRandomPassword() const
Definition: TorSettings.cpp:275
TorSettings::bootstrap
bool bootstrap() const
Definition: TorSettings.cpp:445
DEFAULT_CONTROL_METHOD
#define DEFAULT_CONTROL_METHOD
Definition: TorSettings.cpp:52
SETTING_TORRC
#define SETTING_TORRC
Definition: TorSettings.cpp:31
AbstractTorSettings::value
virtual QVariant value(const QString &key) const
Definition: AbstractTorSettings.cpp:113
TorSettings::PasswordAuth
@ PasswordAuth
Definition: TorSettings.h:35