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