Vidalia
0.2.17
|
00001 /* 00002 ** This file is part of Vidalia, and is subject to the license terms in the 00003 ** LICENSE file, found in the top level directory of this distribution. If you 00004 ** did not receive the LICENSE file with this file, you may obtain it from the 00005 ** Vidalia source package distributed by the Vidalia Project at 00006 ** http://www.torproject.org/projects/vidalia.html. No part of Vidalia, 00007 ** including this file, may be copied, modified, propagated, or distributed 00008 ** except according to the terms described in the LICENSE file. 00009 */ 00010 00011 /* 00012 ** \file TorSettings.cpp 00013 ** \brief Settings used for starting and running Tor 00014 */ 00015 00016 #include "TorSettings.h" 00017 #include "Vidalia.h" 00018 #include "crypto.h" 00019 #include "file.h" 00020 #include "stringutil.h" 00021 #if defined(Q_OS_WIN32) 00022 #include "win32.h" 00023 #include <QFileInfo> 00024 #endif 00025 00026 #include <QDir> 00027 #include <QProcess> 00028 00029 /* Tor Settings */ 00030 #define SETTING_TOR_EXECUTABLE "TorExecutable" 00031 #define SETTING_TORRC "Torrc" 00032 #define SETTING_CONTROL_ADDR "ControlAddr" 00033 #define SETTING_CONTROL_PORT "ControlPort" 00034 #define SETTING_SOCKET_PATH "ControlSocket" 00035 #define SETTING_CONTROL_METHOD "ControlMethod" 00036 #define SETTING_AUTH_TOKEN "AuthToken" 00037 #define SETTING_TOR_USER "User" 00038 #define SETTING_TOR_GROUP "Group" 00039 #define SETTING_DATA_DIRECTORY "DataDirectory" 00040 #define SETTING_AUTH_METHOD "AuthenticationMethod" 00041 #define SETTING_CONTROL_PASSWORD "ControlPassword" 00042 #define SETTING_USE_RANDOM_PASSWORD "UseRandomPassword" 00043 #define SETTING_WARN_PLAINTEXT_PORTS "WarnPlaintextPorts" 00044 #define SETTING_REJECT_PLAINTEXT_PORTS "RejectPlaintextPorts" 00045 #define SETTING_BOOTSTRAP "Bootstrap" 00046 #define SETTING_BOOTSTRAP_FROM "BootstrapFrom" 00047 #define SETTING_AUTOCONTROL "AutoControl" 00048 00049 /** Default to using hashed password authentication */ 00050 #define DEFAULT_AUTH_METHOD PasswordAuth 00051 /** Default control method */ 00052 #define DEFAULT_CONTROL_METHOD "ControlPort" 00053 /** Default socket path */ 00054 #define DEFAULT_SOCKET_PATH "" 00055 00056 /* Arguments we can pass to Tor on the command-line */ 00057 #define TOR_ARG_CONTROL_PORT "ControlPort" 00058 #define TOR_ARG_TORRC "-f" 00059 #define TOR_ARG_DATA_DIRECTORY "DataDirectory" 00060 #define TOR_ARG_HASHED_PASSWORD "HashedControlPassword" 00061 #define TOR_ARG_COOKIE_AUTH "CookieAuthentication" 00062 #define TOR_ARG_SOCKSPORT "SocksPort" 00063 00064 /** Generate random control passwords of 16 characters */ 00065 #define PASSWORD_LEN 16 00066 00067 00068 /** Default constructor */ 00069 TorSettings::TorSettings(TorControl *torControl) 00070 : AbstractTorSettings("Tor", torControl) 00071 { 00072 #if defined(Q_OS_WIN32) 00073 QString programFiles = win32_program_files_folder(); 00074 if (QFileInfo(programFiles + "\\Vidalia Bundle\\Tor\\tor.exe").exists()) 00075 setDefault(SETTING_TOR_EXECUTABLE, 00076 programFiles + "\\Vidalia Bundle\\Tor\\tor.exe"); 00077 else 00078 setDefault(SETTING_TOR_EXECUTABLE, programFiles + "\\Tor\\tor.exe"); 00079 #else 00080 setDefault(SETTING_TOR_EXECUTABLE, "/usr/bin/tor"); 00081 #endif 00082 00083 setDefault(SETTING_TORRC, "/etc/tor/torrc"); 00084 setDefault(SETTING_CONTROL_ADDR, "127.0.0.1"); 00085 setDefault(SETTING_CONTROL_PORT, 9051); 00086 setDefault(SETTING_AUTH_METHOD, toString(DEFAULT_AUTH_METHOD)); 00087 setDefault(SETTING_CONTROL_METHOD, DEFAULT_CONTROL_METHOD); 00088 setDefault(SETTING_SOCKET_PATH, DEFAULT_SOCKET_PATH); 00089 setDefault(SETTING_DATA_DIRECTORY, "/var/lib/tor"); 00090 setDefault(SETTING_CONTROL_PASSWORD, ""); 00091 setDefault(SETTING_USE_RANDOM_PASSWORD, true); 00092 setDefault(SETTING_WARN_PLAINTEXT_PORTS, QList<QVariant>() << 23 << 109 00093 << 110 << 143); 00094 setDefault(SETTING_REJECT_PLAINTEXT_PORTS, QList<QVariant>()); 00095 setDefault(SETTING_BOOTSTRAP, false); 00096 setDefault(SETTING_BOOTSTRAP_FROM, ""); 00097 setDefault(SETTING_AUTOCONTROL, false); 00098 } 00099 00100 /** Applies any changes to Tor's control port or authentication settings. */ 00101 bool 00102 TorSettings::apply(QString *errmsg) 00103 { 00104 QHash<QString, QString> conf; 00105 QString hashedPassword; 00106 00107 conf.insert(SETTING_CONTROL_PORT, 00108 localValue(SETTING_CONTROL_PORT).toString()); 00109 00110 if(localValue(SETTING_AUTOCONTROL).toBool()) 00111 conf.insert(TOR_ARG_SOCKSPORT, "auto"); 00112 else 00113 conf.insert(TOR_ARG_SOCKSPORT, "9050"); 00114 00115 AuthenticationMethod authMethod = 00116 toAuthenticationMethod(localValue(SETTING_AUTH_METHOD).toString()); 00117 switch (authMethod) { 00118 case CookieAuth: 00119 conf.insert(TOR_ARG_COOKIE_AUTH, "1"); 00120 conf.insert(TOR_ARG_HASHED_PASSWORD, ""); 00121 break; 00122 case PasswordAuth: 00123 hashedPassword = useRandomPassword() 00124 ? hashPassword(randomPassword()) 00125 : hashPassword(getControlPassword()); 00126 if (hashedPassword.isEmpty()) { 00127 if (errmsg) 00128 *errmsg = tr("Failed to hash the control password."); 00129 return false; 00130 } 00131 conf.insert(TOR_ARG_COOKIE_AUTH, "0"); 00132 conf.insert(TOR_ARG_HASHED_PASSWORD, hashedPassword); 00133 break; 00134 default: 00135 conf.insert(TOR_ARG_COOKIE_AUTH, "0"); 00136 conf.insert(TOR_ARG_HASHED_PASSWORD, ""); 00137 } 00138 00139 conf.insert(SETTING_WARN_PLAINTEXT_PORTS, 00140 localValue(SETTING_WARN_PLAINTEXT_PORTS).toStringList().join(",")); 00141 conf.insert(SETTING_REJECT_PLAINTEXT_PORTS, 00142 localValue(SETTING_REJECT_PLAINTEXT_PORTS).toStringList().join(",")); 00143 00144 return torControl()->setConf(conf, errmsg); 00145 } 00146 00147 /** Gets the location of Tor's data directory. */ 00148 QString 00149 TorSettings::getDataDirectory() const 00150 { 00151 return QDir::convertSeparators(value(SETTING_DATA_DIRECTORY).toString()); 00152 } 00153 00154 /** Sets the location to use as Tor's data directory. */ 00155 void 00156 TorSettings::setDataDirectory(const QString &dataDirectory) 00157 { 00158 setValue(SETTING_DATA_DIRECTORY, dataDirectory); 00159 } 00160 00161 /** Returns a fully-qualified path to Tor's executable, including the 00162 * executable name. */ 00163 QString 00164 TorSettings::getExecutable() const 00165 { 00166 QString tor = localValue(SETTING_TOR_EXECUTABLE).toString(); 00167 if (tor.isEmpty()) /* Don't let the Tor executable name be empty */ 00168 tor = defaultValue(SETTING_TOR_EXECUTABLE).toString(); 00169 return QDir::convertSeparators(tor); 00170 } 00171 00172 /** Sets the location and name of Tor's executable to the given string. */ 00173 void 00174 TorSettings::setExecutable(const QString &torExecutable) 00175 { 00176 setValue(SETTING_TOR_EXECUTABLE, torExecutable); 00177 } 00178 00179 /** Returns the torrc that will be used when starting Tor. */ 00180 QString 00181 TorSettings::getTorrc() const 00182 { 00183 QString torrc; 00184 TorControl *tc = torControl(); 00185 if (tc && tc->isConnected() && tc->getInfo("config-file", torrc)) 00186 return QDir::convertSeparators(torrc); 00187 return QDir::convertSeparators(localValue(SETTING_TORRC).toString()); 00188 } 00189 00190 /** Sets the torrc that will be used when starting Tor. 00191 * \param torrc The torrc to use. 00192 */ 00193 void 00194 TorSettings::setTorrc(const QString &torrc) 00195 { 00196 setValue(SETTING_TORRC, torrc); 00197 } 00198 00199 /** Get the address or hostname used to connect to Tor */ 00200 QHostAddress 00201 TorSettings::getControlAddress() const 00202 { 00203 QString addr = localValue(SETTING_CONTROL_ADDR).toString(); 00204 return QHostAddress(addr); 00205 } 00206 00207 /** Set the address or hostname used to connect to Tor */ 00208 void 00209 TorSettings::setControlAddress(const QHostAddress &addr) 00210 { 00211 setValue(SETTING_CONTROL_ADDR, addr.toString()); 00212 } 00213 00214 /** Get the control port used to connect to Tor */ 00215 quint16 00216 TorSettings::getControlPort() const 00217 { 00218 return (quint16)value(SETTING_CONTROL_PORT).toInt(); 00219 } 00220 00221 /** Set the control port used to connect to Tor */ 00222 void 00223 TorSettings::setControlPort(quint16 port) 00224 { 00225 setValue(SETTING_CONTROL_PORT, port); 00226 } 00227 00228 /** Get the path for ControlSocket */ 00229 QString 00230 TorSettings::getSocketPath() const 00231 { 00232 return value(SETTING_SOCKET_PATH).toString(); 00233 } 00234 00235 /** Set the path for ControlSocket */ 00236 void 00237 TorSettings::setSocketPath(const QString &path) 00238 { 00239 setValue(SETTING_SOCKET_PATH, path); 00240 } 00241 00242 /** Get the current control method */ 00243 ControlMethod::Method 00244 TorSettings::getControlMethod() const 00245 { 00246 return ControlMethod::fromString(localValue(SETTING_CONTROL_METHOD).toString()); 00247 } 00248 00249 /** Set the control method */ 00250 void 00251 TorSettings::setControlMethod(ControlMethod::Method method) 00252 { 00253 setValue(SETTING_CONTROL_METHOD, ControlMethod::toString(method)); 00254 } 00255 00256 /** Returns the plaintext (i.e., not hashed) control password used when 00257 * authenticating to Tor. */ 00258 QString 00259 TorSettings::getControlPassword() const 00260 { 00261 return localValue(SETTING_CONTROL_PASSWORD).toString(); 00262 } 00263 00264 /** Sets the control password used when starting Tor with 00265 * HashedControlPassword to <b>password</b>. */ 00266 void 00267 TorSettings::setControlPassword(const QString &password) 00268 { 00269 setValue(SETTING_CONTROL_PASSWORD, password); 00270 } 00271 00272 /** Returns true if a new, random control password is to be used each time Tor 00273 * is started. */ 00274 bool 00275 TorSettings::useRandomPassword() const 00276 { 00277 return localValue(SETTING_USE_RANDOM_PASSWORD).toBool(); 00278 } 00279 00280 /** Sets whether or not to generate and use a random control password each 00281 * time Tor is started. */ 00282 void 00283 TorSettings::setUseRandomPassword(bool useRandomPassword) 00284 { 00285 setValue(SETTING_USE_RANDOM_PASSWORD, useRandomPassword); 00286 } 00287 00288 /** Returns the current authentication method used when connecting to Tor. */ 00289 TorSettings::AuthenticationMethod 00290 TorSettings::getAuthenticationMethod() const 00291 { 00292 AuthenticationMethod type = UnknownAuth; 00293 TorControl *tc = torControl(); 00294 00295 if (tc && tc->isConnected()) { 00296 QHash<QString,QString> conf; 00297 conf.insert(TOR_ARG_COOKIE_AUTH, ""); 00298 conf.insert(TOR_ARG_HASHED_PASSWORD, ""); 00299 if (tc->getConf(conf)) { 00300 if (conf.value(TOR_ARG_COOKIE_AUTH) == "1") 00301 type = CookieAuth; 00302 else if (!conf.value(TOR_ARG_HASHED_PASSWORD).isEmpty()) 00303 type = PasswordAuth; 00304 } 00305 } 00306 if (type == UnknownAuth) 00307 type = toAuthenticationMethod(localValue(SETTING_AUTH_METHOD).toString()); 00308 return (type == UnknownAuth ? DEFAULT_AUTH_METHOD : type); 00309 } 00310 00311 /** Sets the authentication method used when starting Tor to <b>method</b>. */ 00312 void 00313 TorSettings::setAuthenticationMethod(AuthenticationMethod method) 00314 { 00315 setValue(SETTING_AUTH_METHOD, toString(method)); 00316 } 00317 00318 /** Returns the current list of ports that will cause Tor to issue a warning 00319 * when the user tries to connect to one of them. */ 00320 QList<quint16> 00321 TorSettings::getWarnPlaintextPorts() const 00322 { 00323 QList<quint16> out; 00324 QList<QVariant> ports; 00325 00326 ports = value(SETTING_WARN_PLAINTEXT_PORTS).toList(); 00327 foreach (QVariant port, ports) { 00328 out << port.toUInt(); 00329 } 00330 return out; 00331 } 00332 00333 /** Sets the list of ports that will cause Tor to issue a warning when the 00334 * user tries to connect to one of them. */ 00335 void 00336 TorSettings::setWarnPlaintextPorts(const QList<quint16> &ports) 00337 { 00338 QList<QVariant> warnList; 00339 foreach (quint16 port, ports) { 00340 warnList << QVariant(port); 00341 } 00342 setValue(SETTING_WARN_PLAINTEXT_PORTS, warnList); 00343 } 00344 00345 /** Returns the current list of ports that will cause Tor to reject the 00346 * connection when the user tries to connect to one of them. */ 00347 QList<quint16> 00348 TorSettings::getRejectPlaintextPorts() const 00349 { 00350 QList<quint16> out; 00351 QList<QVariant> ports; 00352 00353 ports = value(SETTING_REJECT_PLAINTEXT_PORTS).toList(); 00354 foreach (QVariant port, ports) { 00355 out << port.toUInt(); 00356 } 00357 return out; 00358 } 00359 00360 /** Sets the list of ports that will cause Tor to reject the connection 00361 * when the user tries to connect to one of them. */ 00362 void 00363 TorSettings::setRejectPlaintextPorts(const QList<quint16> &ports) 00364 { 00365 QList<QVariant> rejectList; 00366 foreach (quint16 port, ports) { 00367 rejectList << QVariant(port); 00368 } 00369 setValue(SETTING_REJECT_PLAINTEXT_PORTS, rejectList); 00370 } 00371 00372 /** Returns the string description of the authentication method specified by 00373 * <b>method</b>. The authentication method string is stored in Vidalia's 00374 * configuration file. */ 00375 QString 00376 TorSettings::toString(AuthenticationMethod method) const 00377 { 00378 switch (method) { 00379 case NullAuth: return "none"; 00380 case PasswordAuth: return "password"; 00381 case CookieAuth: return "cookie"; 00382 default: break; 00383 } 00384 return "unknown"; 00385 } 00386 00387 /** Returns the AuthenticationMethod enum value for the string 00388 * description of the authentication method given in <b>authMethod</b>. */ 00389 TorSettings::AuthenticationMethod 00390 TorSettings::toAuthenticationMethod(const QString &authMethod) const 00391 { 00392 QString str = authMethod.toLower(); 00393 if (str == toString(NullAuth)) 00394 return NullAuth; 00395 else if (str == toString(PasswordAuth)) 00396 return PasswordAuth; 00397 else if (str == toString(CookieAuth)) 00398 return CookieAuth; 00399 return UnknownAuth; 00400 } 00401 00402 /** Generates a random control password consisting of PASSWORD_LEN characters. */ 00403 QString 00404 TorSettings::randomPassword() 00405 { 00406 return crypto_rand_string(PASSWORD_LEN); 00407 } 00408 00409 /** Returns the hash of <b>password</b> as given by the command "tor 00410 * --hash-password foo". */ 00411 QString 00412 TorSettings::hashPassword(const QString &password) 00413 { 00414 QByteArray salt; 00415 00416 /* Generate an 8 octet salt value. Bail if we fail to generate enough 00417 * random bytes (unlikely). */ 00418 while (salt.size() < 8) { 00419 QByteArray bytes = crypto_rand_bytes(8-salt.size()); 00420 if (bytes.isNull()) 00421 return QString(); 00422 salt.append(bytes); 00423 } 00424 00425 /* Generate the salted hash of the specified password. 96 is the one-octet 00426 * RFC 2440 coded count value hardcoded into Tor. Specifies that we should 00427 * hash 64K worth of data. */ 00428 QByteArray key = crypto_secret_to_key(password, salt, 96); 00429 if (key.isNull()) 00430 return QString(); 00431 salt.append(96); /* Append the coded count value to the salt */ 00432 00433 /* Convert the result to hexadecimal and put it in the format Tor wants. */ 00434 return QString("16:%1%2").arg(base16_encode(salt)) 00435 .arg(base16_encode(key)); 00436 } 00437 00438 void 00439 TorSettings::setBootstrap(bool enabled) 00440 { 00441 setValue(SETTING_BOOTSTRAP, enabled); 00442 } 00443 00444 bool 00445 TorSettings::bootstrap() const 00446 { 00447 return value(SETTING_BOOTSTRAP).toBool(); 00448 } 00449 00450 void 00451 TorSettings::setBootstrapFrom(const QString &from) 00452 { 00453 setValue(SETTING_BOOTSTRAP_FROM, from); 00454 } 00455 00456 QString 00457 TorSettings::bootstrapFrom() const 00458 { 00459 return QDir::convertSeparators(value(SETTING_BOOTSTRAP_FROM).toString()); 00460 } 00461 00462 bool 00463 TorSettings::autoControlPort() const 00464 { 00465 return value(SETTING_AUTOCONTROL).toBool(); 00466 } 00467 00468 void 00469 TorSettings::setAutoControlPort(const bool autoControl) 00470 { 00471 setValue(SETTING_AUTOCONTROL, autoControl); 00472 }