torsettings.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include <QDir>
00018 #include <QProcess>
00019 #include <crypto.h>
00020 #include <vidalia.h>
00021
00022 #if defined(Q_OS_WIN32)
00023 #include <QFileInfo>
00024 #include <win32.h>
00025 #endif
00026
00027 #include "torsettings.h"
00028
00029
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_AUTH_TOKEN "AuthToken"
00035 #define SETTING_TOR_USER "User"
00036 #define SETTING_TOR_GROUP "Group"
00037 #define SETTING_DATA_DIRECTORY "DataDirectory"
00038 #define SETTING_AUTH_METHOD "AuthenticationMethod"
00039 #define SETTING_CONTROL_PASSWORD "ControlPassword"
00040 #define SETTING_USE_RANDOM_PASSWORD "UseRandomPassword"
00041
00042
00043 #define DEFAULT_AUTH_METHOD PasswordAuth
00044
00045
00046 #define TOR_ARG_CONTROL_PORT "ControlPort"
00047 #define TOR_ARG_TORRC "-f"
00048 #define TOR_ARG_USER "User"
00049 #define TOR_ARG_GROUP "Group"
00050 #define TOR_ARG_DATA_DIRECTORY "DataDirectory"
00051 #define TOR_ARG_HASHED_PASSWORD "HashedControlPassword"
00052 #define TOR_ARG_COOKIE_AUTH "CookieAuthentication"
00053
00054
00055 #define PASSWORD_LEN 16
00056
00057
00058
00059 TorSettings::TorSettings(TorControl *torControl)
00060 : AbstractTorSettings("Tor", torControl)
00061 {
00062 #if defined(Q_OS_WIN32)
00063 QString programFiles = win32_program_files_folder();
00064 if (QFileInfo(programFiles + "\\Vidalia Bundle\\Tor\\tor.exe").exists())
00065 setDefault(SETTING_TOR_EXECUTABLE,
00066 programFiles + "\\Vidalia Bundle\\Tor\\tor.exe");
00067 else
00068 setDefault(SETTING_TOR_EXECUTABLE, programFiles + "\\Tor\\tor.exe");
00069 #else
00070 setDefault(SETTING_TOR_EXECUTABLE, "/usr/bin/tor");
00071 #endif
00072
00073 setDefault(SETTING_TORRC, "/etc/tor/torrc");
00074 setDefault(SETTING_CONTROL_ADDR, "127.0.0.1");
00075 setDefault(SETTING_CONTROL_PORT, 9051);
00076 setDefault(SETTING_AUTH_METHOD, toString(DEFAULT_AUTH_METHOD));
00077 setDefault(SETTING_TOR_USER, "toruser");
00078 setDefault(SETTING_TOR_GROUP, "toruser");
00079 setDefault(SETTING_DATA_DIRECTORY, "/var/lib/tor");
00080 setDefault(SETTING_CONTROL_PASSWORD, "");
00081 setDefault(SETTING_USE_RANDOM_PASSWORD, true);
00082 }
00083
00084
00085 bool
00086 TorSettings::apply(QString *errmsg)
00087 {
00088 QHash<QString, QString> conf;
00089 QString hashedPassword;
00090
00091 conf.insert(SETTING_CONTROL_PORT,
00092 localValue(SETTING_CONTROL_PORT).toString());
00093
00094 AuthenticationMethod authMethod =
00095 toAuthenticationMethod(localValue(SETTING_AUTH_METHOD).toString());
00096 switch (authMethod) {
00097 case CookieAuth:
00098 conf.insert(TOR_ARG_COOKIE_AUTH, "1");
00099 conf.insert(TOR_ARG_HASHED_PASSWORD, "");
00100 break;
00101 case PasswordAuth:
00102 hashedPassword = useRandomPassword()
00103 ? hashPassword(randomPassword())
00104 : hashPassword(getControlPassword());
00105 if (hashedPassword.isEmpty()) {
00106 if (errmsg)
00107 *errmsg = tr("Failed to hash the control password.");
00108 return false;
00109 }
00110 conf.insert(TOR_ARG_COOKIE_AUTH, "0");
00111 conf.insert(TOR_ARG_HASHED_PASSWORD, hashedPassword);
00112 break;
00113 default:
00114 conf.insert(TOR_ARG_COOKIE_AUTH, "0");
00115 conf.insert(TOR_ARG_HASHED_PASSWORD, "");
00116 }
00117 return torControl()->setConf(conf, errmsg);
00118 }
00119
00120
00121 QString
00122 TorSettings::getDataDirectory() const
00123 {
00124 return QDir::convertSeparators(value(SETTING_DATA_DIRECTORY).toString());
00125 }
00126
00127
00128 void
00129 TorSettings::setDataDirectory(const QString &dataDirectory)
00130 {
00131 setValue(SETTING_DATA_DIRECTORY, dataDirectory);
00132 }
00133
00134
00135
00136 QString
00137 TorSettings::getExecutable() const
00138 {
00139 QString tor = localValue(SETTING_TOR_EXECUTABLE).toString();
00140 if (tor.isEmpty())
00141 tor = defaultValue(SETTING_TOR_EXECUTABLE).toString();
00142 return QDir::convertSeparators(tor);
00143 }
00144
00145
00146 void
00147 TorSettings::setExecutable(const QString &torExecutable)
00148 {
00149 setValue(SETTING_TOR_EXECUTABLE, torExecutable);
00150 }
00151
00152
00153 QString
00154 TorSettings::getTorrc() const
00155 {
00156 QString torrc;
00157 TorControl *tc = torControl();
00158 if (tc && tc->isConnected() && tc->getInfo("config-file", torrc))
00159 return QDir::convertSeparators(torrc);
00160 return QDir::convertSeparators(localValue(SETTING_TORRC).toString());
00161 }
00162
00163
00164
00165
00166 void
00167 TorSettings::setTorrc(const QString &torrc)
00168 {
00169 setValue(SETTING_TORRC, torrc);
00170 }
00171
00172
00173
00174 QString
00175 TorSettings::getUser() const
00176 {
00177 return value(SETTING_TOR_USER).toString();
00178 }
00179
00180
00181
00182 void
00183 TorSettings::setUser(const QString &user)
00184 {
00185 setValue(SETTING_TOR_USER, user);
00186 }
00187
00188
00189
00190 QString
00191 TorSettings::getGroup() const
00192 {
00193 return value(SETTING_TOR_GROUP).toString();
00194 }
00195
00196
00197
00198 void
00199 TorSettings::setGroup(const QString &group)
00200 {
00201 setValue(SETTING_TOR_GROUP, group);
00202 }
00203
00204
00205 QHostAddress
00206 TorSettings::getControlAddress() const
00207 {
00208 QString addr = localValue(SETTING_CONTROL_ADDR).toString();
00209 return QHostAddress(addr);
00210 }
00211
00212
00213 void
00214 TorSettings::setControlAddress(const QHostAddress &addr)
00215 {
00216 setValue(SETTING_CONTROL_ADDR, addr.toString());
00217 }
00218
00219
00220 quint16
00221 TorSettings::getControlPort() const
00222 {
00223 return (quint16)value(SETTING_CONTROL_PORT).toInt();
00224 }
00225
00226
00227 void
00228 TorSettings::setControlPort(quint16 port)
00229 {
00230 setValue(SETTING_CONTROL_PORT, port);
00231 }
00232
00233
00234
00235 QString
00236 TorSettings::getControlPassword() const
00237 {
00238 return localValue(SETTING_CONTROL_PASSWORD).toString();
00239 }
00240
00241
00242
00243 void
00244 TorSettings::setControlPassword(const QString &password)
00245 {
00246 setValue(SETTING_CONTROL_PASSWORD, password);
00247 }
00248
00249
00250
00251 bool
00252 TorSettings::useRandomPassword() const
00253 {
00254 return localValue(SETTING_USE_RANDOM_PASSWORD).toBool();
00255 }
00256
00257
00258
00259 void
00260 TorSettings::setUseRandomPassword(bool useRandomPassword)
00261 {
00262 setValue(SETTING_USE_RANDOM_PASSWORD, useRandomPassword);
00263 }
00264
00265
00266 TorSettings::AuthenticationMethod
00267 TorSettings::getAuthenticationMethod() const
00268 {
00269 AuthenticationMethod type = UnknownAuth;
00270 TorControl *tc = torControl();
00271
00272 if (tc && tc->isConnected()) {
00273 QHash<QString,QString> conf;
00274 conf.insert(TOR_ARG_COOKIE_AUTH, "");
00275 conf.insert(TOR_ARG_HASHED_PASSWORD, "");
00276 if (tc->getConf(conf)) {
00277 if (conf.value(TOR_ARG_COOKIE_AUTH) == "1")
00278 type = CookieAuth;
00279 else if (!conf.value(TOR_ARG_HASHED_PASSWORD).isEmpty())
00280 type = PasswordAuth;
00281 }
00282 }
00283 if (type == UnknownAuth)
00284 type = toAuthenticationMethod(localValue(SETTING_AUTH_METHOD).toString());
00285 return (type == UnknownAuth ? DEFAULT_AUTH_METHOD : type);
00286 }
00287
00288
00289 void
00290 TorSettings::setAuthenticationMethod(AuthenticationMethod method)
00291 {
00292 setValue(SETTING_AUTH_METHOD, toString(method));
00293 }
00294
00295
00296
00297
00298 QString
00299 TorSettings::toString(AuthenticationMethod method) const
00300 {
00301 switch (method) {
00302 case NullAuth: return "none";
00303 case PasswordAuth: return "password";
00304 case CookieAuth: return "cookie";
00305 default: break;
00306 }
00307 return "unknown";
00308 }
00309
00310
00311
00312 TorSettings::AuthenticationMethod
00313 TorSettings::toAuthenticationMethod(const QString &authMethod) const
00314 {
00315 QString str = authMethod.toLower();
00316 if (str == toString(NullAuth))
00317 return NullAuth;
00318 else if (str == toString(PasswordAuth))
00319 return PasswordAuth;
00320 else if (str == toString(CookieAuth))
00321 return CookieAuth;
00322 return UnknownAuth;
00323 }
00324
00325
00326 QString
00327 TorSettings::randomPassword()
00328 {
00329 return crypto_rand_string(PASSWORD_LEN);
00330 }
00331
00332
00333
00334 QString
00335 TorSettings::hashPassword(const QString &password)
00336 {
00337 TorSettings settings;
00338 QProcess tor;
00339 QString dataDirectory, line;
00340 QStringList args;
00341
00342
00343
00344
00345 dataDirectory = settings.getDataDirectory();
00346 if (!dataDirectory.isEmpty())
00347 args << "DataDirectory" << dataDirectory;
00348 args << "--hash-password" << password;
00349
00350
00351
00352 tor.start(settings.getExecutable(), args);
00353 if (!tor.waitForStarted() || !tor.waitForFinished())
00354 return QString();
00355
00356
00357 while (tor.canReadLine()) {
00358 line = tor.readLine();
00359 if (line.startsWith("16:"))
00360 return line.trimmed();
00361 }
00362 return QString();
00363 }
00364