23 #include <QHostAddress>
24 #include <QVariantMap>
30 #define RELAY_SIGNAL(src, sig) \
31 QObject::connect((src), (sig), this, (sig))
39 QString, QStringList)));
81 QObject::connect(
_torProcess, SIGNAL(finished(
int, QProcess::ExitStatus)),
82 this, SLOT(
onStopped(
int, QProcess::ExitStatus)));
83 QObject::connect(
_torProcess, SIGNAL(log(QString, QString)),
86 #if defined(Q_OS_WIN32)
90 QObject::connect(_torService, SIGNAL(finished(
int, QProcess::ExitStatus)),
91 this, SLOT(
onStopped(
int, QProcess::ExitStatus)));
119 #if defined(Q_OS_WIN32)
123 _torService->start();
153 emit
stopped(exitCode, exitStatus);
161 return (
_torProcess->state() != QProcess::NotRunning);
168 return (
_torProcess->state() != QProcess::NotRunning
219 if (!
send(cmd, reply, &str)) {
224 QHash<QString, QString> args;
234 args.value(
"PROGRESS").toInt(),
235 args.value(
"SUMMARY"));
286 return send(cmd, reply, errmsg);
300 if (!
send(cmd, reply, &str)) {
302 return err(errmsg, str);
319 if (!
send(cmd, reply, &str)) {
321 return err(errmsg, str);
352 QHash<QString,QString> keyvals;
356 if (!
send(cmd, reply, errmsg))
364 idx = msg.indexOf(
" ");
365 topic = msg.mid(0, idx).toUpper();
372 keyvals = QHash<QString,QString>();
375 if (topic ==
"AUTH") {
376 if (keyvals.contains(
"METHODS"))
378 if (keyvals.contains(
"COOKIEFILE"))
380 }
else if (topic ==
"VERSION") {
381 if (keyvals.contains(
"Tor"))
395 return send(cmd, errmsg);
401 QString str =
getInfo(
"status/bootstrap-phase").toString();
402 if (!str.isEmpty()) {
407 args.value(
"PROGRESS").toInt(),
408 args.value(
"SUMMARY"),
409 args.value(
"WARNING"),
412 args.value(
"RECOMMENDATION")));
426 if (
getInfo(
"status/circuit-established", tmp))
433 foreach (
Circuit circ, circs) {
452 foreach (QString key, map.keys()) {
457 if (
send(cmd, reply, errmsg)) {
461 QStringList keyval = line.
getMessage().split(
"=");
462 if (keyval.size() == 2) {
463 QString key = keyval.at(0);
464 QString val = keyval.at(1);
465 if (val.startsWith(QLatin1Char(
'\"')) &&
466 val.endsWith(QLatin1Char(
'\"'))) {
472 map.insert(key, val);
491 if (!
send(cmd, reply, errmsg))
492 return QVariantMap();
496 int index = msg.indexOf(
"=");
497 QString key = msg.mid(0, index);
500 if (index > 0 && index < msg.length()-1) {
501 QString str = msg.mid(index+1);
502 if (str.startsWith(QLatin1Char(
'\"')) &&
503 str.endsWith(QLatin1Char(
'\"'))) {
514 if (infoMap.contains(key)) {
515 QStringList values = infoMap.value(key).toStringList();
517 infoMap.insert(key, values);
519 infoMap.insert(key, val);
531 QVariantMap map =
getInfo(QStringList() << key, errmsg);
532 return map.value(key);
539 QHash<QString,QString> map;
543 val = map.value(key);
561 return send(cmd, errmsg);
569 QHostAddress socksAddr;
573 return QHostAddress::Null;
579 foreach (QString addr, addrList) {
580 addr = addr.mid(0, addr.indexOf(
":"));
581 if (socksAddr.setAddress(addr)) {
586 return QHostAddress::LocalHost;
594 QStringList addrList;
595 if (
getConf(
"SocksListenAddress", addrList, errmsg)) {
598 return QStringList();
607 if (portList.size() > 0) {
608 return portList.at(0);
619 quint16 port, socksPort;
621 QList<quint16> portList;
624 if (
getConf(
"SocksPort", portString, errmsg)) {
625 socksPort = (quint16)portString.toUInt(&valid);
627 if (socksPort == 0) {
630 return QList<quint16>();
636 foreach (QString addr, addrList) {
637 if (addr.contains(
":")) {
638 portString = addr.mid(addr.indexOf(
":")+1);
639 port = (quint16)portString.toUInt(&valid);
647 if (!portList.size() || (portList.size() != addrList.size())) {
648 portList << socksPort;
665 static QString versionString;
666 static quint32 version = 0;
667 quint8 major, minor, micro, patch;
675 QStringList parts = versionString.split(QRegExp(
"\\.|-|\\ "));
676 if (parts.size() >= 4) {
677 major = (quint8)parts.at(0).toUInt();
678 minor = (quint8)parts.at(1).toUInt();
679 micro = (quint8)parts.at(2).toUInt();
680 patch = (quint8)parts.at(3).toUInt();
681 version = ((major << 24) | (minor << 16) | (micro << 8) | patch);
712 return send(cmd, errmsg);
723 foreach (QString key, map.uniqueKeys()) {
729 QList<QString> values = map.values(key);
730 for (
int i = values.size()-1;
i >= 0;
i--) {
731 QString value = values.at(
i);
732 if (value.length() > 0)
738 return send(cmd, errmsg);
745 QHash<QString,QString> map;
746 map.insert(key, value);
754 QHash<QString,QString> map;
755 map.insert(keyAndValue,
"");
764 QHash<QString,QStringList> multiMap;
765 foreach (QString key, map.keys()) {
766 multiMap.insert(key, QStringList());
768 if (
getConf(multiMap, errmsg)) {
769 foreach (QString key, multiMap.keys()) {
770 if (map.contains(key)) {
771 map.insert(key, multiMap.value(key).join(
"\n"));
784 QStringList confValue;
788 foreach (QString key, map.keys()) {
793 if (
send(cmd, reply, errmsg)) {
797 QStringList keyval = line.
getMessage().split(
"=");
798 if (keyval.size() == 2) {
799 confKey = keyval.at(0);
801 if (map.contains(confKey)) {
804 confValue = map.value(confKey);
806 confValue << keyval.at(1);
807 map.insert(keyval.at(0), confValue);
819 QStringList confValues;
820 if (
getConf(key, confValues, errmsg)) {
821 value = confValues.join(
"\n");
831 QHash<QString,QStringList> map;
832 map.insert(key, QStringList());
835 value = map.value(key);
852 if (!
send(cmd, reply, errmsg))
853 return QVariantMap();
857 int index = msg.indexOf(
"=");
858 QString key = msg.mid(0, index);
861 if (index > 0 && index < msg.length()-1)
862 val = msg.mid(index+1);
863 if (val.startsWith(QLatin1Char(
'\"')) &&
864 val.endsWith(QLatin1Char(
'\"'))) {
871 if (confMap.contains(key)) {
872 QStringList values = confMap.value(key).toStringList();
874 confMap.insert(key, values);
876 confMap.insert(key, val);
888 QVariantMap map =
getConf(QStringList() << key, errmsg);
889 return map.value(key);
902 if (!
send(cmd, reply, errmsg))
913 bool ret =
send(cmd, errmsg);
917 setConf(
"__ReloadTorrcOnSIGHUP",
"0", &err);
930 foreach (QString key, keys) {
933 return send(cmd, errmsg);
941 return resetConf(QStringList() << key, errmsg);
948 errmsg =
new QString();
950 QString mdres, fetchres;
951 if(!
getConf(
"UseMicrodescriptors", mdres, errmsg))
953 if(!
getConf(
"FetchUselessDescriptors", fetchres, errmsg))
955 return (mdres ==
"1") or (mdres ==
"auto" and fetchres ==
"0");
966 return getInfo(
"md/id/" +
id, errmsg).toStringList();
968 return getInfo(
"desc/id/" +
id, errmsg).toStringList();
986 QStringList status =
getInfo(
"ns/id/" +
id, errmsg).toStringList();
996 QStringList networkStatusLines =
getInfo(
"ns/all", errmsg).toStringList();
997 QList<RouterStatus> networkStatus;
998 int len = networkStatusLines.size();
1003 QStringList routerStatusLines;
1005 routerStatusLines << networkStatusLines.at(i);
1006 }
while (++i < len && ! networkStatusLines.at(i).startsWith(
"r "));
1012 networkStatus << routerStatus;
1014 return networkStatus;
1024 QStringList lines =
getInfo(
"desc-annotations/id/"+
id, errmsg).toStringList();
1028 foreach (QString line, lines) {
1029 int idx = line.indexOf(
" ");
1032 key = line.mid(0, idx);
1033 if (key.startsWith(
"@"))
1034 key = key.remove(0, 1);
1037 if (idx > 0 && idx < line.length()-1)
1038 annotations.insert(key, line.mid(idx + 1).trimmed());
1040 annotations.insert(key, QString());
1053 if (!
send(cmd, reply, errmsg))
1057 foreach(QString line, reply.
getData()) {
1074 return send(cmd, errmsg);
1083 QList<Stream> streams;
1086 if (
send(cmd, reply, errmsg)) {
1094 foreach (QString line, reply.
getData()) {
1109 return send(cmd, errmsg);
1118 QStringList entries;
1122 entries =
getInfo(
"address-mappings/config").toStringList();
1125 entries =
getInfo(
"address-mappings/cache").toStringList();
1128 entries =
getInfo(
"address-mappings/control").toStringList();
1131 entries =
getInfo(
"address-mappings/all").toStringList();
1134 foreach (QString entry, entries) {
1135 addressMap.
add(entry);
1147 QString request = QString(
"ip-to-country/%1").arg(ip.toString());
1148 QVariant response =
getInfo(request, errmsg);
1149 if (! response.isNull())
1150 return response.toString();
1159 return send(cmd, errmsg);