Vidalia 0.2.12
|
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.vidalia-project.net/. No part of Vidalia, including this file, 00007 ** may be copied, modified, propagated, or distributed except according to the 00008 ** terms described in the LICENSE file. 00009 */ 00010 00011 /* 00012 ** \file Policy.cpp 00013 ** \brief Exit policy parsing 00014 */ 00015 00016 #include "Policy.h" 00017 00018 #include <QStringList> 00019 00020 00021 /** Default constructor. Creates an AcceptAll policy. */ 00022 Policy::Policy() 00023 { 00024 _action = Accept; 00025 _address = QHostAddress::Any; 00026 _fromPort = _toPort = 0; 00027 _mask = 0; 00028 } 00029 00030 /** Constructor. Creates a new Policy object from the given string. */ 00031 Policy::Policy(QString policy) 00032 { 00033 /* Set the defaults */ 00034 _action = Accept; 00035 _address = QHostAddress::Any; 00036 _fromPort = _toPort = 0; 00037 _mask = 0; 00038 00039 /* Parse the given string to override the defaults. */ 00040 fromString(policy); 00041 } 00042 00043 /** Constructor. Creates a new Policy object from the string parts. */ 00044 Policy::Policy(QString action, QString address, QString ports) 00045 { 00046 /* Set the defaults */ 00047 _action = Accept; 00048 _address = QHostAddress::Any; 00049 _fromPort = _toPort = 0; 00050 _mask = 0; 00051 00052 fromString(action + " " + address + ":" + ports); 00053 } 00054 00055 /** Constructor. Creates a new Policy object depending on the specified 00056 * special policy type. */ 00057 Policy::Policy(SpecialPolicy policy) 00058 { 00059 _action = (policy == AcceptAll ? Accept : Reject); 00060 _address = QHostAddress::Any; 00061 _fromPort = _toPort = 0; 00062 _mask = 0; 00063 } 00064 00065 /** Constructor. Creates a new policy object based on the given rules. */ 00066 Policy::Policy(Action action, QHostAddress addr, uchar mask, 00067 quint16 fromPort, quint16 toPort) 00068 { 00069 _action = action; 00070 _address = addr; 00071 _mask = mask; 00072 _fromPort = fromPort; 00073 _toPort = (toPort >= fromPort ? toPort : fromPort); 00074 } 00075 00076 /** Returns true if this policy is identical to <b>policy</b>. */ 00077 bool 00078 Policy::operator==(const Policy &policy) const 00079 { 00080 return ((this->_action == policy._action) && 00081 (this->_address == policy._address) && 00082 (this->_mask == policy._mask) && 00083 (this->_fromPort == policy._fromPort) && 00084 (this->_toPort == policy._toPort)); 00085 } 00086 00087 /** Returns true if this policy matches <b>policy</b>. For example, if this 00088 * policy is "reject *:6660-6669" and <b>policy</b> is "reject *:6662-6664", 00089 * this will return true. For strict comparison, use the == operator. */ 00090 bool 00091 Policy::matches(const Policy &policy) const 00092 { 00093 /* This doesn't take into account addr/mask matches yet */ 00094 return ((this->_action == policy._action) && 00095 (this->_address == policy._address) && 00096 (this->_mask == policy._mask) && 00097 (this->_fromPort <= policy._fromPort) && 00098 (this->_toPort >= policy._toPort)); 00099 } 00100 00101 /** Parses the given exit policy string. */ 00102 void 00103 Policy::fromString(QString policy) 00104 { 00105 /* Separate the action and the address/mask/port info */ 00106 QStringList ruleParts = policy.split(" "); 00107 _action = toAction(ruleParts.at(0)); 00108 00109 /* If some address/mask/port stuff was specified, parse it. */ 00110 if (ruleParts.size() > 1) { 00111 QStringList addrParts = ruleParts.at(1).split(":"); 00112 00113 /* Parse the address and mask (if specified) */ 00114 QString addr = addrParts.at(0); 00115 _address.setAddress(addr.mid(0, addr.indexOf("/"))); 00116 if (_address.isNull()) { 00117 _address = QHostAddress::Any; 00118 } 00119 if (addr.contains("/")) { 00120 _mask = addr.mid(addr.indexOf("/")+1).toUInt(); 00121 } 00122 00123 /* Parse the specified port range (if specified) */ 00124 if (addrParts.size() > 1) { 00125 QString ports = addrParts.at(1); 00126 _fromPort = ports.mid(0, ports.indexOf("-")).toUInt(); 00127 if (ports.contains("-")) { 00128 _toPort = ports.mid(ports.indexOf("-")+1).toUInt(); 00129 } else { 00130 _toPort = _fromPort; 00131 } 00132 } 00133 } 00134 } 00135 00136 /** Converts this policy to a form Tor understands. The format is: 00137 * "accept|reject ADDR[/MASK][:PORT]" 00138 * 00139 * PORT can be a single port number, an interval of ports "FROM_PORT-TO_PORT", 00140 * or "*". If PORT is omitted, that means "*" 00141 */ 00142 QString 00143 Policy::toString() const 00144 { 00145 QString act = (_action == Accept ? "accept" : "reject"); 00146 return act + " " + address() + ":" + ports(); 00147 } 00148 00149 /** Converts the given action to a string. This function tolerates both the 00150 * translated and untranslated forms of the string "accept" and "reject". */ 00151 Policy::Action 00152 Policy::toAction(QString action) 00153 { 00154 action = action.toLower(); 00155 if (action == tr("accept") || action == "accept") { 00156 return Accept; 00157 } 00158 return Reject; 00159 } 00160 00161 /** Returns the action associated with this policy. NOTE: This string will be 00162 * translated to whatever the current language setting is. */ 00163 QString 00164 Policy::action() const 00165 { 00166 return (_action == Accept ? tr("accept") : tr("reject")); 00167 } 00168 00169 /** Returns the address (and mask, if specified) for this policy. */ 00170 QString 00171 Policy::address() const 00172 { 00173 QString addrString; 00174 00175 if (_mask) { 00176 addrString = _address.toString() + "/" + QString::number(_mask); 00177 } else if (_address == QHostAddress::Any || _address.isNull()) { 00178 addrString = "*"; 00179 } else { 00180 addrString = _address.toString(); 00181 } 00182 return addrString; 00183 } 00184 00185 /** Returns the port (or port range, if specified) for this policy. */ 00186 QString 00187 Policy::ports() const 00188 { 00189 QString ports = (_fromPort ? QString::number(_fromPort) : "*"); 00190 if (_fromPort && (_toPort > _fromPort)) { 00191 ports += "-" + QString::number(_toPort); 00192 } 00193 return ports; 00194 } 00195